Skip links

Using Fail2ban to secure your server (SSH, OpenVPN and Recidive)

Fail2ban is an essential tool if you run a server that has ports open to the internet, whether the server is running in a cloud service (AWS, GCP, etc.) or a raspberry pi at home with router port forwarding, you probably noticed attempts to connect to your server from random IP addresses.

Most of the time, you should be safe if you are using strong authentication like SSH Keys instead of passwords or OVPN files for an Openvpn server. However, security should be approached as a multi layer defense system instead of relying on only a single layer.

That’s where Fail2ban comes in handy, it creates a firewall block list (called a jail) for IP addresses that attempt to connect multiple times using wrong credentials, it gets the information from the logs of whichever application you’re trying to protect, you can customize 3 main criteria for blocking an IP address:

  1. bantime : the period of time the IP address will be banned (default is in seconds)
  2. maxretry: the number of times an IP fails before it gets banned
  3. findtime: the period of time during which a maxretry number will cause a block (default is in seconds)

There are many options and customization you can do in the configuration file but for this use case we will configure only the following:

  1. Configure logging for Fail2ban
  2. Configure a jail for SSH
  3. Configure a jail for Openvpn server running on default port 1194 UDP
  4. Configure Recidive jail for repeat offenders

If you need to read more or want to configure a different use case, you can visit Fail2ban’s documentation here

This guide assumes you’re using Debian, Ubuntu or Raspberry Pi Os

Download and install

# Run the repository update
sudo apt update -y && sudo apt upgrade -y
# install Fail2ban
sudo apt install fail2ban
#navigate to the installation directory
cd /etc/fail2ban
#it's a good idea to leave the default config files in place, so copy these 2 files
sudo cp fail2ban.conf fail2ban.local && sudo cp jail.conf jail.local

Configure logging for Fail2ban

sudo nano fail2ban.local

Inside this file near the top you will find the key loglevel, you can select from different log levels, we recommend DEBUG

You can also change the name or path of the file where Fail2ban keeps its logs by changing the key logtarget, it is recommended to leave it as the default /var/log/fail2ban.log

Configure jails for Fail2ban

Jails rely on filter files which are placed in the directory /etc/fail2ban/filter.d/ , filter files use Regex in order to identify a failed login attempt in the applications log file, there are already multiple filters in the filter.d directory and multiple jails in the jail.conf file, these are all default configurations and can be enabled in the jail.conf file

Ubuntu enables the SSH jail section by default and its filter already exists in the filter.d directory – it’s called sshd.conf

We will create a new filter for Openvpn using the following command

sudo nano /etc/fail2ban/filter.d/openvpn.local

When nano opens, paste the following in the file then crtl+x to save and exit

This section was copied from Fail2ban’s website

# Fail2Ban filter for selected OpenVPN rejections
# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf
# Example messages (other matched messages not seen in the testing server's logs):
# Fri Sep 23 11:55:36 2016 TLS Error: incoming packet authentication failed from [AF_INET]
# Thu Aug 25 09:36:02 2016 TLS Error: TLS handshake failed
failregex = ^%(__prefix_line)sTLS Error: incoming packet authentication failed from \[AF_INET\]<HOST>:\d+$
            ^%(__prefix_line)s<HOST>:\d+ Connection reset, restarting
            ^%(__prefix_line)s<HOST>:\d+ TLS Auth Error
            ^%(__prefix_line)s<HOST>:\d+ TLS Error: TLS handshake failed$
            ^%(__prefix_line)s<HOST>:\d+ VERIFY ERROR
ignoreregex =

Next, we will configure our jail.local file which we created during the installation section

sudo nano /etc/fail2ban/jail.local

First we will configure the bantime, maxretry and findtime, we will use 1 hour ban and 1 hour findtime with maxretry 3 but you can choose your own numbers

bantime = 60m

findtime = 60m

maxretry = 3

Configure OpenVPN jail

We will need to add the following jail configuration to the end of the jail.local file

enabled  = true
port     = 1194
protocol = udp
filter   = openvpn
logpath  = /var/log/openvpn.log
maxretry = 3

Make sure to change the port and protocol to whichever port you’re using for VPN, also make sure the logpath points to the path of your openvpn log file

Configure recidive for repeat offenders

It’s very common you will have repeat offenders who would still try to connect whenever they get unbanned, the solution is to enable recidive which monitors your fail2ban logs for repeat offenders and sets up a jail for them for extended blocking

Find the section in the jail.local file that says [recidive] – you can search in nano using ctrl + w – replace it with the following

Don’t forget to configure your own bantime, findtime and maxretry

enabled = true
logpath  = /var/log/fail2ban.*
banaction = %(banaction_allports)s
bantime  = 365d
findtime = 30d
maxretry = 20

crtl+x to save the file, then reload fail2ban to ensure it picks up the new configuration

sudo systemctl reload fail2ban.service

Now we need to test if our jails are active, use the following command

sudo fail2ban-client status

You should receive a confirmation like the following:

|- Number of jail:      3
`- Jail list:   openvpn, sshd, recidive

Finally, we need to make sure fail2ban starts after a system reboot

sudo systemctl enable fail2ban