Securing Your Linux Server with Fail2ban
Guide to installing and configuring Fail2ban to protect your server from unauthorized access and brute force attacks.
Fail2Ban is a security tool that helps protect your server from unauthorized access attempts and brute force attacks by monitoring logs for suspicious activities and blocking the IP addresses of attackers.
This will allow your server to harden itself against these access attempts without intervention from you.
In this guide, I’ll walk you through installing and configuring Fail2Ban.
I assume you're working on a properly set-up Ubuntu server. If not, check out my guide on preparing Ubuntu servers to get started.
Author's Note
Before we dive into the technical details, I want to highlight a few important considerations regarding Fail2ban.
Firstly, it's crucial to understand that Fail2ban should not be your sole security measure. Some may mistakenly believe it can replace firewall rules, but that is not the case.
Additionally, disabling password authentication and relying solely on SSH key authentication may lessen the need for Fail2ban.
However, I still advocate for its use as an additional layer of security.
Installation
Fail2ban is available in Ubuntu’s repositories.
To install it, use this command:
sudo apt install fail2banI noticed that Fail2ban disables its service upon installation on Ubuntu 22.04 due to some default settings that may cause unexpected behavior. In contrast, it is activated by default on Ubuntu 24.04.
You can verify this by using the following command:
sudo systemctl status fail2banThat's it for the installation.
Pre-Configuration
Fail2ban's configuration files are located in the /etc/fail2ban/ directory.
If you list the contents of this directory, you will find two important configuration files: fail2ban.conf and jail.conf.
The fail2ban.conf file contains Fail2Ban's global settings, which I don't recommend modifying.
The jail.conf file contains jails, filters with actions.
We shouldn't directly modify these files, as an update may override our changes.
That's why Fail2Ban recommends creating two local copies of these configuration files for us to modify.
Use the following commands to create a local copy of these two files:
sudo cp jail.conf jail.local
sudo cp fail2ban.conf fail2ban.localNow you can safely modify Fail2Ban's configuration.
Configuration
Open the jail.local file with your preferred editor and examine its settings.
Under the [DEFAULT] section, you will find settings that apply to all services protected by Fail2Ban.
Elsewhere in the file, there are sections like the [sshd] section, which contains service-specific settings (or individual jails) that will override the defaults.
Under the [DEFAULT] section, there are some variables that you may want to modify.
bantimeThe bantime variable sets the duration for which an IP will be blocked from accessing the server after failing to authenticate correctly.
By default, this is set to 10 minutes.
You can change its value as you prefer, for instance, to 60m for one hour.
findtime
maxretryThe findtime and maxretry variables function together to determine the conditions under which an IP should be blocked from accessing the server.
The maxretry variable defines the number of authentication attempts an IP is allowed to make within a time period defined by findtime before being blocked.
With the default settings, Fail2Ban will block an IP that unsuccessfully attempts to access the server more than 5 times within a 10-minute interval.
#ignoreip = 127.0.0.1/8 ::1The ignoreip variable contains a list of IP addresses, CIDR masks, or DNS hosts that Fail2ban won't block.
By default, this variable is commented out.
I strongly advise uncommenting this line and appending your own IP address to the list. This ensures that you won't inadvertently block yourself from accessing the server.
Email Alerts
Receiving email alerts is a practice I consistently advocate for in all of my guides.
If you want to receive email alerts whenever Fail2ban blocks an IP, you should adjust these two variables inside the jail.local file:
destemail
senderThe destemail variable defines the email address to which the alerts should be sent.
The sender variable defines the email address from which the alerts will be sent.
But there is something to pay attention to.
The sender variable should look like this:
sender = root@example.comDon't use your hostname. This won't work:
sender = root@host.example.comLastly, there is the mta variable, which specifies the mail agent that will be used to send the emails.
By default, Fail2ban uses Sendmail as its mail agent.
If you prefer to use Postfix, you can do so without changing the mta variable, as Fail2ban will automatically use it if it is installed.
Now, there is one more step to take in order to receive alerts. Keep reading.
Default Action
If you scroll down a bit inside the jail.local file, you'll see the action variable:
action = %(action_)sThis variable dictates the action Fail2ban should take when blocking an IP address.
The default action is to add a firewall rule that rejects traffic from the IP address, removing it after the specified bantime elapses.
Aha, the default action doesn't send alerts, which is why I asked you to keep reading.
Above the action variable, you'll find various actions you can switch between.
For example, action_mw sends an email when taking action, action_mwl sends an email and includes logging, and action_cf_mwl does all of the above, plus sends an update to the Cloudflare API associated with your account to ban the attacker there as well.
I always prefer using the action_mwl action.
If you want to use it too, your action variable should be set as follows:
action = %(action_mwl)sNow, whenever Fail2ban blocks an IP address, you'll receive an email alert, and Fail2ban logs the block.
Don’t miss out on exclusive guides, tutorials, and updates – delivered right to your inbox!
Individual Jails
Now, it is time to examine the service-specific sections, also known as individual jails, such as the [sshd] jail, which protects our server from unauthorized access attempts.
Each of these jails needs to be individually enabled by adding an enabled = true line under the header, along with their other settings.
By default, only the [sshd] jail is enabled, and all others are disabled.
You can verify this by opening the /etc/fail2ban/jail.d/defaults-debian.conf file, which contains the line enabled = true for the [sshd] jail.
Scroll down the jail.conf file until you find the [sshd] jail, which should look similar to this:
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)sIf you've changed the SSH port, ensure to update the value of the port variable accordingly.
You can include variables defined in the [DEFAULT] section, such as the bantime, maxretry, and findtime variables, which will only apply to this jail.
If you scroll down further, you'll find other jails that are disabled, such as the [nginx-http-auth] or [apache-auth] jails.
If you're running NGINX and want to protect a page of your site using a password, you could enable the [nginx-http-auth] jail to secure that page from unauthorized access attempts.
Starting Fail2ban
Since the [sshd] jail, which protects SSH, is enabled, we can proceed to start and enable the fail2ban service if it is disabled, depending on the version of Ubuntu you are using.
Use the following commands to start and enable Fail2ban:
sudo systemctl start fail2ban
sudo systemctl enable fail2banYou can use the fail2ban-client command to check the active jails:
sudo fail2ban-client statusOutput:
Status
|- Number of jail: 1
`- Jail list: sshdTo view the status and information regarding a specific jail like the sshd jail, you can use the following command:
sudo fail2ban-client status sshdOutput:
Status for the jail: sshd
|- Filter
| |- Currently failed: 5
| |- Total failed: 21
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 1
|- Total banned: 2
`- Banned IP list: 218.92.0.29Conclusion and Final Thoughts
Great job reaching the end!
There are many more things you can do with Fail2Ban, but for now, protecting SSH is the most important.
If you found value in this guide or have any questions or feedback, please don't hesitate to share your thoughts in the discussion section.
Your input is greatly appreciated, and you can also contact me directly if you prefer.
Discussion