Protecting your web services is crucial in today’s interconnected world.

Fail2Ban is a powerful tool that can help you mitigate brute-force attacks and other malicious activities by monitoring logs and automatically banning offending IP addresses.

This post will show you how to set up Fail2Ban to work with Nginx, both using a traditional installation and a Dockerized approach.

What is Fail2Ban?

Fail2Ban is an intrusion prevention system (IPS) that analyzes log files (like those from Nginx, Apache, SSH, etc.) for suspicious patterns, such as repeated failed login attempts.

When it detects malicious activity, Fail2Ban can take action, typically by adding the offending IP address to firewall rules to block further connections.

Why use Fail2Ban with Nginx?

Fail2Ban is an excellent way to enhance the security of your Nginx web server. It can help protect against:

  • Brute-force attacks: Fail2Ban can detect and block IP addresses attempting to guess passwords for your website’s login forms.
  • Denial-of-service (DoS) attacks: While not a complete DoS solution, Fail2Ban can mitigate some simpler DoS attacks by blocking IP addresses making excessive requests.
  • Malicious bots: Fail2Ban can be configured to block IP addresses associated with known malicious bots.

Setting up Fail2Ban with Nginx (Traditional Installation)

Here’s how to install and configure Fail2Ban on your Ubuntu system to work with Nginx:

  1. Install Fail2Ban:
sudo apt-get update
sudo apt-get install -y fail2ban
  1. Configure Fail2Ban:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local  # Copy to edit
sudo nano /etc/fail2ban/jail.local
  1. Add Nginx Jail Configuration (in jail.local):
[nginx-http-auth]
enabled = true
port    = http,https
logpath = /var/log/nginx/access.log
backend = nginx
maxretry = 3
findtime = 10m  # Time window to check for failures
bantime = 1d    # Ban duration (1 day)
  • Explanation:
    • [nginx-http-auth]: Defines a new jail for Nginx HTTP authentication failures.
    • enabled = true: Enables the jail.
    • port = http,https: Specifies the ports to monitor (HTTP and HTTPS).
    • logpath = /var/log/nginx/access.log: The path to your Nginx access log file. Adjust if necessary.
    • backend = nginx: Tells Fail2Ban to use the nginx backend. This is important for log parsing.
    • maxretry = 3: The number of failed attempts before an IP is banned.
    • findtime = 10m: The time window within which the maxretry attempts must occur.
    • bantime = 1d: How long to ban the IP address (1 day).
  1. Restart Fail2Ban:
sudo systemctl restart fail2ban
  1. Verify Fail2Ban:
sudo systemctl status fail2ban
sudo tail -f /var/log/fail2ban.log  # Check the log for activity

Setting up Fail2Ban with Nginx (Dockerized)

For a more containerized approach, you can use the crazymax/fail2ban Docker image.

You can follow this NGINX setup Post if you are also new to NGINX

version: '2'
services:
  fail2ban:
    image: crazymax/fail2ban:latest
    restart: unless-stopped
    network_mode: "host"  # Or use a Docker network if preferred
    cap_add:
      - NET_ADMIN
      - NET_RAW
    volumes:
      - /var/log:/var/log:ro  # Mount the host's log directory (read-only)
      - ~/Docker/fail2ban/data:/data # Persist Fail2Ban data
    environment: # Or use an env_file
      TZ: "Your/Timezone" # Set your timezone
      FAIL2BAN_BANTIME: 86400 # Ban for 24h
      FAIL2BAN_MAXRETRY: 3
      FAIL2BAN_FINDTIME: 600 # 10 minutes
      # Add other jails here
      FAIL2BAN_JAILS: "nginx-http-auth"
      FAIL2BAN_NGINX_HTTP_AUTH_ENABLED: "true"
      FAIL2BAN_NGINX_HTTP_AUTH_LOGPATH: "/var/log/nginx/access.log"

  nginx: # Your Nginx service (example)
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - /var/log/nginx:/var/log/nginx # Mount logs for fail2ban
    depends_on:
      - fail2ban
  1. Create Directory and Docker Compose File:
mkdir Docker
cd Docker
mkdir fail2ban
cd fail2ban
wget  -cO - [https://raw.githubusercontent.com/reisikei/docker/main/Security/fail2ban_docker-compose.yaml](https://raw.githubusercontent.com/reisikei/docker/main/Security/fail2ban_docker-compose.yaml) -O docker-compose.yaml # or create it manually
nano docker-compose.yaml # to adjust the file
  1. Run with Docker Compose:
sudo docker-compose up -d

Key improvements and explanations for the Dockerized approach:

  • Volumes: Mounting /var/log (read-only) allows the Fail2Ban container to access the Nginx logs on the host. Mounting a persistent volume for /data ensures that bans are preserved across container restarts.
  • Capabilities: NET_ADMIN and NET_RAW are required for Fail2Ban to modify firewall rules.
  • Environment Variables: Using environment variables makes it easier to configure Fail2Ban jails within the Docker Compose file. You can easily define parameters like bantime, maxretry, and the log path.
  • Nginx Service: The example includes an Nginx service. You’ll likely already have your own Nginx service, but this demonstrates how to ensure the logs are available to Fail2Ban. The depends_on ensures Fail2Ban starts before Nginx.
  • Timezone: Setting the TZ environment variable is crucial for Fail2Ban to correctly interpret timestamps in the logs.

Conclusion

Fail2Ban is a valuable tool for enhancing the security of your Nginx web server.

Whether you choose a traditional installation or a Dockerized approach, Fail2Ban can help protect your services from malicious activity.

Remember to adjust the configuration to suit your specific needs and monitor the Fail2Ban logs for any issues.