DDoS attack on your web server can have the most unpleasant consequences for your infrastructure. Each attack should be considered as a separate case, and in the case of DDoS on your server, we recommend involving a qualified system administrator to solve this problem. In this article we will try to consider the most basic methods of preventing common attacks on web servers Apache/Nginx.
Apache
For this web server, the Ddos attack begins with the revelation of a large number of apache processes, your server may become unavailable due to exceeding the maximum number of processes, or due to shortage of RAM.
Let’s look at the sequence of actions and recommendations in case you encounter an attack.
1.Diagnostics
If possible, you need to connect to the server via ssh. Using the ps and top commands, you can detect an increase in the number of httpd processes. In this case, you can stop apache or kill all httpd processes.
These commands will help determine the direction and status of all connections that are established on port 80 or on all ports:
netstat -na | grep ':80 ' netstat -na
Using the following commands, you can view the number of httpd processes and the number of connections on port 80. If a connection is detected that exceeds the average, you can review that it is a DoS / DDoS attack.
ps aux | grep -с httpd netstat -na | grep -с ":80 "
The Centos 7 operating system does not have the netstat command in the image, but you can install netstat with the command:
yum instal net-tools
You can also use an alternative method, the ss command, which during output displays all connections to the web server:
ss -o '( dport = :http or sport = :http )'
With the following command, you can display the number of connections from one IP address to the web server and sort the list in ascending order:
ss -o '( dport = :http or sport = :http )' | awk '{print $6}' | cut -d : -f 1 | grep -v 'Address' | sort | uniq -c | sort -n
With a high probability, http flood can be determined by side signs. With the following command, you can cause every 2 seconds to display a list of apache logs, and if there is a big increase with the size of the access file, you can determine that the attack goes to a particular site:
watch 'ls -laS /var/www/httpd-logs/'
The following commands can help detect DoS / DDoS using tcpdump.
tcpdump will write the first 200 packets that are waiting for connections on port 80 to the check.log file:
tcpdump -n port 80 -c 200 -w check.log
With this command you can parse the log file and sort it by ip and number of connections:
tcpdump -nr check.log | awk '{print $3}' |grep -oE '[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}' |sort |uniq -c |sort -rn
2.Actions to stop the attack
First of all, you need to determine which site the attack is on.
Apache has a mod_status module, mod_status allows real-time monitoring of server load.
- Connecting mod_status in Apache 2.4
In apache2.4, you need to edit the file /etc/apache2/mods-enabled/status.conf. Change section:
<Location /server-status> SetHandler server-status Require local #Require ip ---- </Location>
on
<Location /server-status> SetHandler server-status </Location>
Check that the string is uncommented:
ExtendedStatus On
Restart apache:
service httpd restart
- Mod_status connection in Apache 2.2
In apache2.2, edit /etc/httpd/conf/httpd.conf
Uncomment the lines, and if not, add them to the file:
#LoadModule status_module libexec/apache22/mod_status.so #Include etc/apache22/extra/httpd-info.conf
Change section:
<Location /server-status> SetHandler server-status Order deny,allow Deny from all Allow from .examplesite.com </Location>
on
<Location /server-status> SetHandler server-status </Location>
Check that the string is uncommented:
ExtendedStatus On
Restart apache:
service httpd restart
- Using server-status
And now at
http: //server-ip-address/server-status statistics of requests to it are available.
For example, the attack occurs with empty GET / requests to the examplesite.com website and you need to disable it. You can do this by creating a .htaccess file in the root directory of the domain and writing it to the contents of the file:
Deny from All
Now, when accessing the site, 403 Forbidden error will be generated and the load on other sites will be significantly reduced.
3.Additional settings
- iptables
Using the following command, you can filter the 80th port for a specific IP:
iptables -A INPUT -p tcp --src xxx.xxx.xxx.xxx --dport 80 -j DROP
Using the following combination, you can create a chain where all connections will be redirected to the 80th port of the server. All illegitimate IPs will be added to this chain:
iptables -N chainname iptables -A INPUT -p tcp --dport 80 -j chainname while true; do tail -10000 /var/www/httpd-logs/site.com.access.log | sort | cut -f 1 -d " " | uniq -c | awk '($1>50){print $2}' | xargs -tn 1 iptables -A dos -p tcp -j DROP --dport 80 -s; sleep 30; done
iptables -F INPUT — clear the table INPUT
iptables -F chainname— clear the table chainname
iptables -X chainname— delete the table chainname
Setting up using iptables can lead to duplicate rules in the chain. This can be avoided by using the ipset module.
- ipset
ipset -N chainname iphash iptables -A INPUT -p tcp -m tcp --dport 80 -m set --set chainname src -j DROP while true; do tail -10000 /var/www/httpd-logs/site.com.access.log | sort | cut -f 1 -d " " | uniq -c | awk '($1>50){print $2}' | xargs -tl -I _ ipset -A chainname _;sleep 30; done
- ICMP-flood
In this case, close icmp:
iptables -A INPUT -p icmp -j DROP --icmp-type 8
You can also limit the maximum number of half-open connections from one IP to a specific port, you must first install the desired module:
iptables -I INPUT -p tcp --syn --dport 80 -m iplimit --iplimit-above 10 -j DROP
The following combination can limit the maximum number of connections from one IP to a specific port:
/sbin/iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 3 -j REJECT
- Apache server optimization
First of all, it is necessary to adjust additional parameters in the server settings:
/etc/httpd/conf/httpd.conf <IfModule mpm_itk_module> StartServers 1 MinSpareServers 1 MaxSpareServers 1 MaxClients 150 MaxRequestsPerChild 100 </IfModule>
You should to change the MaxClients value, which means the maximum number of processes, given the number of processes that will not lead to a server crash due to a shortage of RAM.Keep in mind that each Apache process takes 4-8 MB of memory, so the following command can find out how much one apache / httpd process takes up memory on your server and determine MaxClients from this value:
top -d 1 | grep -E 'http|apache' | awk '{a+=$7}END{print a/(1024*NR) " Mb"}'
You should also adjust and set the following parameters so that outdated apache processes can stop their work faster:
Timeout 60 MaxKeepAliveRequests 50
- Configuring nginx as front-end for apache
server { listen 80; server_name examplesite.com www.examplesite.com; deny all;
WWW domain must be disabled by configuring nginx in the required virtual host. This will force nginx to issue 403 Forbidden rather than redirecting requests to the apache web server.
Nginx
1.First of all, it is necessary to limit the speed of requests so that Nginx accepts incoming requests at the speed necessary for real users:
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m; server { # ... location /index.html { limit_req zone=one; } } limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m; server { # ... location /example.html { limit_req zone=one; } }
This configuration example uses the following settings:
- limit_req_zone – the directive configures the called shared memory zone to store the status of requests for the specified key, in this case the client IP address ($ binary_remote_addr).
- limit_req – The directive in the location block for /index.html refers to the shared memory zone.
2.Limit the number of connections that can be opened by one client IP
limit_conn_zone $binary_remote_addr zone=addr:10m; server { # ... location /products/ { limit_conn addr 10; } }
This configuration example uses the following settings:
- limit_conn_zone— The directive sets up a shared memory zone named addr to /products requests for the specified key, in this case (as in the previous example) the client IP address, $ binary_remote_addr.
- limit_conn— The directive in the location block for / products refers to the shared memory zone and establishes a maximum of 10 connections from each client IP address.
3.Close slow connections
You can close connections that write data too infrequently, which may be an attempt to keep connections open and thus reduce the server’s ability to accept new connections.
client_header_timeout 30s; client_body_timeout 30s;
By default, this parameter is 60 seconds.
These are currently all common measures to prevent attacks on web servers. If you encounter an attack on your web server, please save the logs for further investigation of the causes of vulnerabilities in your service.