image

What Is Fail2Ban and How to Use It on a VPS

Published : January 9, 2026
Last Updated : January 9, 2026
Published In : Technical Guide

Every day, automated bots scan thousands of servers, trying password after password until they find a weak spot and break in. One successful breach can compromise your entire server.

Fail2Ban acts as an automated security guard, monitoring your server logs and blocking suspicious IP addresses before they cause damage. It monitors authentication attempts and automatically bans attackers.

Understanding Fail2Ban

Fail2Ban is an open source intrusion prevention tool written in Python. It monitors your server log files and looks for patterns that indicate malicious activity. When someone tries logging into your SSH service with the wrong password multiple times, Fail2Ban notices this behavior. After a set number of failed attempts, it automatically adds their IP address to your firewall and blocks them for a specific duration. You can protect any service that writes authentication attempts to log files. This includes SSH, Apache, Nginx, Postfix, and dozens of other services.

How Fail2Ban Works

Fail2Ban reads log files looking for failed authentication attempts. It uses regex patterns to identify suspicious entries. When it finds a match, it counts how many times that IP address failed within a specific time window. Once the count exceeds your threshold, Fail2Ban takes action.


It communicates with your firewall to block that IP address. Modern systems have used nftables as the default firewall framework since 2019. Older systems use iptables. Fail2Ban supports both but requires explicit configuration. Bans typically last from minutes to days, depending on your configuration. After the ban period expires, Fail2Ban automatically removes the IP address.

Key Components

log file to monitor, and what action to take when violations occur. Filters define the patterns Fail2Ban looks for in log files. These regex patterns match suspicious log entries. Actions determine what happens when an IP gets flagged. The most common action is adding the IP to your firewall block list.

Prerequisites

Before installing Fail2Ban, ensure you have these requirements in place. This guide requires root or sudo access on Debian 10+, Ubuntu 20.04+, or similar distributions. Your system should have a firewall configured (nftables, iptables, or UFW) and basic command line familiarity.


Fail2Ban version 1.1.0 and higher requires Python 3.6 or higher. Version 1.1.0 completely removed Python 2 support in April 2024. Check your Python version with python3 –version to confirm compatibility.


Know your current public IP address before starting. Run curl ifconfig.me from your local machine to find it. This prevents locking yourself out during configuration.

Installing and Verifying Fail2Ban

Update your package lists and install Fail2Ban with the Python systemd library for modern log integration.

				
					systemctl enable --now fail2ban

				
			

You should see an active running status.

				
					fail2ban.service - Fail2Ban Service
   Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled)
   Active: active (running) since Wed 2025-12-11 10:30:22 UTC

				
			

Check your Fail2Ban version and verify systemd backend support.

				
					fail2ban-client --version
fail2ban-client --dp

				
			

The second command should show systemd in the available backends list.

Check System Configuration

Identify which firewall framework your system uses before configuring Fail2Ban.

Check if your system uses nftables, the standard since Debian 10 and Ubuntu 20.04.

				
					nft list ruleset
				
			

If this shows rules, you use nftables. If it returns an error, check for iptables.

				
					iptables -L
				
			

If this shows rules, you use iptables.

Verify that your system uses systemd journal for logging.

				
					journalctl -u ssh -n 5
				
			

If this shows recent SSH log entries, your system uses systemd journal and you must configure Fail2Ban to use the systemd backend.

Configuring SSH Protection

SSH protection should be your first priority. Successful SSH access gives attackers complete control.

Never edit jail.conf directly because updates will overwrite your changes. Create a jail.local file instead.

				
					nano /etc/fail2ban/jail.local
				
			

Add this complete configuration. Replace YOUR_ADMIN_IP_HERE with your actual IP address from the curl command earlier.

				
					[DEFAULT]
# === SECURITY: PREVENT SELF-LOCKOUT ===
ignoreip = 127.0.0.1/8 ::1 YOUR_ADMIN_IP_HERE

# === BAN SETTINGS ===
bantime = 3600
findtime = 600
maxretry = 3

# === FIREWALL INTEGRATION ===
banaction = nftables-multiport
banaction_allports = nftables[type=allports]

# === LOG INTEGRATION ===
backend = systemd

# === DATABASE MAINTENANCE ===
dbpurgeage = 86400

[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 3
bantime = 3600
findtime = 600

				
			

The ignoreip setting prevents Fail2Ban from ever banning specified addresses, protecting you from self-lockout during testing and administration.

The banaction settings tell Fail2Ban which firewall to use. Since 2019, nftables has been the default on modern distributions. If your system uses iptables, change these to iptables-multiport and iptables-allports. If you use UFW, change both to ufw.

The backend = systemd setting is critical for modern systems. Services like SSH now log to the systemd journal rather than traditional log files. This setting tells Fail2Ban to read directly from the systemd journal, providing better performance.

The dbpurgeage setting removes bans older than 24 hours from the database, keeping it manageable. For high traffic servers, you can reduce this to 43200 (12 hours) for more aggressive cleanup.

If you changed your SSH port from the default port 22, update the port setting. For example, if you moved SSH to port 2222, use port = 2222. Check your SSH port with grep Port /etc/ssh/sshd_config.

Test your configuration syntax before applying it.

				
					fail2ban-client -t
				
			

If the test passes, restart Fail2Ban.

				
					systemctl restart fail2ban

				
			

Verify that your SSH jail loaded correctly.

				
					fail2ban-client status
				
			

You should see output showing your active jails.

				
					Status
|- Number of jail:      1
`- Jail list:   sshd

				
			

Testing Your Configuration

Follow these steps to verify that Fail2Ban works correctly.

Step 1: Verify Fail2Ban Is Running

Check that Fail2Ban recognizes your jails.

				
					systemctl status fail2ban
fail2ban-client status

				
			

Your SSH jail should appear in the jail list.

 

Step 2: Perform a Test Ban

From a different machine where you are not logged in, attempt SSH login with wrong passwords three times. Verify that you added your regular admin IP to ignoreip before testing.

 

Step 3: Verify the Ban Took Effect

Check if the ban worked.

				
					fail2ban-client status sshd

				
			

You should see the test IP in the banned list.

				
					Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     3
|  `- File list:        systemd-journal
`- Actions
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   203.0.113.45

				
			

Check the log for ban confirmation.

				
					grep 'Ban' /var/log/fail2ban.log | tail -5
				
			

Step 4: Remove the Test Ban

Unban your test IP.

				
					fail2ban-client set sshd unbanip 203.0.113.45
				
			

Protecting Repeat Offenders

Sophisticated attackers may wait out bans and try again. The recidive jail catches these repeat offenders.

Add this to your jail.local file.

				
					[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = nftables-allports
bantime = 604800
findtime = 86400
maxretry = 3
protocol = all

				
			

This bans repeat offenders for one week. If an IP gets banned three times within 24 hours across any jails, recidive triggers the longer ban. Change banaction to iptables-allports for iptables systems or ufw for UFW systems.

Protecting Web Applications

Web services need protection too. Fail2Ban can secure any service that logs authentication attempts.

 

Securing Nextcloud

Create a custom filter for Nextcloud.

				
					nano /etc/fail2ban/filter.d/nextcloud.conf
				
			

Add this filter definition.

				
					[Definition]
failregex = Login failed.*REMOTE_ADDR=<HOST>
            ^.*Trusted domain error.*from <HOST>
ignoreregex =

				
			

Add the jail to your jail.local file. The logpath depends on your installation method.

				
					[nextcloud]
enabled = true
port = http,https
filter = nextcloud
maxretry = 3
bantime = 3600
logpath = /var/www/nextcloud/data/nextcloud.log

				
			

For Snap installations, use

				
					logpath = /var/snap/nextcloud/current/logs/nextcloud.log.
				
			

For Docker installations, Fail2Ban should always run on the host system, not inside containers, as it requires direct firewall and log access. First, find your volume name with docker volume ls, then inspect it to get the correct path.

				
					docker volume ls
docker volume inspect YOUR_VOLUME_NAME | grep Mountpoint

				
			

Use the discovered path in your configuration. For example, if your volume is named nextcloud_data, the path might be 

				
					/var/lib/docker/volumes/nextcloud_data/_data/nextcloud.log
				
			

Developing Custom Filters

When creating filters for applications not included with Fail2Ban, follow this process. First, identify the log location and format. Find failed authentication entries in the logs.

Create a regex pattern matching those entries. Test with fail2ban-regex to verify it works.

				
					fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

				
			

Successful output looks like this:

				
					Running tests
=============

Use   failregex filter file : sshd
Use         log file : /var/log/auth.log

Results
=======

Failregex: 3 total

Lines: 3 lines, 0 ignored, 3 matched, 0 missed

				
			

This confirms your filter correctly matches failed authentication attempts.

 

Securing Email Services

For Postfix email server, add this jail.

				
					[postfix]
enabled = true
port = smtp,submission,smtps
filter = postfix
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600

				
			

After adding new jails, restart Fail2Ban and verify they have loaded.

				
					systemctl restart fail2ban
fail2ban-client status

				
			

Configuring Email Notifications

Configure Fail2Ban to send email notifications when bans occur. First, ensure your system can send email by installing and configuring postfix or similar.

Add to your jail.local DEFAULT section:

				
					destemail = admin@yourdomain.com
sendername = Fail2Ban-Alert
mta = sendmail
action = %(action_mwl)s

				
			

The action_mwl sends mail with whois info and log lines. Other options include action_mw for mail with whois only, or action_ for bans without email.

 

Monitoring Fail2Ban Activity

Check active bans across all jails.

				
					fail2ban-client status

				
			

For detailed information about a specific jail, add its name.

				
					fail2ban-client status sshd
				
			

Version 1.1.0 introduced a statistics command.

				
					fail2ban-client stats

				
			

This displays backend types used, ban counts over time, and jail performance metrics.

View all ban actions.

				
					grep 'Ban' /var/log/fail2ban.log
				
			

Watch Fail2Ban activity in real time.

				
					tail -f /var/log/fail2ban.log

				
			

Troubleshooting Common Issues

 

Have Not Found Any Log File Error

If you see this error, add backend = systemd to your jail configuration and restart.

				
					apt install python3-systemd -y
systemctl restart fail2ban

				
			

Iptables Command Errors

If you see iptables errors, your system uses nftables. Change banaction settings to nftables-multiport and nftables-allports in the DEFAULT section.

Backend Systemd Failed to Initialize

Install the Python systemd library.

				
					apt install python3-systemd -y
systemctl restart fail2ban

				
			

Fail2Ban Not Banning Attackers

Verify the jail is enabled.

				
					fail2ban-client status
				
			

Check if Fail2Ban reads the correct log files.

				
					fail2ban-client get sshd logpath
				
			

Test your filter against logs.

				
					fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
				
			

Watch the Fail2Ban log for errors.

				
					tail -f /var/log/fail2ban.log

				
			

Locked Yourself Out

Access your server through your hosting provider’s web console. Unban your IP.

				
					fail2ban-client set sshd unbanip YOUR_IP_ADDRESS
				
			

Then add your IP to ignoreip so it does not happen again.

Performance Optimization

For high-traffic servers, optimize Fail2Ban performance with these settings.

Use the systemd backend for much faster log reading than polling files.

				
					backend = systemd

				
			

Reduce database bloat by purging old entries more aggressively. The standard setting is 86400 (24 hours), but busy servers can use 43200 (12 hours) for more aggressive cleanup.

				
					dbpurgeage = 43200
				
			

Only enable jails for services you actually run. Each active jail consumes resources.

Use stricter thresholds to reduce false positives.

				
					findtime = 300
maxretry = 2

				
			

Best Practices for Long Term Security

Run regular updates to get bug fixes and new filter patterns.

				
					apt update && apt upgrade fail2ban

				
			

Use Fail2Ban alongside your firewall for defense in depth. If you have not set up UFW yet, install and configure it.

				
					apt install ufw -y
ufw allow ssh
ufw enable

				
			

If using UFW, remember to set banaction = ufw in your Fail2Ban configuration.

Back up the /etc/fail2ban directory regularly using rsync.

				
					rsync -av /etc/fail2ban /backup/location/


				
			

Archive your logs instead of deleting them. They help you identify attack patterns. Note that if using traditional log files instead of the systemd backend, ensure log rotation is configured to reload Fail2Ban with systemctl reload fail2ban in your logrotate configuration.

Understanding Rate Limiting and Fail2Ban

Fail2Ban blocks IPs after failed authentication attempts, but this approach cannot stop distributed attacks from thousands of different IPs. For these scenarios, combine Fail2Ban with application-level rate limiting.

Fail2Ban provides IP-level protection after authentication failures. Rate limiting controls requests per IP before authentication even occurs. Use both together for comprehensive defense.

When attackers use botnets, banning individual IPs becomes ineffective. In these cases, rate limiting at the application level helps more. For example, Nginx can limit requests per IP address, complementing Fail2Ban protection.

Modern Deployment Considerations

If you run services in Docker containers, Fail2Ban should run on the host system, not inside containers. While technically possible to run Fail2Ban inside containers, the community strongly discourages this. Fail2Ban needs direct access to the host firewall and log sources.


Many cloud providers use specific IP ranges for health checks. Add these to your ignoreip list to prevent banning health check services. Common cloud provider ranges include AWS (54.240.0.0/12), GCP (35.191.0.0/16, 130.211.0.0/22), and Azure (check Azure Portal for current ranges). Always verify current ranges with your provider, as these can change.

IPv6 Considerations

Modern attackers increasingly use IPv6 addresses. Your configuration should handle both IPv4 and IPv6 properly. Include IPv6 localhost in ignoreip with ::1, which the example configurations already do.

Fail2Ban automatically handles both IPv4 and IPv6 addresses. Your firewall (nftables or iptables) must support IPv6 for bans to work correctly. Verify your configuration handles both protocols by checking banned IPs with fail2ban-client status sshd, which shows both IPv4 and IPv6 addresses.

Understanding Fail2Ban Limitations

The tool cannot protect against zero day exploits or vulnerabilities. Keep applications updated and follow security best practices beyond just Fail2Ban.

If someone has legitimate credentials from a data breach, Fail2Ban cannot stop them. Use two-factor authentication for critical services as additional protection.

Essential Commands Reference


Status and Monitoring

				
					fail2ban-client status
fail2ban-client status sshd
fail2ban-client stats
tail -f /var/log/fail2ban.log

				
			

Ban Management

				
					fail2ban-client set sshd banip 203.0.113.45
fail2ban-client set sshd unbanip 203.0.113.45

				
			

Configuration

				
					fail2ban-client -t
systemctl reload fail2ban
fail2ban-client get sshd logpath

				
			

Testing

				
					fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

				
			

Conclusion

Fail2Ban transforms your server from a passive target into an active defender. It works continuously in the background, identifying threats and blocking them before damage occurs. Start with SSH protection since it remains the most common attack vector. Once SSH protection runs smoothly, expand protection to other services.


Security is not a one-time task. Review your Fail2Ban logs monthly to understand attack patterns. Update configurations as you add or remove services. Keep the software current with security patches. Combined with strong passwords, firewall rules, rate limiting, and regular updates, Fail2Ban forms a solid foundation for server security.


About the Author Peter French is the Managing Director at Virtarix, with over 17 years in the tech industry. He has co-founded a cloud storage business, led strategy at a global cloud computing leader, and driven market growth in cybersecurity and data protection.

Other posts

image
January 9, 2026
Published in : Technical Guide
What Is Fail2Ban and How to Use It on a VPS

Learn what Fail2Ban is and how to secure your VPS by automatically blocking brute-force attacks on SSH, web, and email services.

image
December 17, 2025
Published in : Technical Guide
How to Install Nexcloud on VPS

Step-by-step guide to install Nextcloud 32 on Debian 12 VPS with SSL, Redis, backups, and firewall for secure, private cloud storage.

image
December 12, 2025
Published in : Technical Guide
What is Umask and How to Use It on a VPS?

Learn how umask controls default file and directory permissions, and how to configure it on your VPS for better security, collaboration, and server management.

Listed on WHTop.com Listed on WHTop.com

© 2026 : Virtarix. All Rights Reserved