Web server security – Part 4: WAF ModSecurity and IPS Fail2ban

Web server security – Part 4: WAF ModSecurity and IPS Fail2ban

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.

Contents

  1. Requirements
  2. Definitions
  3. Setup
  4. Tests
  5. Continuous monitoring
  6. Summary
  7. Links

Always stay in the loop!
Subscribe to our RSS/Atom feeds.

Requirements

  • hardened web server as configured in part 2
  • SSH client on your computer
  • basic knowledge about firewalls

Definitions

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

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 login attempts, scanning for certain files, usage of blacklisted HTTP methods). Administrators can use regular expressions to customize standard configuration (so-called “jails”).

ModSecurity

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.

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.

Setup

In this section, we install and configure Fail2ban and OWASP ModSecurity CRS. Finally, we tell ModSecurity to use the CRS.

Fail2ban

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.

In jail.local, look for the following snippet and add enabled = true:

1
2
3
4
5
6
7
8
[…]
[sshd]
# Add the following line
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
[…]

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:

1
2
3
4
5
6
7
[…]
[apache-modsecurity]

port     = http,https
logpath  = %(apache_error_log)s
maxretry = 2
[…]

Change this to:

1
2
3
4
5
6
7
8
[…]
[apache-modsecurity]
enabled  = false
port     = http,https
logpath  = %(apache_error_log)s
bantime  = 86400
maxretry = 1
[…]

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

ModSecurity

Install ModSecurity: 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 modsecurity.conf file: sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf.

Enter the file sudo nano /etc/modsecurity/modsecurity.conf and change:

  • SecRuleEngine DetectionOnly to SecRuleEngine On (enables ModSecurity)
  • SecStatusEngine On to SecStatusEngine Off (disables transmission of information about your ModSecurity setup to the developer team)

OWASP ModSecurity CRS

Installing CRS requires git: 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 crs-setup.conf: 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:

1
2
3
4
5
6
7
8
9
[…]
SecAction \
 "id:900200,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.allowed_methods=GET'"
[…]

Carefully check which rules are useful and enable them by uncommenting them. 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity

        # Include all the \*.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
        IncludeOptional /etc/modsecurity/*.conf
        Include /etc/modsecurity/crs/crs-setup.conf
        Include /etc/modsecurity/rules/*.conf

        # Include OWASP ModSecurity CRS rules if installed
        # IncludeOptional /usr/share/modsecurity-crs/owasp-crs.load

        SecServerSignature " "
</IfModule>

Restart Apache web server: sudo systemctl restart apache2.

Tests

After restarting Fail2ban and Apache, you can test ModSecurity before we turn 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 [45]\d\d (?:.*)$.

Follow us on Mastodon:
@infosechandbook

Continuous monitoring

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.

Summary

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.

In the fifth part of this series, we show you basic server-side DNS security configuration.

See also