How to set up Fail2ban
Installing Fail2ban to automatically block repeated failed logins, configured safely so you do not end up banning yourself.
Fail2ban watches your server's log files for repeated failed login attempts and, once a threshold is crossed, temporarily blocks the offending IP address at the firewall. It is a defensive tool that reduces automated background noise against SSH and any other service you expose — it does not replace key-based login or a properly configured firewall, it complements both.
Install it
sudo apt install fail2ban -y # Ubuntu / Debian
sudo dnf install fail2ban -y # RHEL / Rocky / AlmaLinux
sudo systemctl enable --now fail2ban
Always configure jail.local, never jail.conf directly
Fail2ban ships a default configuration in /etc/fail2ban/jail.conf. Do not edit that file — it is overwritten whenever the package updates, silently taking your changes with it. Instead, create jail.local, which Fail2ban reads afterwards and which takes precedence over anything in jail.conf:
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
What each setting controls:
bantime— how long an offending IP stays blocked.1his one hour; use-1for a permanent ban, which is rarely a good idea on a dynamic IP address that could later belong to someone innocent.findtime— the window within which failures are counted toward the threshold.maxretry— how many failures withinfindtimetrigger a ban.ignoreip— addresses Fail2ban never bans, regardless of failures. Add your own static IP address here if you have one, so a mistyped password during testing cannot lock you out of your own server.
Apply the configuration:
sudo systemctl restart fail2ban
Check it is actually working
sudo fail2ban-client status
Lists the active jails. Check a specific one for its current ban count and banned IP list:
sudo fail2ban-client status sshd
Unbanning an IP address
If you, or someone you did not intend to block, ends up banned — most commonly from testing your own login and getting the password wrong too many times — unban it directly:
sudo fail2ban-client set sshd unbanip 203.0.113.10
While setting this up, keep one working SSH session open and add your own IP address to ignoreip before testing anything that might trigger a ban. Testing failed logins from the only connection you have to the server is how people end up needing the console recovery process covered in what to do when you are locked out of your VPS.
Adding jails for other services
Fail2ban ships filters for many common services beyond SSH — enable whichever you are actually running by adding a matching section to jail.local. For a website with a login form protected by Nginx or Apache, for example:
[nginx-http-auth]
enabled = true
[apache-auth]
enabled = true
Only enable a jail for a service that is actually installed and logging in the format that jail expects — an enabled jail with no matching log file to watch does nothing useful and can generate errors in Fail2ban's own log.
Reading what Fail2ban itself is doing
sudo tail -f /var/log/fail2ban.log
This is worth watching for a few minutes after first setting up a new jail, to confirm it is actually parsing the target log file correctly rather than silently matching nothing.
What actually happens when an IP is banned
Fail2ban does not intercept traffic itself — it watches logs, and when a jail's threshold is crossed, it inserts a rule into the server's own firewall (iptables, nftables, or ufw/firewalld depending on your setup) that drops traffic from that address. This is why Fail2ban needs to run as root, and why a ban is enforced at the network layer rather than by the service being protected — SSH itself never even sees the connection attempt from a banned address once the rule is in place.
Choosing sensible thresholds
The defaults above are a reasonable starting point, but tune them to your own risk tolerance:
- A lower
maxretrycatches automated scanning faster but increases the chance of banning a legitimate user who mistypes a password a few times in a row. - A longer
bantimeis more of a deterrent but risks blocking a legitimate, dynamically-assigned IP address for longer than the actual threat justified. - Fail2ban also supports escalating repeat offenders to progressively longer bans using its
bantime.incrementsetting, which rewards persistent scanners with longer blocks each time without needing you to tune a single fixed value for every scenario.
What Fail2ban does not do
It does not stop a targeted, low-and-slow attack that stays under the failure threshold, and it does not protect a service that is vulnerable rather than merely guessable. Treat it as one layer among several — alongside key-based SSH login, a properly scoped firewall (see setting up a firewall on your VPS), and keeping the system patched (see securing a new Linux server) — rather than a single fix for server security on its own.
Related reading
How to enable and configure a firewall on your VPS with ufw or firewalld, without accidentally shutting yourself out over SSH.
How to secure a new Linux serverThe concrete steps that actually matter for securing a fresh Linux server, in the order that keeps you from locking yourself out.
How to read Linux server logsWhere Linux keeps its logs, the commands to actually read them, and how to filter thousands of lines down to the one that matters.
How much RAM does my VPS need?It depends what is running, but free -h on an existing server and a look at what each extra service costs gets you a real answer fast.