Hello all
Yesterday, my website faced a SYN flood attack, which is a proper pain in the backside and you know how much of a pain it is only after it happens to you.
So, the kiddie hackers (hope I am not tempting fate) managed to make the site unstable for about 6 hours. Here the resource usage chart for that period – Click here
Here is the easiest way to block such an attack using IPtables :
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP iptables -A INPUT -f -j DROP iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP iptables -A INPIT -p tcp --tcp-flags ALL NONE -j DROP
These commands need to be entered via SSH.
However, the best way to block this is by using nginx as a reverse proxy. The instructions below are quite crude, so if you can make it better, please feel free to do so.
First, install nginx :
wget http://nginx.org/download/nginx-0.8.34.tar.gz tar -zxvf nginx-0.8.34.tar.gz cd nginx-0.8.34 ./configure --sbin-path=/usr/local/sbin --with-http_perl_module --with-http_stub_status_module make sudo make install
Then access your browser using SFTP and go here
/usr/local/nginx/conf
Edit the file called nginx.conf
#user nobody; worker_processes 2; worker_rlimit_nofile 40960; worker_rlimit_sigpending 32768; error_log logs/error.log crit; #pid logs/nginx.pid; events { worker_connections 100000; } http { include mime.types; default_type application/octet-stream; access_log off; limit_conn_log_level info; #sendfile on; #tcp_nopush on; reset_timedout_connection on; server_tokens off; autoindex off; keepalive_timeout 0; #keepalive_timeout 65; limit_zone one $binary_remote_addr 10m; server { listen 80; server_name www.yourwebsite.com; access_log off; # Apache already creates access logs, I'd disable them unless you really need them error_log /var/log/httpd/nginx.errors.cramit.in.log warn; # error log, level "warn": # Forward requests to Apache! This is the key to our system location / { proxy_pass http://www.yourwebsite.com:81; include /usr/local/nginx/conf/proxy.conf; # the proxy.conf file limit_conn one 2; } # Select files to be deserved by nginx location ~* ^.+\.(jpeg|jpg|gif|png|bmp)$ { root /var/www/vhosts/yourwebsite.com/httpdocs; # the httpdocs folder of your domain } } server { listen 80; server_name yourwebsite.com; access_log off; # Apache already creates access logs, I'd disable them unless you really need them error_log /var/log/httpd/nginx.errors.cramit.in.log warn; # error log, level "warn": # Forward requests to Apache! This is the key to our system location / { proxy_pass http://yourwebsite.com:81; include /usr/local/nginx/conf/proxy.conf; # the proxy.conf file limit_conn one 2; } # Select files to be deserved by nginx location ~* ^.+\.(jpeg|jpg|gif|png|bmp)$ { root /var/www/vhosts/yourwebsite.com/httpdocs; # the httpdocs folder of your domain } }
Create a file called proxy.conf in the same folder as nginx.conf and paste the following in it
location / { proxy_pass http://yourwebsite.com:81/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $HTTP_X_REAL_IP; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Referer $http_referer; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; }
Edit this file
/etc/httpd/conf/httpd.conf
Replace all instances of 80 with 81.
Now the last part, this will differ depending on the control panel that you use. I use Plesk and so the above tutorial is based on that. Please feel free to add versions for other control panels in this thread.
Edit this file
/etc/httpd/conf.d/zz010_psa_httpd.conf
Replace all instances of 80 with 81.
Edit this file
/var/www/vhosts/yourdomain.com/conf/httpd.include
Replace all instances of 80 with 81.
Type the following commands in SSH
chattr +i /etc/httpd/conf.d/zz010_psa_httpd.conf chattr +i /var/www/vhosts/yourdomain.com/conf/httpd.include
The above commands will lock the two files from being edited as Plesk likes to restore these files to it’s original configurations every time it restarts.
To unlock them use
chattr -i /etc/httpd/conf.d/zz010_psa_httpd.conf chattr -i /var/www/vhosts/yourdomain.com/conf/httpd.include
Restart Apache
service httpd graceful
Start nginx
sudo /usr/local/sbin/nginx
To shut nginx down (only when needed)
sudo kill `cat /usr/local/nginx/logs/nginx.pid`
And, there you go. You will be DDOS and SYN free. As I said before, this is a very crude ‘tutorial’ so I haven’t posted it in the tutorial section.
Also, there may be errors in the nginx part as I haven’t had sleep yet, but I thought that it is important to post this as soon as possible because it is very difficult to find a definitive DDOS prevention tutorial using Google.
The IPtables instructions work perfectly, so you can follow them word for word. The nginx one is only to be used by experts who know how to interpret the config file, atleast until the tutorial is refined by others.
The principle of working : By using nginx, basically, you are limiting the connections per IP to 2 before sending requests to Apache. So, that effectively blocks the DDOS.
Known issues : nginx does not support a progress bar, so not a good idea if you have anything that requires one. This method does show a progress bar, but it is not smooth, so not very user friendly. There is an nginx mod for this though, so if anyone knows how to install it, please feel free to post your intructions here.
Apache needs the module RPAF loaded to take the referrer and user IP from nginx. Otherwise, all visits are shown from your server IP and a blank referrer.