This is how we setup our own CDN + WAF. Where multi node will be deployed and act as CDN (nginx) and WAF (modsecurity) installed.
Pre-installation before setup the CDN + WAF
yum clean all yum erase NetworkManager mariadb-libs* -y yum install perl wget screen net-tools bind-utils ntpdate vim unzip -y
• Disable the selinux
perl -pi -e "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config setenforce 0
• Stop and disable the firewalld
systemctl stop firewalld systemctl disable firewalld
• Customize and optimize ssh service
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.tmp cat /etc/ssh/sshd_config.tmp | sed s/"#Port 22"/"Port 9321"/g > /etc/ssh/sshd_config echo "" >> /etc/ssh/sshd_config echo "Protocol 2" >> /etc/ssh/sshd_config echo "" >> /etc/ssh/sshd_config echo "Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,arcfour" >> /etc/ssh/sshd_config echo "MACs hmac-sha1,hmac-ripemd160" >> /etc/ssh/sshd_config echo "" >> /etc/ssh/sshd_config echo "Protocol 2" >> /etc/ssh/sshd_config perl -pi -e "s/\#ClientAliveInterval 0/ClientAliveInterval 900/g" /etc/ssh/sshd_config perl -pi -e "s/\#ClientAliveCountMax 3/ClientAliveCountMax 3/g" /etc/ssh/sshd_config echo "TMOUT=900" >> /etc/profile systemctl restart sshd
• Update the server time, set cronjob to update it every day and auto update it every time server rebooted.
ntpdate time.ipserverone.com echo "/sbin/ntpdate time.ipserverone.com" >> /etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local systemctl start rc-local (crontab -l; echo "15 00 * * * /sbin/ntpdate time.ipserverone.com > /dev/null 2>&1") | crontab -
• Create user isupport and enable root privileges.
cp /etc/sudoers /etc/sudoers.tmp cat /etc/sudoers.tmp | sed '/NOPASSWD/ a isupport ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers useradd isupport
• Install development tools, update all software packages that pre-installed and reboot the server.
yum groupinstall 'development tools' -y; yum update -y; reboot
• Install Kernel Version Checker
mkdir -p /ips1 cd /ips1 wget -O /ips1/ips1-kernel-checker --user=support --password=Jz8jx001 https://ns82.small-dns.com/setup/ips1-kernel-checker chmod +x /ips1/ips1-kernel-checker (crontab -l; echo "30 22 * * * /ips1/ips1-kernel-checker > /dev/null 2>&1" ) | crontab -
Install libmodsecurity
yum install gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel \ doxygen zlib-devel httpd-devel pcre-devel libxml2-devel libtool autoconf \ automake openssl-devel pcre-devel -y cd /opt git clone https://github.com/SpiderLabs/ModSecurity cd ModSecurity git checkout -b v3/master origin/v3/master sh build.sh git submodule init git submodule update ./configure make && make install useradd --no-create-home nginx export MODSECURITY_INC="/opt/ModSecurity/headers/" export MODSECURITY_LIB="/opt/ModSecurity/src/.libs/" cd /opt git clone https://github.com/SpiderLabs/ModSecurity-nginx git clone https://github.com/openresty/headers-more-nginx-module.git wget https://nginx.org/download/nginx-1.14.0.tar.gz tar xvf nginx-1.14.0.tar.gz cd nginx-1.14.0 vi install.sh
Copy and paste the following installation script,
#!/bin/bash
./configure \
"--user=nginx" \
"--group=nginx" \
"--prefix=/usr" \
"--sbin-path=/usr/sbin" \
"--conf-path=/etc/nginx/nginx.conf" \
"--pid-path=/var/run/nginx.pid" \
"--http-log-path=/var/log/nginx/access_log" \
"--error-log-path=/var/log/nginx/error_log" \
"--without-mail_imap_module" \
"--without-mail_smtp_module" \
"--with-http_ssl_module" \
"--with-http_realip_module" \
"--with-http_stub_status_module" \
"--with-http_gzip_static_module" \
"--with-http_dav_module" \
"--with-cc-opt='-D FD_SETSIZE=32768'" \
"--with-ld-opt='-Wl,-rpath,/usr/local/lib/'" \
"--add-module=/opt/headers-more-nginx-module" \
"--add-module=/opt/ModSecurity-nginx"
Install the Nginx with module of modsecurity and header enabled.
sh install.sh make && make install
Verify if the Nginx installation is OK or not.
# nginx -t ...... nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ...... # nginx -V ...... nginx version: nginx/1.14.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --user=nginx --group=nginx --prefix=/usr --sbin-path=/usr/sbin --conf-path=/etc/nginx/nginx.conf --pid-path=/var/run/nginx.pid --http-log-path=/var/log/nginx/access_log --error-log-path=/var/log/nginx/error_log --without-mail_imap_module --without-mail_smtp_module --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_dav_module --with-cc-opt=''-D FD_SETSIZE=32768'' --with-ld-opt='-Wl,-rpath,/usr/local/lib/' --add-module=/opt/headers-more-nginx-module --add-module=/opt/ModSecurity-nginx ......
Start the nginx service
# nginx
Verify if the nginx service running or not
# pidof nginx ...... 27159 27158 ...... # netstat -anp : grep nginx ...... tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 27158/nginx: master unix 3 [ ] STREAM CONNECTED 29253 27158/nginx: master unix 3 [ ] STREAM CONNECTED 29252 27158/nginx: master ...... # curl -I http://localhost/ ...... HTTP/1.1 200 OK Server: nginx/1.14.0 Date: Sun, 13 May 2018 05:58:11 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Sun, 13 May 2018 05:53:03 GMT Connection: keep-alive ETag: "5af7d2bf-264" Accept-Ranges: bytes ......
Download the owasp modsecurity rules.
mkdir -p /etc/modsecurity.d cd /etc/modsecurity.d wget -O master.zip https://github.com/SpiderLabs/owasp-modsecurity-crs/zipball/v3.0/master unzip master.zip ln -s SpiderLabs-owasp-modsecurity-crs-a216353 owasp-modsecurity-crs wget -O /etc/modsecurity.d/owasp-modsecurity-crs/crs-setup.conf --user=support --password=Jz8jx001 https://ns82.small-dns.com/setup/cdn-waf-crs-setup-conf rm -f master.zip
Backup the nginx config directory, remove it and download the default CDN + WAF configs.
nginx -s stop mkdir -p /var/log/modsec cd /etc mv nginx nginx.old wget -O /etc/nginx.tar.gz --user=support --password=Jz8jx001 https://ns82.small-dns.com/setup/cdn-waf-nginx.tar.gz tar xvf nginx.tar.gz rm -f nginx.tar.gz
Start the nginx service and verify
# nginx # netstat -anp | grep nginx ...... unix 3 [ ] STREAM CONNECTED 29332 27210/nginx: master unix 3 [ ] STREAM CONNECTED 29330 27210/nginx: master unix 3 [ ] STREAM CONNECTED 29333 27210/nginx: master unix 3 [ ] STREAM CONNECTED 29331 27210/nginx: master ......
Download a bash script to add and delete domain in this node
mkdir -p /ips1/scripts cd /ips1/scripts wget -O /ips1/scripts/scripts.tar.gz --user=support --password=Jz8jx001 https://ns82.small-dns.com/setup/cdn-waf-scripts.tar.gz tar xvf scripts.tar.gz rm -f scripts.tar.gz
Then, we can start to add the domain to test.
cd /ips1/scripts ./add-domain-http.sh khairul.org 14.102.148.38 ...... Domain khairul.org successful created ......
Change your PC host file, and point your domain to node IP address, then test and verify.
localhost:~ khairul$ curl -X GET -I http://khairul.org/ HTTP/1.1 200 OK Server: nginx Date: Mon, 21 May 2018 18:12:47 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding Expires: Mon, 21 May 2018 18:12:46 GMT Cache-Control: private, no-cache, no-store, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache X-DNS-Prefetch-Control: off X-Frame-Options: sameorigin Content-Language: en Set-Cookie: roundcube_sessid=f1sekiorf9t005gk0pc45udti7; path=/; domain:.khairul.org; HttpOnly; HttpOnly X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Node: 20180514-MY3-01
To delete the domain from this node
cd /ips1 ./remove-domain.sh khairul.org ...... Domain khairul.org successful deleted ......