How to Install and Configure Fail2ban on an Ubuntu VPS?
Protecting your VPS from unauthorized access is a critical task. Fail2ban is a powerful tool that scans logs for suspicious activity, such as failed login attempts, and automatically blocks the IP addresses from which these attempts originate. In this article, we will take a detailed look at the process of installing and configuring Fail2ban on a VPS running Ubuntu to provide an additional layer of security for your server.
We’ll cover all the steps, from installing the Fail2ban package to configuring filters to protect against various types of attacks. You will learn how to define your own blocking rules and adapt Fail2ban to the specific needs of your server. This guide is intended for both novice and experienced Linux users looking to improve the security of their VPS.
Table of Contents
- Installing Fail2ban
- Basic Fail2ban Configuration
- Configuring Jail.local to Protect SSH
- Testing and Verifying Fail2ban
- Automatically Unbanning IP Addresses
Installing Fail2ban
The first step in protecting your VPS is to install Fail2ban. Ubuntu provides the Fail2ban package in its standard repositories, which greatly simplifies the installation process.
To start, update the package list to make sure you have the latest versions:sudo apt update
This command will update information about available packages from the repositories specified in your system.
sudo apt install fail2ban
This command will download and install Fail2ban and all necessary dependencies. During the installation, you may be prompted to confirm the package installation. Answer affirmatively by pressing «Y» and Enter.
After the installation is complete, Fail2ban will start automatically. You can check its status with the following command:
sudo systemctl status fail2ban
The output will show whether the Fail2ban service is active, its uptime, and recent logs. If the service is not running, you can start it manually:
sudo systemctl start fail2ban
And to make sure it starts automatically at system boot:
sudo systemctl enable fail2ban
Example 1: Updating and installing Fail2ban.
sudo apt update && sudo apt install fail2ban
This command combines updating the package list and installing Fail2ban into one line, which makes the process a little faster.
Example 2: Checking the Fail2ban version.
fail2ban-client --version
This command will output the version of the installed Fail2ban. This is useful for tracking security updates and compatibility with other applications.
Example 3: Viewing the Fail2ban log.
sudo tail -f /var/log/fail2ban.log
This command displays the latest lines of the Fail2ban log file in real time. This allows you to track which IP addresses are being blocked and why. The `-f` option means «follow», that is, the command will continue to display new lines as they are added to the file.
Basic Fail2ban Configuration
After successful installation, it is necessary to configure Fail2ban for effective protection of your server. Fail2ban configuration is managed through the `jail.conf` and `jail.local` files. It is important to understand that `jail.conf` is the default configuration file and it is not recommended to directly modify it, as package updates may overwrite your changes. Instead, you should use the `jail.local` file to override parameters from `jail.conf`. First, create a `jail.local` file based on `jail.conf`:sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Then open `jail.local` for editing:
sudo nano /etc/fail2ban/jail.local
In this file, you can change various parameters, such as the ban time, the number of attempts before banning, and the email address for notifications. Let’s look at some important parameters:
- `bantime`: Determines how many seconds the IP address will be blocked for. For example, `bantime = 600` means blocking for 10 minutes.
- `findtime`: Determines how long Fail2ban will track login attempts. For example, `findtime = 600` means that Fail2ban will consider login attempts made in the last 10 minutes.
- `maxretry`: Determines how many failed login attempts are allowed during `findtime` before the IP address is blocked. For example, `maxretry = 3` means that after three failed login attempts, the IP address will be blocked.
- `destemail`: Specify the email address to which lock notifications will be sent.
- `sendername`: The sender name in notification emails.
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
destemail = your_email@example.com
sendername = Fail2ban
Replace `your_email@example.com` with your actual email address.
After making changes, save the file and restart Fail2ban to apply the new settings:
sudo systemctl restart fail2ban
Example 1: Changing the ban time and number of attempts.
[DEFAULT]
bantime = 7200 ; Ban for 2 hours
maxretry = 4 ; 4 failed attempts
This example shows how to change the ban time to 2 hours and allow only 4 failed login attempts.
Example 2: Enabling email notifications.
[DEFAULT]
destemail = admin@example.com
sendername = Cómo Configurar Alertas de Nagios en tu Servidor Dedicado: Guía Paso a Paso" class="internal-post-link">Guía Paso a Paso" class="internal-post-link">Fail2ban VPS
mta = sendmail
action = %(action_mwl)s
This example enables sending notifications to `admin@example.com` with the sender name «Fail2ban VPS». `mta = sendmail` indicates that the sendmail (or compatible) mail server is used, and `action = %(action_mwl)s` defines the action that will be performed when blocking, including sending an email notification with information about the event. Make sure that a mail server (such as postfix or sendmail) is configured on your server to send notifications.
Example 3: Specifying another log file for monitoring (not recommended without special necessity).
[DEFAULT]
logfile = /var/log/my_custom_log.log
This example shows how to change the log file that Fail2ban will monitor. Attention: This should only be done if you know exactly what you are doing and if the standard log file does not contain the necessary information. Incorrectly specifying a log file can cause Fail2ban to malfunction.
Configuring Jail.local to Protect SSH
Fail2ban uses «jails» to define blocking rules for various services. Each jail is associated with a specific service (e.g., SSH, Apache, Nginx) and defines which logs to monitor, which patterns to look for, and what actions to take when suspicious activity is detected. By default, some jails are already defined in the `jail.conf` file, but they are often disabled. To activate and configure a jail to protect SSH, you need to make changes to the `jail.local` file. Open the `jail.local` file for editing:sudo nano /etc/fail2ban/jail.local
Find the `[sshd]` section (or add it if it is not there) and make the following changes:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = systemd
Let’s analyze each line:
- `enabled = true`: Enables the sshd jail.
- `port = ssh`: Specifies the port that Fail2ban will protect. In this case, this is the standard SSH port (22). If you are using a non-standard SSH port, replace `ssh` with your port number (for example, `port = 2222`).
- `logpath = %(sshd_log)s`: Specifies the path to the SSH log file. `%(sshd_log)s` is a variable defined in `jail.conf` that points to the standard SSH log file.
- `backend = systemd`: Specifies how Fail2ban will track changes to the log file. `systemd` is the init system used in Ubuntu. Other possible values: `polling`, `gamin`, `inotify`. `systemd` is usually the most efficient and reliable method.
sudo systemctl restart fail2ban
Now Fail2ban will monitor the SSH log file and block IP addresses from which failed login attempts originate.
Important: If you are using a non-standard SSH port, you must specify it in the sshd jail settings. Otherwise, Fail2ban will not monitor the correct port and will not be able to protect your server from attacks.
Example 1: Configuring Fail2ban to protect SSH on a non-standard port.
[sshd]
enabled = true
port = 2222
logpath = %(sshd_log)s
backend = systemd
In this example, Fail2ban will protect SSH on port 2222.
Example 2: Enabling protection against brute-force attacks on SSH using filters.
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = systemd
filter = sshd
In this example, the line `filter = sshd` is added. `filter` defines which filter will be used to analyze the log file. Filters are files containing regular expressions that Fail2ban uses to search for suspicious activity in logs. In this case, the `sshd` filter is used, which is already defined in Fail2ban and contains rules for detecting brute-force attacks on SSH. Using filters allows you to more accurately determine which login attempts are suspicious and avoid blocking legitimate users.
Example 3: Increasing the ban time for SSH.
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = systemd
bantime = 86400 ; Ban for 24 hours
In this example, the ban time for SSH is increased to 24 hours (86400 seconds). This can be useful for protecting against persistent attacks.
Testing and Verifying Fail2ban
After installing and configuring Fail2ban, you need to check its functionality to make sure it effectively protects your server. There are several ways to do this:- Checking the jail status: You can check the status of a specific jail using the `fail2ban-client` command.
- Analyzing the Fail2ban log: Viewing the Fail2ban log allows you to see which IP addresses have been blocked and why.
- Simulating an attack: You can simulate failed login attempts to check that Fail2ban correctly blocks the IP address.
sudo fail2ban-client status sshd
This command will output information about the `sshd` jail, including:
- Status (enabled or disabled)
- Number of banned IP addresses
- List of banned IP addresses
sudo tail -f /var/log/fail2ban.log
In the log, you will see records of all events related to Fail2ban, including starting and stopping the service, activating and deactivating jails, and blocking and unblocking IP addresses. Analyzing the log allows you to understand how Fail2ban works and identify possible problems.
To simulate an attack and check that Fail2ban correctly blocks the IP address, you can try to connect to your server via SSH several times with an incorrect password. After several failed attempts, your IP address should be blocked. You can check this using the `fail2ban-client status sshd` command or by viewing the Fail2ban log.
Important: Be careful when simulating an attack so as not to block yourself for a long time. You can reduce the ban time for testing and then return it to its normal value.
Example 1: Manually unbanning an IP address.
sudo fail2ban-client set sshd unbanip 192.168.1.100
This command unbans the IP address 192.168.1.100 in the `sshd` jail. This can be useful if you accidentally blocked your own IP address.
Example 2: Checking iptables rules created by Fail2ban.
sudo iptables -L FAIL2BAN-SSHD
This command shows the iptables rules created by Fail2ban for the `sshd` jail. Iptables is a Linux firewall that Fail2ban uses to block IP addresses. The command output will show a list of rules that block incoming traffic from blocked IP addresses. This allows you to make sure that Fail2ban correctly configures the firewall to block suspicious traffic.
Example 3: Reloading Fail2ban without restarting the entire system.
sudo fail2ban-client reload
This command reloads the Fail2ban configuration without restarting the entire service. This is faster than restarting and allows you to apply configuration changes without interrupting Fail2ban.
Automatically Unbanning IP Addresses
In some cases, it may be necessary to automatically unban IP addresses after a certain period of time. Fail2ban by default blocks IP addresses for the specified time (`bantime`), but sometimes it is necessary for the IP address to be unblocked automatically earlier, for example, if the block occurred by mistake or if the dynamic IP address has changed. To implement automatic unbanning, you can use several approaches:- Setting a short ban time: The easiest way is to set a small value for the `bantime` parameter. However, this can make your server more vulnerable to attacks, as an attacker can repeat login attempts after a short period of time.
- Using scripts for automatic unbanning: A more complex but also more flexible approach is to use scripts that automatically unban IP addresses after a certain period of time.
#!/bin/bash
# Time in seconds after which to unban IP addresses
UNBAN_TIME=3600
# Jails for which to perform automatic unbanning
JAILS="sshd"
for JAIL in $JAILS; do
fail2ban-client status $JAIL | grep "Banned IP list:" | awk '{print $4}' | tr -d '[]' | tr ',' '\n' | while read IP; do
BAN_TIME=$(fail2ban-client get $JAIL banip $IP | grep "Ban since" | awk '{print $3 " " $4 " " $5 " " $6 " " $7}')
BAN_TIMESTAMP=$(date -d "$BAN_TIME" +%s)
CURRENT_TIMESTAMP=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIMESTAMP - BAN_TIMESTAMP))
if [ "$ELAPSED_TIME" -gt "$UNBAN_TIME" ]; then
fail2ban-client set $JAIL unbanip $IP
echo "$(date) - Unbanned IP $IP in jail $JAIL" >> /var/log/fail2ban-auto-unban.log
fi
done
done
This script does the following:
- Defines the time in seconds after which to unban IP addresses (`UNBAN_TIME`).
- Defines a list of jails for which to perform automatic unbanning (`JAILS`).
- Goes through the list of blocked IP addresses for each jail.
- Determines the IP address ban time.
- If the ban time exceeds the specified value (`UNBAN_TIME`), it unbans the IP address.
- Writes information about the unbanning to a log file.
sudo chmod +x /usr/local/bin/fail2ban-auto-unban.sh
Then configure cron to automatically run the script, for example, every hour:
sudo crontab -e
Add the following line to the cron file:
0 * * * * /usr/local/bin/fail2ban-auto-unban.sh
This line indicates that the script should run at the beginning of each hour.
Important: This script is an example and may need to be adapted to your specific needs. For example, you may need to change the list of jails, the log file format, or add additional checks.
Example 1: Configuring automatic unbanning via cron using a short `bantime`.
[DEFAULT]
bantime = 300 ; Ban for 5 minutes
; Run the script every minute to unban
- * * * * /usr/local/bin/fail2ban-auto-unban.sh
This example shows how to set a short ban time (5 minutes) and configure cron to run the script every minute. The script will check blocked IP addresses and unblock them if they have been blocked for more than 5 minutes. This approach is easy to implement but may be less secure than using a longer ban time and a more complex script.
Example 2: Unbanning IP addresses only for specific jails.
JAILS="sshd apache"
In the `fail2ban-auto-unban.sh` script, change the `JAILS` variable to specify only those jails for which to perform automatic unbanning. In this example, automatic unbanning will only be performed for the `sshd` and `apache` jails.
Example 3: Logging script actions to a separate file.
echo "$(date) - Unbanned IP $IP in jail $JAIL" >> /var/log/fail2ban-auto-unban.log
This line in the `fail2ban-auto-unban.sh` script writes information about unbanning an IP address to the file `/var/log/fail2ban-auto-unban.log`. This allows you to track which IP addresses have been unbanned and when. Regularly review this log file to identify possible problems.