Configure Fail2Ban on Ubuntu VPS: Step-by-Step

Why Fail2Ban Matters on a Debian VPS
SSH brute-force attempts start within hours of a new server going live. If your Debian VPS is publicly accessible — and it is — you will see login attempts in your auth logs almost immediately. Fail2Ban is the standard first line of defence: it watches log files and temporarily bans IP addresses that exceed a failure threshold.
This tutorial walks through a clean Fail2Ban setup on Debian 12 (Bookworm). The same steps apply to Debian 11 with minor package version differences. By the end, you will have SSH protection active, a basic Apache jail configured, and email alerts working.
If you are running a Hostperl VPS on Debian, this is one of the first things worth configuring after initial provisioning — before you point any domains or open additional ports.
Before You Start: What You Need
- A Debian 12 or 11 VPS with root or sudo access
- SSH access confirmed and working
- A basic understanding of text editors (nano is fine)
- An outbound mail relay if you want email alerts (optional but recommended)
You do not need a control panel. This is all done over SSH. If you have not yet set up SSH key authentication, do that first — it is a natural companion to Fail2Ban and covered in our guide on configuring SSH key authentication on a VPS.
Step 1 — Install Fail2Ban on Debian
Update your package list and install Fail2Ban from the default Debian repositories:
sudo apt update
sudo apt install fail2ban -y
Once installed, the service starts automatically. Confirm it is running:
sudo systemctl status fail2ban
You should see active (running). If not, start and enable it:
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
Fail2Ban on Debian 12 ships as version 1.0.x. Check with fail2ban-client --version if you need to confirm.
Step 2 — Understand the Configuration Structure
Fail2Ban separates its configuration into two layers. The /etc/fail2ban/jail.conf file is the default — but you should never edit it directly, because package updates will overwrite your changes.
Instead, create a local override file:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Any setting in jail.local takes precedence over jail.conf. The same pattern applies to filter and action files under /etc/fail2ban/filter.d/ and /etc/fail2ban/action.d/.
Step 3 — Configure Global Defaults
Open your local jail file:
sudo nano /etc/fail2ban/jail.local
Find the [DEFAULT] section near the top. Set these values:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
banaction = iptables-multiport
backend = systemd
A quick explanation of each setting:
- bantime — How long an offending IP stays banned.
1his a sensible default; you can raise it to24hor use-1for a permanent ban. - findtime — The window in which failures are counted. Five failures in ten minutes triggers a ban.
- maxretry — Number of failures allowed before the ban fires.
- banaction — The firewall method used.
iptables-multiportworks reliably on Debian without nftables complications. - backend — Set to
systemdon Debian 12, which uses journald rather than flat log files for most services.
If you are also running UFW on this server, note that Fail2Ban manages its own iptables chains separately. They can coexist without conflict — but for a clean setup, it helps to understand which tool owns which rules. Our tutorial on configuring UFW on a VPS covers that boundary clearly.
Step 4 — Enable the SSH Jail
Scroll down in jail.local to find the [sshd] section, or add it manually if it is not present:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
If you have changed your SSH port from the default 22, replace ssh with the actual port number:
port = 2299
On Debian 12, %(sshd_log)s resolves to the systemd journal. Fail2Ban reads it correctly when backend = systemd is set in the defaults.
Three failed attempts is tighter than the global default of five. SSH is your most exposed service, so it warrants stricter treatment.
Step 5 — Add an Apache Jail (Optional)
If Apache is running on this server, add basic HTTP protection. This catches bots hammering login pages and probing for WordPress vulnerabilities:
[apache-auth]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 6
[apache-noscript]
enabled = true
port = http,https
logpath = %(apache_access_log)s
maxretry = 6
The apache-noscript jail blocks clients requesting executable file types that do not exist on your server — a common scanning pattern. Both jails use Fail2Ban's built-in filter definitions, so no custom filter file is needed.
Step 6 — Set Up Email Alerts
Getting an email when an IP is banned is useful, especially during the first few weeks on a new server. Add these lines under [DEFAULT]:
destemail = you@yourdomain.com
sendername = Fail2Ban
mta = sendmail
action = %(action_mwl)s
action_mwl sends an email with the ban reason and recent log lines. You need a working MTA on the server — sendmail or postfix both work. Install a lightweight option if needed:
sudo apt install sendmail -y
If your server sends outbound mail through a relay (common with shared IP addresses), make sure port 587 is open and SMTP AUTH is configured. Our VPS email hosting checklist covers the relay and deliverability side of that.
Step 7 — Apply Changes and Test
Restart Fail2Ban to load your new configuration:
sudo systemctl restart fail2ban
Check that your jails are active:
sudo fail2ban-client status
You should see both sshd and any other jails you enabled listed under active jails. Inspect a specific jail:
sudo fail2ban-client status sshd
This shows the currently banned IPs, the failure count, and when bans were applied. A clean new server will show zero bans — give it a few hours and that changes.
How to Unban an IP Address
Occasionally you will accidentally lock out a legitimate user — or yourself. Unban an IP immediately with:
sudo fail2ban-client set sshd unbanip 203.0.113.45
Replace the IP with the one you need to release. The ban is removed from iptables instantly. It will re-trigger if the same IP exceeds the threshold again, so address the root cause (wrong password, key mismatch) before giving it back access.
If you lock yourself out entirely, you will need to access the server through your hosting provider's console. On Hostperl VPS plans, the VPS control panel provides out-of-band console access for exactly this situation.
Checking Fail2Ban Logs
Fail2Ban writes its own log to /var/log/fail2ban.log. Tail it to watch bans happen in real time:
sudo tail -f /var/log/fail2ban.log
You will see lines like:
2026-03-14 08:22:11,043 fail2ban.actions [INFO] [sshd] Ban 198.51.100.22
If you want structured daily summaries rather than tailing raw logs, pair Fail2Ban with Logwatch. The tutorial on configuring Logwatch on Debian VPS shows how to set that up so you get a daily digest covering Fail2Ban activity alongside other server events.
Persistent Bans Across Reboots
By default, Fail2Ban clears its ban list when it restarts. For most shared hosting or VPS environments, this is acceptable — repeat offenders tend to trigger a new ban quickly anyway.
If you want bans to persist through reboots, enable the database backend:
[DEFAULT]
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 1d
This stores bans in a local SQLite database. Set dbpurgeage to control how long old records are kept. After the next restart, Fail2Ban restores active bans from the database rather than starting clean.
Running Debian on a VPS and want a clean, well-provisioned environment to work from? Hostperl VPS plans give you full root access, fast SSD storage, and a reliable network — exactly what you need for security-hardened server setups. Need more resources or dedicated capacity? Dedicated server plans are available for sites that have grown beyond shared VPS.
Frequently Asked Questions
Does Fail2Ban work with nftables on Debian 12?
Yes, but the default iptables-multiport banaction works fine on Debian 12 even though nftables is the system default. Fail2Ban uses iptables compatibility layers. If you prefer native nftables integration, set banaction = nftables-multiport — but test carefully before relying on it in production.
Will Fail2Ban interfere with my cPanel or Plesk installation?
Fail2Ban coexists with cPanel and Plesk, both of which have their own firewall management tools (CSF/LFD on cPanel, Plesk Firewall on Plesk). Running them together can cause rule conflicts. On cPanel servers, CSF already provides Fail2Ban-like functionality — so in that case, you would configure CSF rather than Fail2Ban directly.
How do I whitelist my own IP address?
Add your IP to the ignoreip list in [DEFAULT]:
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
Separate multiple IPs or CIDR ranges with spaces. Your own IP will never be banned, regardless of failure count.
How do I know if Fail2Ban is actually blocking anything?
Run sudo fail2ban-client status sshd and check the Currently banned and Total banned counters. You can also run sudo iptables -L f2b-sshd -n --line-numbers to see the active iptables rules Fail2Ban has inserted.
Can I increase the ban time for repeat offenders?
Yes. Use the bantime.increment feature introduced in Fail2Ban 0.10. Add to [DEFAULT]:
bantime.increment = true
bantime.factor = 1
bantime.maxtime = 1w
Each time an IP triggers a new ban, the ban duration multiplies. A persistent attacker can end up banned for a week automatically.
