Fail2ban

From Extremely Corporate Wiki
Jump to navigation Jump to search

Fail2ban is an application-level firewall (that is to say it monitors individual pieces of software instead of packet flow) which works by scanning the logs of programs for reports of malicious activity and blocking the reported perpetrator.

Configuration

  • Configure your individual application level filters in /etc/fail2ban/filter.d
  • Configure your jail rules (punishments for triggering the filters) in /etc/fail2ban.jail.local

The simplest possible setup is to use the "allports" ban action for everything which completely blocks banned addresses.

You can configure this by setting up the [DEFAULT] section of jail.local like so:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
banaction = nftables[type=allports]
  • ignoreip is set to prevent localhost from ever being banned
  • If you use iptables, replace nftables[type=allports] with iptables-allports. You can find available ban actions in /etc/fail2ban/action.d.

Using Fail2ban and Nginx to block automated bot spam

You can use Nginx together with Fail2ban to block many automated attacks. Nginx has a pseudo return code, 444, which just terminates the connection instead of serving a response. You can detect this with fail2ban using the following filter:

# /etc/fail2ban/filter.d/nginx-444.conf
[Definition]
failregex = ^<HOST> -.*".*HTTP.*" 444
ignoreregex =

This reads Nginx access logs looking for requests that were "served" 444 so we can ban their addresses.

Put the following in jail.local to use this filter:

[nginx-444]
enabled = true
logpath = /var/log/nginx/*access.log

You can set bantime, maxretry, etc. as desired. Personally, I just ban addresses forever since exceptions can always be made if this causes problems.

Nginx never returns 444 in the default configuration, so this filter will only be triggered by conditions we specify. Here are some ideas:

Set the default server to return 444. Assuming Nginx is configured to serve all your domains and subdomains, this will make it so that if someone tries to reach you on the web directly from your address (not a DNS lookup on your domain name), they can be blocked. This is useful because this type of traffic is 99.9% malicious.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    return 444;
    error_page 400 =444 /bad_request;
    location /bad_request {
        internal;
        return 444;
    }
}

You can also extend this to serve HTTPS by default as well. If you do this, I recommend serving a self-signed certificate that contains no information about your domains to make circumventing this defense slightly more difficult.

This config also returns 444 for bad requests. Nginx generates this response for any sort of malformed request it receives. Any malformed request sent directly to your IP address is almost guaranteed to be an attempt to exploit some CVE.