Denial of Service attacks or the distributed version of them (DDoS) have been growing throughout the years with their ups and downs. In my view the only thing that will happen to them is even bigger growth. With the advent of IoT devices the next decade will see an increase in these kind of attacks. Among the things users and administrators can do to prevent them is staying current and patch all the systems connected to the network so those devices do not fall into slave participants on those attacks. Unfortunately is not uncommon home routers are already playing a role in many attacks. So it is ISP’s as well as users responsability to be on the right track. The other thing administrators can do is setting up the most robust systems they are capable of so attacks get inadverted or at least partially mitigated.
Mod_evasive is a complementary module for the Apache web server and it is one of those tools that can help web administrators cope with a DoS attack. It may not be able to completely mitigate the effects of such an issue, since your infrastructure may not be ready for a large attack, but aside of helping on mitigating the effects in can also work as a warning so you can report to the infrastructure provider you are using. As the author claims the software works as follows:
Detection is performed by creating an internal dynamic hash table of IP Addresses and URIs, and denying any single IP address from any of the following:
– Requesting the same page more than a few times per second
– Making more than 50 concurrent requests on the same child per second
– Making any requests while temporarily blacklisted (on a blocking list)
As the developer also explains the software is limited by the capacity of the infrastructure in use in terms of cpu consumption and network bandwidth. This is why large attacks on small infrastructure are effective despite of it. It is usually wise to have a complex networking setup, load balancers, filtered traffic and such measures to cope with large attacks. The security researcher Brian Krebs can explain how this works in a very accurate and personnal way.
Mod_evasive is also ready not to block legitimate connections, even when a user repetedly refreshes the web page (to a logical limit of course), so regular and desired traffic doesn’t get blocked. The software works using three generic rules. The first method is by checking requests with a temporary blacklist based on the requestor’s ip. The second way is by taking the requestor’s ip and the URI and hashing them into a ‘key’. Afterhat a lookup is performed in the listerner’s internal hash table to check if that same host has requested that specific web page more than once in the past one second. A third way is by hashing the requestor’s ip into a ‘key’. Then a lookup is performed in the listener’s internal hash table to see if the same host has requested more than 50 objects during the last second. If any of those three methods is true, a 403 response is sent. This helps reducing bandwidth and system resources during an attack.
Once that 403 response is sent for a particular IP it is blocked during 10 seconds on the default configuration, although this can be increased to a different time frame if desired. Mind this only happens by asking repeteadly for the same resource (URL) so legitimate users won’t be affected.
We’ll now proceed with the install so you get an idea of how to mitigate DoS attacks with mod_evasive on FreeBSD.
As always do first update the system. After that is done let’s look for the package.
root@system:~ # pkg search mod_evasive
ap24-mod_evasive-1.10.1_1 Apache module to try to protect the HTTP Server from DoS/DDoS attacks
Once found we’ll proceed with the binary install.
root@system:~ #pkg install ap24-mod_evasive-1.10.1_1
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
Number of packages to be installed: 1
17 KiB to be downloaded.
Proceed with this action? [y/N]: y
[system] [1/1] Fetching ap24-mod_evasive-1.10.1_1.txz: 100% 17 KiB 17.7kB/s 00:01
Checking integrity... done (0 conflicting)
[system] [1/1] Installing ap24-mod_evasive-1.10.1_1...
[system] [1/1] Extracting ap24-mod_evasive-1.10.1_1: 100%
[preparing module `evasive20' in /usr/local/etc/apache24/httpd.conf]
A new line has been inserted into Apache’s main configuration file ‘httpd.conf’. You can check it as follows:
root@system:~ # cat /usr/local/etc/apache24/httpd.conf | nl -ba | egrep 'evasive'
181 #LoadModule evasive20_module libexec/apache24/mod_evasive20.so
As you can see on the line 181 in the httpd.conf file the mod_evasive directive is declared but it is commented, so it’s not working at this moment. We have to uncomment it for it to work and restart Apache so it’s effective.
root@system:~ # vi +181 /usr/local/etc/apache24/httpd.conf
LoadModule evasive20_module libexec/apache24/mod_evasive20.so
Once enabled we must edit a file into the modules.d directory so the module works following a number of parameters. The path to that directory is:
Inside that we will edit a file begining with 3 numbers and ended with the ‘.conf’ extension so Apache reads from it. The installation message of this software gives you a sample configuration so you can use it. It reads like follows:
We’ll use a slightly modified configuration, including some changes such as a longer blocking period, and a bigger page count so it isn’t triggered as quickly. We’ll also include an email address to inform about the issue which may be a positive DoS or DDoS attack.
root@system:/usr/local/etc/apache24/modules.d # vi 020-mod_evasive.conf
DOSSystemCommand "su - root -c /sbin/ipfw add 50000 deny %s to any in"
Once the file on its place Apache needs to be restarted so this file is included and the module fully activated.
root@system:~ # apachectl restart
Performing sanity check on apache24 configuration:
Waiting for PIDS: 5038.
Performing sanity check on apache24 configuration:
We are now ready to test the tool to see if it works. The developers have included a test perl script so you can make a test for yourself at any time.
root@system:~ # perl /usr/local/share/doc/mod_evasive/test.pl
Be advised a hundred lines of output will be displayed since this script makes one hundred tries in almost no time. So if you don’t want to see that you can use the redirection to a file into the /tmp file, or if you preffer you can redirect the output to /dev/null.
root@system:~ # perl /usr/local/share/doc/mod_evasive/test.pl >> /dev/null
If we check the access logs we can see three requests are replied with a 200 code, which is a success. However beyond that we’ll see the rest of the connections are forbidden and the code is a 403 for those.
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?0 HTTP/1.0" 200 45
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?1 HTTP/1.0" 200 45
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?2 HTTP/1.0" 200 45
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?3 HTTP/1.0" 403 209
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?4 HTTP/1.0" 403 209
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?5 HTTP/1.0" 403 209
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?6 HTTP/1.0" 403 209
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?7 HTTP/1.0" 403 209
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?8 HTTP/1.0" 403 209
192.168.1.124 - - [10/Mar/2019:18:31:07 +0100] "GET /?9 HTTP/1.0" 403 209
Refreshing the browser frenetically gives similar results.
It is possible the script doesn’t give you 403 error codes (forbidden acces) but 400 (bad requests). Be careful and check the first response lines in the httpd-acces.log file so at least a few requests have got a result code of 200 (ok) and then the 400 or 403. You can tune the script a bit and change it from this:
print $SOCKET "GET /?$_ HTTP/1.0\n\n";
print $SOCKET "GET /?$_ HTTP/1.0\r\n\r\n";
If you want to add a different configuration there is a very good explanation on the project’s github page. Check it out.
Last but not least. Proxies. Be aware of what ip comes to be the requestor. Remember in large deployments if a proxy is calling the Apache web server to spit out the same page serveral times in a very short period of time (less than a second) you may be blocking legitimate traffic. As a starting point the official documentation from the Apache project may be helpful in resolving this. With the use of the mod_remoteip module the original client IP address for the connection is replaced with the useragent IP address list presented by proxies or a load balancer via the request headers.