New Customers: 50% OFF Your First Month on All VPS Servers & Web Hosting Plans!

fail2ban and automatic security updates

Fail2ban watches for repeated failed login attempts and automatically blocks the source IP using your system firewall. Pair it with automatic security updates to close known vulnerabilities without manual intervention. This guide covers Ubuntu 24.04 and AlmaLinux 9.

HostworldSecurity 8 min read Updated 23 Sep 2026 AlmaLinux 9, Ubuntu 24.04

Answer

Use Fail2ban to watch for repeated failed logins, then block the source IP automatically using your system firewall. Add either incremental bans that get longer each time, or a recidive jail that rebans offenders seen across several jails. Pair that with automatic security updates so known vulnerabilities are closed without waiting for manual patching.

This picks up from a server you can already reach over SSH. If you get locked out while testing, use the VNC console in Virtualizor from the Hostworld client area to regain access and fix your rules.

Before you start

  • Root access or a user with sudo is required.
  • Do not edit /etc/fail2ban/jail.conf. Put your changes in /etc/fail2ban/jail.d/*.conf or *.local. The parser applies settings in this order: jail.conf then jail.d/*.conf then jail.local then jail.d/*.local. Upgrades can overwrite *.conf. Using your own file in jail.d keeps your changes safe.
  • On Ubuntu 24.04, the packaging sets banaction = nftables by default and provides a UFW action if you prefer to manage bans through UFW. Pick one method and keep it consistent. Bans applied with nftables will not appear in ufw status.
  • On AlmaLinux 9, Fail2ban integrates with firewalld. Use the documented firewalld actions such as firewallcmd-rich-rules or firewallcmd-allports. Ensure firewalld is running so bans take effect.
  • On modern distributions that use systemd journals, Fail2ban often reads logs with backend = systemd. In that mode, logpath is ignored and journalmatch is used instead. Old instructions that point to /var/log/auth.log on Ubuntu 24.04 will not work with the systemd backend.
  • Set the backend per jail, not in the global [DEFAULT] section. A global backend = systemd also applies to the recidive jail, and recidive's stock definition reads a file at /var/log/fail2ban.log, which the systemd backend ignores. That combination quietly breaks recidive.
  • If you enable the recidive jail, it reads /var/log/fail2ban.log. If Fail2ban is configured to log to the journal only, recidive will not see anything and can fail to start. Make sure Fail2ban writes a file log before enabling recidive or use the documented skip_if_nologs behaviour.
  • Automatic updates can restart services and can reboot if you enable that. On Ubuntu 24.04, needrestart may restart services automatically after updates. On AlmaLinux 9, enabling dnf-automatic-install.timer installs updates on a schedule. Set maintenance windows and decide on reboots before you enable these features.
  • On Ubuntu 24.04 the SSH service is called ssh and is socket activated. systemctl restart sshd will fail. Use systemctl restart ssh.

Step 1: Install Fail2ban

Install the Fail2ban package and, where relevant, its firewall integration.

AlmaLinux 9: install Fail2ban and its firewalld action. AlmaLinux 9 gets Fail2ban from EPEL 9.

sudo dnf install fail2ban fail2ban-firewalld

If that command reports “No match for argument: fail2ban”, EPEL is not enabled on the server. This installs the EPEL release package, which adds the EPEL 9 repositories, and then installs Fail2ban.

sudo dnf install epel-release
sudo dnf install fail2ban fail2ban-firewalld

Ubuntu 24.04: update your package lists, then install Fail2ban from the Ubuntu archive.

sudo apt update
sudo apt install fail2ban

Step 2: Start Fail2ban and ensure the firewall it needs is active

Enable and start the Fail2ban service so it runs now and on boot.

AlmaLinux 9: start Fail2ban and ensure firewalld is running so bans can be applied as rich rules.

sudo systemctl enable --now fail2ban
sudo systemctl enable --now firewalld

Ubuntu 24.04: start Fail2ban. Ubuntu uses nftables by default. If you use UFW and want Fail2ban to place rules through it, we will set that in a later step.

sudo systemctl enable --now fail2ban

Step 3: Allowlist your management IP and set safe defaults

Create an override file that allowlists your office or jump host and sets sane defaults that will survive package upgrades.

What this does: creates a file in /etc/fail2ban/jail.d/ that sets ignoreip in the global [DEFAULT] section. It also defines a starting ban window you can adjust later. The backend is deliberately left out here and set per jail in Step 4, so that jails which read a log file, recidive in particular, keep working.

Replace 203.0.113.10 with your own IPv4 or a CIDR range. You can add several values separated by spaces. ignoreself = true tells Fail2ban to never ban the server’s own IP.

AlmaLinux 9 and Ubuntu 24.04:

sudo tee /etc/fail2ban/jail.d/00-hostworld-defaults.local >/dev/null <<'EOF'
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
ignoreself = true
bantime = 15m
findtime = 10m
maxretry = 5
EOF

Step 4: Enable and tune the SSH jail

Ubuntu 24.04: confirm defaults and enable the SSH jail

Check the packaging defaults so you do not fight them. This prints the current default banaction and backend shipped by Ubuntu.

grep -E '^\s*(banaction|backend)\s*=' /etc/fail2ban/jail.d/defaults-debian.conf || true

Enable the SSH jail. The jail is called sshd even though the service is ssh.

What this does: creates a per-jail override enabling [sshd] and sets the systemd backend for that jail only. Longer bans for repeat offenders are handled in Step 6, so there is one place that controls them.

sudo tee /etc/fail2ban/jail.d/10-sshd.local >/dev/null <<'EOF'
[sshd]
enabled = true
port = ssh
backend = systemd

bantime = 15m
findtime = 10m
maxretry = 5
EOF

If you manage your firewall through UFW and want Fail2ban to add rules there, set the action to UFW. If you are happy with the default nftables handling, skip this.

sudo tee /etc/fail2ban/jail.d/15-ufw-action.local >/dev/null <<'EOF'
[DEFAULT]
action = ufw
EOF

AlmaLinux 9: enable the SSH jail and pick the firewalld action

Enable the SSH jail using the systemd backend for that jail. Set the ban action to a firewalld integration that adds rich rules. Use firewallcmd-allports if you want the ban to apply to all ports, not only SSH.

sudo tee /etc/fail2ban/jail.d/10-sshd.local >/dev/null <<'EOF'
[sshd]
enabled = true
port = ssh
backend = systemd

# Use firewalld actions on AlmaLinux 9
banaction = firewallcmd-rich-rules
# Alternative: block on all ports
# banaction = firewallcmd-allports

bantime = 15m
findtime = 10m
maxretry = 5
EOF

Step 5: Apply the changes and verify

Restart Fail2ban so it picks up your new jail files.

AlmaLinux 9 and Ubuntu 24.04:

sudo systemctl restart fail2ban

List active jails to confirm SSH is enabled.

sudo fail2ban-client status
sudo fail2ban-client status sshd

If you do not see sshd in the jail list, recheck that your file in /etc/fail2ban/jail.d/ ends with .conf or .local, that enabled = true is present, and that the backend is not misconfigured. With backend = systemd, do not add a logpath.

Step 6: Choose how to identify repeat attackers

Option A: Progressive bans using bantime.increment

Fail2ban can lengthen bans automatically for IPs that have been banned before. It uses its persistent SQLite database at /var/lib/fail2ban/fail2ban.sqlite3 to track history.

What this does: sets incremental bans in [DEFAULT], so every jail you enable gets them, including the SSH jail from Step 4. The multipliers mean a first ban is 15 minutes, then 30, 60, 120, 240 and so on until the final multiplier is reached. Keep these settings in this one file. If you also put bantime.increment in a per-jail file, the jail's own value is the one that applies to that jail and the two will drift apart as you edit them.

sudo tee /etc/fail2ban/jail.d/20-bantime-increment.local >/dev/null <<'EOF'
[DEFAULT]
bantime = 15m
bantime.increment = true
# Double, then double again, up to a ceiling
bantime.multipliers = 1 2 4 8 16 32
EOF

Option B: Recidive jail to reban chronic offenders across jails

The stock recidive filter watches the Fail2ban log for repeated bans across your jails and then applies a longer ban. It reads /var/log/fail2ban.log by default.

  • Enable this only if Fail2ban writes a file log. If your Fail2ban logtarget is the systemd journal only, recidive will not match anything. Switch Fail2ban to write a /var/log/fail2ban.log file before enabling, or use the documented skip_if_nologs behaviour as appropriate for your setup.
  • Do not set backend = systemd for this jail, and check that you have not set it in [DEFAULT] either. With the systemd backend the logpath is ignored, and recidive has nothing to read.

What this does: enables the recidive jail with a longer ban time and a wider observation window, leaving the stock file-based log reading in place.

sudo tee /etc/fail2ban/jail.d/30-recidive.local >/dev/null <<'EOF'
[recidive]
enabled = true
# Uses the stock recidive filter which reads /var/log/fail2ban.log
# Ensure Fail2ban is configured to write that file before enabling
bantime = 1w
findtime = 1d
maxretry = 5
EOF

Restart Fail2ban after changing this.

sudo systemctl restart fail2ban

Step 7: Keep the system patched with automatic security updates

Ubuntu 24.04: unattended-upgrades

Install the unattended-upgrades package if it is not already present.

sudo apt install unattended-upgrades

Installing the package is not enough on its own. Unattended upgrades only run if the periodic settings are switched on. This prints the current state of that file.

cat /etc/apt/apt.conf.d/20auto-upgrades

What this does: writes the two periodic settings that make package lists refresh and unattended upgrades actually run. If the file is missing, or either value is "0", write it as below. Without this, anything you set afterwards has no effect because upgrades never run unattended.

sudo tee /etc/apt/apt.conf.d/20auto-upgrades >/dev/null <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
EOF

Enable or tune automatic reboots safely by creating a small override so your settings are clear and preserved.

What this does: writes a file that enables automatic reboots after upgrades that require it, and schedules them for 03:30. By default, unattended reboots are off. From 24.04 LTS, services may be restarted automatically by needrestart after updates.

sudo tee /etc/apt/apt.conf.d/51-hostworld-auto-reboot >/dev/null <<'EOF'
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:30";
EOF

Check the timers that drive unattended upgrades. The pattern is quoted so the shell passes it to systemctl instead of matching files in your current directory.

systemctl list-timers 'apt*' --no-pager

AlmaLinux 9: dnf-automatic with systemd timers

Install the dnf-automatic tools if they are not present.

sudo dnf install dnf-automatic

Edit the configuration to restrict to security updates and apply them automatically.

What this does: opens the configuration file so you can set upgrade_type=security and apply_updates=yes, which installs only security updates unattended.

sudo nano /etc/dnf/automatic.conf

In that file set:

  • upgrade_type = security
  • apply_updates = yes

Enable the timer that installs updates on schedule.

sudo systemctl enable --now dnf-automatic-install.timer
systemctl list-timers "*dnf*" --no-pager

Plan and announce maintenance windows if a reboot will be needed after kernel or glibc updates.

Step 8: Verify and test safely

Check Fail2ban’s view of jails and recent activity.

sudo fail2ban-client status
sudo fail2ban-client status sshd

On Ubuntu 24.04, if you switched to UFW actions, you can confirm bans appear there. With nftables actions, bans will not be listed by UFW.

sudo ufw status verbose

On AlmaLinux 9 with firewalld actions, you can inspect rich rules applied to the public zone.

sudo firewall-cmd --zone=public --list-rich-rules

Do not test by locking yourself out from your only IP. If you must test, use a second connection from a different address, or use the Virtualizor VNC console in the Hostworld client area so you can undo a ban if it catches you.

What next

  • Continue hardening SSH. Move to key-based authentication and adjust your SSH daemon settings. This reduces the noise Fail2ban has to process and cuts off password attacks early.
  • If you are weighing up a new server for this build, see our London VPS. We also run VPS in New York if you want your server in the US. You choose AlmaLinux or Ubuntu during the build, or mount your own ISO in Virtualizor.
  • Browse more how-tos and security notes in our VPS guides.
  • If anything here does not behave as described, open a support ticket. We can check your VPS from our side and help you recover access if a ban caught you.

Next step: Harden SSH access and keys.

Common questions

Is it better to use recidive or bantime.increment?

They solve slightly different problems. bantime.increment lengthens bans for addresses that have been banned before. It uses Fail2ban’s database to count previous bans and applies longer times automatically. recidive watches the Fail2ban log for multiple bans across your jails and then applies a longer, often all‑ports ban. If you only run a small number of jails, incremental bans may be enough. If you run many services and want a “chronic offender” bucket across them, recidive adds that, provided you write a /var/log/fail2ban.log file.

Why does my SSH jail not match anything on Ubuntu 24.04?

On Ubuntu 24.04 the jails use backend = systemd by default. In that mode, logpath is not valid and the jail reads events from the journal using journalmatch. If you copied an older jail that points to /var/log/auth.log, it will not work. Use a jail override that keeps the systemd backend and do not add logpath. Confirm the defaults with grep in /etc/fail2ban/jail.d/defaults-debian.conf.

How do I keep from banning myself?

Add your management IPs and office ranges to ignoreip in a jail.d override, and set ignoreself = true. Start with conservative values for bantime, findtime and maxretry while you tune. If you do get locked out, use the Virtualizor VNC console from the Hostworld client area to sign in and change your rules, or stop Fail2ban temporarily with systemctl stop fail2ban while you correct the allowlist.

Do bans survive a reboot and where is state kept?

Fail2ban writes ban rules into your firewall. On Ubuntu 24.04 that is nftables by default, or UFW if you selected that action. On AlmaLinux 9 that is firewalld rich rules or all‑ports blocks. Fail2ban also keeps a persistent database at /var/lib/fail2ban/fail2ban.sqlite3 that tracks prior bans. Features such as bantime.increment rely on that database.

Will automatic updates reboot my server without warning?

On Ubuntu 24.04, unattended upgrades install updates automatically and may restart services with needrestart. Automatic reboots are off by default, and you can opt in and set a time window in /etc/apt/apt.conf.d/50unattended-upgrades or an override file. On AlmaLinux 9, enabling dnf-automatic-install.timer installs updates on schedule. Plan maintenance windows and set options such as upgrade_type=security so behaviour matches your policy.

Was this guide helpful?