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:
- Install Fail2Ban:
sudo apt-get update
sudo apt-get install -y fail2ban
- Configure Fail2Ban:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local # Copy to edit
sudo nano /etc/fail2ban/jail.local
- 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 thenginx
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 themaxretry
attempts must occur.bantime = 1d
: How long to ban the IP address (1 day).
- Restart Fail2Ban:
sudo systemctl restart fail2ban
- 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
- 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
- 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
andNET_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.