In the previous part of this series, we talked about TLS, OCSP and security-relevant HTTP response headers. In this part, we introduce the web application firewall ModSecurity and the intrusion prevention system Fail2ban.
- Continuous monitoring
Always stay in the loop!
Subscribe to our RSS/Atom feeds.
- hardened web server as configured in part 2
- SSH client on your computer
- basic knowledge about firewalls
All of the three components in this guide have different purposes. However, all of them are needed to accomplish our goal: Blocking attackers, bots and other malicious activities automatically.
Fail2ban is an intrusion prevention system. It monitors different log files of the server to block suspicious IPv4 or IPv6 addresses (e.g., too many failed login attempts, bot-like scanning for certain file types, usage of blacklisted HTTP methods). Administrators can use regular expressions to customize standard configuration (so-called “jails”).
ModSecurity is an open-source web application firewall originally developed for Apache web server. In part 2 of our guide, we already installed ModSecurity to hide our server signature. We can configure “SecRules” to log and filter HTTP traffic in real-time. ModSecurity will be the foundation for blocking unwanted IP addresses. It is also possible to use ModSecurity with Nginx.
OWASP ModSecurity CRS
The ModSecurity Core Rule Set is developed by OWASP (Open Web Application Security Project). This rule set can be used by ModSecurity to provide protection against common attacks and vulnerabilities in web applications. We use CRS to add some useful rules to ModSecurity.
In this section, we install and configure Fail2ban and OWASP ModSecurity CRS. Finally, we tell ModSecurity to use the CRS.
First of all, download and install Fail2ban using apt:
sudo apt install fail2ban. After this, we duplicate the default configuration file of Fail2ban:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local as recommended.
Open the fresh copy using nano editor:
sudo nano /etc/fail2ban/jail.local.
jail.local, look for the following snippet and add
enabled = true:
This tells Fail2ban to monitor the
/var/log/auth.log file and temporarily block IP addresses that continuously try to log in using SSH while providing no valid credentials.
Also look for:
Change this to:
bantime = 86400 means that IP addresses will be banned for 86400 seconds (= 24 hours). We will change
enabled = false to
enabled = true later.
Finally, restart Fail2ban:
sudo systemctl restart fail2ban. If necessary, enable and start it:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Keep in mind that your version of Fail2ban may only support IPv4, so attackers using IPv6 can’t be blocked. On Debian 10, Fail2ban comes with support for IPv4 and IPv6 addresses.
sudo apt install libapache2-modsecurity. If you implemented all steps of part 2, this results in
libapache2-modsecurity is already the newest version.
Now, remove “-recommended” from the
sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf.
sudo nano /etc/modsecurity/modsecurity.conf and change:
SecRuleEngine On(enables ModSecurity)
SecStatusEngine Off(disables transmission of information about your ModSecurity setup to the developer team)
OWASP ModSecurity CRS
Installing CRS requires
git. If you didn’t install it so far, install it now:
sudo apt install git.
Clone the latest version of CRS:
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git.
Enter the folder
cd owasp-modsecurity-crs/ and remove “.example” from
mv crs-setup.conf.example crs-setup.conf.
Move all rules to the ModSecurity folder
sudo mv rules/ /etc/modsecurity/ and also the config file
sudo mv crs-setup.conf /etc/modsecurity/crs/crs-setup.conf. After that, open
sudo nano /etc/modsecurity/crs/crs-setup.conf and enable rules by uncommenting them. For example, we only allow the HTTP method GET by uncommenting and modifying rule id 900200:
Carefully check which rules are useful and enable them by uncommenting them. Document which rules you use. Afterwards, save the file.
Now, open Apache’s configuration file for ModSecurity
sudo nano /etc/apache2/mods-enabled/security2.conf and include the new files:
Restart Apache web server:
sudo systemctl restart apache2. Keep in mind that CRS is also subject to change. So, it is best to check if there are any updates for rules used by your web server from time to time.
After restarting Fail2ban and Apache, you can test ModSecurity before turning on Fail2ban’s ModSecurity rule: Open a web browser on your client and enter “[your-domain]/index.html?exec=/bin/bash”.
Then open Apache’s
error.log on your server:
sudo tail -f /var/log/apache2/error.log. There must be an event in the log file that was created due to your test above.
Finally, enable Fail2ban’s ModSecurity rule. Open
sudo nano /etc/fail2ban/jail.local, look for
[apache-modsecurity] and change
enabled = false to
enabled = true. Save the file and restart Fail2ban:
sudo systemctl restart fail2ban.
If you want to test Fail2ban, use the Tor Browser. By doing so, you avoid that your own real IP address gets banned by Fail2ban. You can unban a particular IP address by entering:
sudo fail2ban-client set JAIL_NAME unbanip IP_ADDRESS.
If you want to unban all IP addresses at once, get the path of Fail2ban’s database file:
sudo fail2ban-client get dbfile. Then stop Fail2ban
sudo systemctl stop fail2ban and delete its database
rm PATH. Start Fail2ban again:
sudo systemctl start fail2ban.
Important: Some websites report that Fail2ban’s regular expression to match errors of ModSecurity is broken. If you also experience this, open
sudo nano /etc/fail2ban/filter.d/apache-modsecurity.conf and look for
failregex = […]. Change the regex to:
failregex = ^%(_apache_error_client)s(?: \[client [\d\.:]+\])? ModSecurity:\s+(?:\[(?:\w+ \"[^\"]*\"|[^\]]*)\]\s*)*Access denied with code \d\d (?:.*)$.
Follow us on Mastodon:
As always, it isn’t sufficient to just install and enable security software and hope for the best. The most important part is continuous monitoring and testing of your setup. Test regularly if Fail2ban still bans IP addresses as expected. You can use the following commands to get information about your jails:
sudo fail2ban-client status apache-modsecurity(actions due to ModSecurity’s error files)
sudo fail2ban-client status sshd(actions due to SSH’s error files)
Additionally, regularly check all error log files of your server.
This article is part of the "Web server security" series.
Read other articles of this series.
Fail2ban and ModSecurity allow you to get rid off basic attacks, bots and IP addresses that show malicious behavior. Carefully check all CRS rules and your setup over and over again to ban everything you don’t want on your server. Moreover, regularly test your setup and check the status of Fail2ban and ModSecurity. Finally, check if there are updates for CRS from time to time.
In the fifth part of this series, we show you basic server-side DNS security configuration.