The Brute Force Problem
If you provision a brand new Ubuntu server on AWS or DigitalOcean and expose port 22 (SSH) to the internet, it will be discovered by automated botnets within five minutes. These bots will begin executing a brute-force attack, attempting thousands of common usernames and passwords per second in an effort to breach the server. Even if you use secure cryptographic keys and disable password authentication, the sheer volume of these connection attempts can overwhelm the SSH daemon and consume massive amounts of CPU and network bandwidth, effectively creating a Denial of Service (DoS) attack.
Standard firewalls like UFW (Uncomplicated Firewall) are static. You can manually block an IP address (sudo ufw deny from 1.2.3.4), but you cannot manually block the 5,000 different IP addresses attacking you every hour.
To solve this, Linux engineers deploy fail2ban. Fail2ban is an automated intrusion prevention system. It continuously scans your system log files (like /var/log/auth.log) looking for patterns of failure, such as 5 failed SSH logins from the same IP address within 10 minutes. When a threshold is crossed, fail2ban dynamically reaches into UFW and injects a temporary block rule, instantly severing the attacker’s connection. After a predetermined time (e.g., 24 hours), it automatically removes the block, keeping your firewall clean.
Step 1: Installing and Preparing fail2ban
The fail2ban package is available in the standard Ubuntu repositories:
sudo apt update
sudo apt install fail2ban -y
Once installed, do not immediately edit the primary configuration file (/etc/fail2ban/jail.conf). Future package updates will blindly overwrite this file, destroying your custom configurations. Instead, you must create a local copy that fail2ban will prioritize.
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
You will perform all of your configuration edits in the jail.local file.
Step 2: Configuring the Global Defaults
Open the local configuration file:
sudo nano /etc/fail2ban/jail.local
Scroll down to the [DEFAULT] block. These settings apply globally to every single “jail” (monitoring rule) you activate.
ignoreip: You must add your own personal IP address, your VPN IP, and the IP addresses of your internal management servers here (separated by spaces). If you accidentally type your password wrong 5 times, you do not wantfail2banto lock you out of your own server.bantime: How long the attacker remains blocked. The default is 10m (10 minutes). For a production server facing the internet, change this to24h(24 hours) or-1(permanent ban).findtimeandmaxretry: The threshold. The default is 5 failures (maxretry = 5) within a 10-minute window (findtime = 10m). This is a safe baseline.banaction: This is critical. Ensure this is set toufwsofail2banknows to inject the rules into the Ubuntu firewall, rather than using rawiptableswhich can conflict with UFW.
Step 3: Enabling the SSH Jail
Scroll further down in the jail.local file until you find the [sshd] block. This is the specific jail that monitors the SSH daemon.
By default, the jail exists in the file but is turned off. You must explicitly activate it by adding enabled = true beneath the header.
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
Save the file and restart the fail2ban service to compile and load the new jail into memory:
sudo systemctl restart fail2ban
The moment you restart the service, fail2ban begins silently monitoring /var/log/auth.log.
Step 4: Monitoring and Managing the Jails
To verify that fail2ban is active and see a list of running jails, use the client command:
sudo fail2ban-client status
It should output: Jail list: sshd.
To view detailed forensics on exactly who is currently banned in the SSH jail:
sudo fail2ban-client status sshd
The output will display the total number of failed attempts since the service started, and a comma-separated list of the exact IP addresses that are currently actively blocked by UFW.
If you query UFW directly (sudo ufw status), you will not see these IP addresses listed in the standard output. fail2ban manages them dynamically in a hidden chain to prevent cluttering your primary UFW ruleset.
Step 5: Unbanning an IP Address
If an authorized user forgets their password, triggers the ban threshold, and calls the helpdesk because they cannot connect to the server, you must manually intervene.
You cannot use ufw allow to fix this. You must use the fail2ban-client to explicitly command the SSH jail to release the IP address from the UFW blocklist.
sudo fail2ban-client set sshd unbanip 192.168.1.150
The output will confirm the IP was unbanned, and the user will instantly regain the ability to attempt an SSH connection.
Conclusion
Exposing a static firewall to the internet guarantees CPU exhaustion from automated brute-force botnets. By integrating fail2ban with UFW, Ubuntu administrators deploy an autonomous, self-healing security perimeter that mathematically analyzes log files in real-time, instantly neutralizing aggressive attackers without requiring human intervention.