Using Fail2ban to Secure Your Server

Meet Fail2ban. This log-parsing application is designed to monitor system logs and recognize signs that indicate automated attacks on your VPS instance.

By the time you reach the last line of this tutorial, you’ll have a better understanding of how to use Fail2ban to keep your server secure.

When Fail2ban identifies and locates an attempted compromise using your chosen parameters, it will add a new rule to iptables to block the IP address from which the attack originates. This restriction will stay in effect for a specific length of time or on a long-term basis. You can also set your Fail2ban configuration to ensure you’re notified of attacks via email as they occur.

While Fail2ban is mainly designed to focus on SSH attacks, you can also experiment with Fail2ban configuration to suit any service that utilizes log files and is at potential risk of being compromised.

Fail2ban Installation – A Step-By-Step Walkthrough

Setup on CentOS 7

  1. Make sure that your system has been updated as required and start the EPEL repository installation:

  2. yum update && yum install epel-release

  3. Proceed with the Fail2Ban installation:

  4. yum install fail2ban

  5. If you want to receive email support, begin the Sendmail installation. But be aware: Sendmail is not mandatory if you wish to take advantage of Fail2Ban.:

  6. yum install sendmail

  7. Start and enable Fail2ban (as well as Sendmail, if you want to use that too):

  8. systemctl start fail2ban

  9. systemctl enable fail2ban

  10. systemctl start sendmail

  11. systemctl enable sendmail

Please be aware:

In case you’re confronted by this error: no directory /var/run/fail2ban to contain the socket file /var/run/fail2ban/fail2ban.sock, you’ll need to set up the directory through a manual process instead:

mkdir /var/run/fail2ban

Setup on Debian

  1. Confirm that your system is updated and ready:

  2. apt-get update && apt-get upgrade -y

  3. Proceed with Fail2ban installation:

  4. apt-get install fail2ban

Now, the service will start automatically.

  1. (Optional step) For email support, start the Sendmail installation:

  2. apt-get install sendmail-bin sendmail

Please be aware:

In its present iteration, Sendmail in Debian Jessie includes an upstream bug known to trigger a number of errors (see below) as a result of installing sendmail-bin. The installation will pause for a brief period before it reaches completion. Errors:

Creating /etc/mail/sendmail.cf...

ERROR: FEATURE() should be before MAILER() MAILER('local') must appear after FEATURE('always_add_domain')

ERROR: FEATURE() should be before MAILER() MAILER('local') must appear after FEATURE('allmasquerade')

Setup on Fedora

  1. Ensure that your system has been updated before you proceed, with:

  2. dnf update

  3. Start the Fail2ban installation:

  4. dnf install fail2ban

  5. (Optional step) You can proceed with the Sendmail installation step if you would prefer email support:

  6. dnf install sendmail

  7. Start and enable Fail2ban (along with Sendmail, as you see fit):

  8. systemctl start fail2ban

  9. systemctl enable fail2ban

  10. systemctl start sendmail

  11. systemctl enable sendmail

Setup on Ubuntu

  1. Check that your system has been updated:

  2. apt-get update && apt-get upgrade -y

  3. Continue with the Fail2ban installation:

  4. apt-get install fail2ban

You’ll see that the service will start automatically.

  1. (Optional step) Install Sendmail if you want email support:

  2. apt-get install sendmail

  3. Grant SSH access via UFW before you proceed with enabling the firewall:

  4. ufw allow ssh

  5. ufw enable

 

The Fail2ban Configuration Process

In this next part of this tutorial, you’ll find a number of examples exploring popular Fail2ban configurations utilizing fail2ban.local and jail.local files. Fail2ban will read.conf configuration files initially before .local files override any settings.

As a result, any configuration adjustments tend to be performed in .local files while the .conf files remain unaffected.

How to Configure fail2ban.local

  1. fail2ban.conf carries the default configuration profile, and these standard settings offer a decent working setup. However, if you would prefer to create any edits, you should do this in a separate file (fail2ban.local). This will override fail2ban.conf. Be sure to rename a copy fail2ban.conf to fail2ban.local.

  2. cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local

  3. From this point, you may choose to adjust the definitions located within fail2ban.local to align with the configuration you want to set up. You can change the following values:

    • loglevel: You can set the detail level provided by the Fail2ban logs to: 1 (error), 2 (warn), 3 (info), or 4 (debug).

    • logtarget: This will log actions in a defined file (the default value of /var/log/fail2ban.log adds all logging into it). On the other hand, you could edit the value to:

      • STDOUT: output any data

      • STDERR: output any errors

      • SYSLOG: message-based logging

      • FILE: output to a file

    • socket: The socket file’s location.

    • pidfile: The PID file’s location.

How to Configure the Fail2ban Backend

  1. By default, the jail.conf file enables Fail2ban for SSH for Debian and Ubuntu, though not for CentOS. Alternative protocols and configurations (such as FTP, HTTP, and so on) will be commented out. You can adjust this if you wish. You’ll need to make a jail.local for editing:

  2. cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

  3. Do you use Fedora or CentOS? You’ll have to switch the backend option in jail.local from auto  to systemd . Be aware, though, that this isn’t needed on Debian 8 or Ubuntu 16.04, despite both being capable of using systemd too.

File: /etc/fail2ban/jail.local

# "backend" specifies the backend used to get files modification.

# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".

# This option can be overridden in each jail as well.

. . .

backend = systemd

Please be aware:

When the backend configuration has been set to auto, Fail2ban will monitor log files by utilizing pyinotify first. After this, Fail2ban will attempt gamin. However, if neither is available, a polling algorithm will choose the next attempt.

By default, there are no jails enabled in CentOS 7. For instance, if you wish to proceed with enabling the SSH daemon jail, you should uncomment these lines in jail.local:

File: /etc/fail2ban/jail.local

[sshd]

enabled = true

How to Configure Fail2ban jail.local

Want to familiarize yourself with the settings available in Fail2ban? Start by opening your jail.local file and locate the configurations available:

File: /etc/fail2ban/jail.local

[DEFAULT]

ignoreip = 127.0.0.1/8

bantime = 600

findtime = 600

maxretry = 3

backend = auto

usedns = warn

destemail = [email protected]

sendername = Fail2Ban

banaction = iptables-multiport

mta = sendmail

protocol = tcp

chain = INPUT

action_ = %(banaction)...

action_mw = %(banaction)...

protocol="%(protocol)s"...

action_mwl = %(banaction)s...

Let’s consider an example. If you were to switch the usedns setting to no, Fail2ban will not utilize reverse DNS to implement its bans. It will ban the IP address instead. When you set it as warn, Fail2ban will undertake a reverse lookup to find the hostname and utilize that to initiate a ban.

What does the chain setting relate to? The range of iptables rules where jumps can be added in ban-actions. This has been set to the INPUT chain by default. If you want to learn more about iptables chains, feel free to check out our comprehensive What is iptables resource.

How to Configure Fail2ban Chain Traffic Drop

If you want to look at your Fail2ban rules, use the iptables’ –line-numbers option.

iptables -L f2b-sshd -v -n --line-numbers

You should see an output that’s similar:

Chain fail2ban-SSH (1 references)

num pkts bytes target prot opt in out source destination

1 19 2332 DROP all -- * * 192.0.0.0 0.0.0.0/0

2 16 1704 DROP all -- * * 192.0.0.1 0.0.0.0/0

3 15 980 DROP all -- * * 192.0.0.2 0.0.0.0/0

4 6 360 DROP all -- * * 192.0.0.3 0.0.0.0/0

5 8504 581K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0

If you would like to, you may utilize the iptables -D chain rulenum command to remove a rule that has been applied to a specific IP address. Swap rulenum with the corresponding IP address rule number found in the num column. For instance, you can remove the IP address 192.0.0.1 by issuing this command:

iptables -D fail2ban-SSH 2

How to Configure Ban Time and Retry Amount Fail2Ban

Set bantime, findtime, and maxretry to configure a ban’s circumstances and the amount of time it lasts:

File: /etc/fail2ban/jail.local

# “bantime” is the number of seconds that a host is banned.

bantime = 600

# A host is banned if it has generated "maxretry" during the last "findtime"

# seconds.

findtime = 600

maxretry = 3

  • findtime: This relates to how much time will pass between login attempts before a ban is implemented. As an example, let’s say Fail2ban is set to ban an IP following four (4) failed log-in attempts. These four attempts must take place during the predefined findtime limit of 10 minutes, and the findtime value should be a set number of seconds.

  • maxretry: To determine if a certain ban will be justified, Fail2ban uses findtime and maxretry. Should the amount of attempts be higher than the limit set at maxretry and fall within the findtime time limit, Fail2ban will set a band. The default is set at 3.

  • bantime: This applies to the duration of time (in seconds) an IP will be banned for, and this will be permanent if set to a negative number. The default value is 600, which will ban an IP for a period lasting 10 minutes.

How to Configure ignoreip for Fail2ban

You can add specific IPs you wish to ignore by adding them to the ignoreip line. This won’t ban the localhost by default. Adding the ignore list may be to your benefit if you tend to frequently leverage an individual IP address:

File: /etc/fail2ban/jail.local

[DEFAULT]

# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not

# ban a host which matches an address in this list. Several addresses can be

# defined using space separator.

ignoreip = 127.0.0.1/8 123.45.67.89

ignoreip: With this setting, you can define which IP addresses are to be excluded from Fail2ban rules. You should add specific IPs you want to ignore to the ignoreip configuration (as per the example). This command doesn’t band the localhost by default. If you regularly work from a single IP address, you may want to add it to the ignore list.

Want to whitelist IPs only for specific jails? Utilize the fail2ban-client command. Just switch JAIL with your jail’s name, and 192.0.0.1 with the IP you intend to be whitelisted.

fail2ban-client set JAIL addignoreip 192.0.0.1

How to Set up Fail2ban Email Alerts

You may want to get email alerts whenever something triggers Fail2ban. You can do this by changing the email settings:

  • destemail: The address at which you want to get your emails.

  • sendername: The name attributed to the email.

  • sender: The address which Fail2ban sends emails from.

Pleas e be aware:

Run the command sendmail -t [email protected], switching [email protected] with your email address if you’re not what to put under sender. Look at your email, along with spam folders if required, and check the sender email. You can use that address for the configuration above.

You’re also required to edit the action setting. This defines the actions undertaken if the band threshold is met. The default, %(action_)s, will only ban the user. %(action_mw)s will ban and distribute an email including a WhoIs report. With %(action_mwl)s, a ban is implemented and an email with the WhoIs report (and any relevant lines in the log file) will be sent. You can also adjust this on a jail-specific basis.

How to Configure Fail2ban banaction and ports

Outside of the above basic settings address, jail.local also has numerous jail configurations for multiple common services (such as iptables and SSH). Just SSH is enabled by default, and the action is to ban the problematic host/IP address through modification of the iptables firewall rules.

Expect the standard jail configuration to look like this:

File: /etc/fail2ban/jail.local

# Default banning action (e.g. iptables, iptables-new,

# iptables-multiport, shorewall, etc) It is used to define

# action_* variables. Can be overridden globally or per

# section within jail.local file

banaction = iptables-multiport

banaction_allports = iptables-allports

[ssh]

enabled = true

port = ssh

filter = sshd

logpath = /var/log/auth.log

maxretry = 6

  • banaction: This defines the action that should be taken if the threshold is met. When you configure the firewall to use firewalld, set the value to firewallcmd-ipset. If you configure the firewall to use UFW, then the value should be set to ufw.

  • banaction_allports: This will block a remote IP in each port. If you configure the firewall to use firewalld, the value should be set to firewallcmd-ipset.

  • enabled: Determine if the filter should be activated or not.

  • port: This is the port that Fail2ban should reference in regards to the service. If you utilize the default port, you can put the service name here. But if you opt for a port that’s not traditional, this must be the port number instead. E.g. if you changed your SSH port to 3775, you would replace ssh with that number.

  • filter: This is the name of the file found in /etc/fail2ban/filter.d containing the failregex information used for parsing log files correctly. You don’t need to include the .conf suffix.

  • logpath: Provides the service’s logs location.

  • maxretry: This overrides the global maxretry for the service you define. You may also add findtime and bantime.

  • action: You may add this as an extra setting when the default action is inappropriate for the jail. You can find other in the action.d folder.

Please be aware:

You may choose to configure jails as individual .conf files withing the jail.d directory. But the format will stay the same.

Securing Servers with Fail2ban Filters

Now, we’ll explore your system’s Fail2ban filters defined within their respective configuration files.

You will see your system’s filters in the /etc/fail2ban/jail.conf file or the /etc/fail2ban/jail.d/defaults-*.conf file, depending on your version of Fail2ban.

Look up your /etc/fail2ban/jail.conf file and check out the ssh/sshd filter:

File: /etc/fail2ban/jail.conf

[ssh]

enabled = true

port = ssh

filter = sshd

logpath = /var/log/auth.log

maxretry = 5

When you use a version of Fail2ban higher than 0.8, examine your defaults-*.conf and jail.conf files.

If you have version 0.8 of Fail2ban or higher, your jail.conf file will look like this:

File: /etc/fail2ban/jail.conf

[sshd]

port = ssh

logpath = %(sshd_log)s

Next, if your system uses Fail2ban 0.8 or beyond, it will have a defaults-*.conf including these filters:

File: /etc/fail2ban/jail.d/defaults-*.conf

[sshd]

enabled = true

maxretry = 3

If you want to try testing current filters, run the example command and switch logfile, failregex, and ignoreregex with your preferred values.

fail2ban-regex logfile failregex ignoreregex

If we use those examples from this section’s start, the command will look like this:

fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

Your Fail2ban filters will need to work with:

  1. Different logs types created by varied software

  2. Varied configurations and a number of operating systems

Alongside the above, your filters should be log-format agnostic too. They should also be protected against DDoS attacks, and must be compatible with other versions of the software to be released in the future.

How to Customize ignoreregex Configurations

Before you can make adjustments to the failregex configuration, customization of ignoreregex is required. Fail2ban needs to understand what server activity is regarded as normal, and what isn’t.

For instance: you may exclude activity cron from running on your server or MySQL if you set up ignoreregex to filter logs created by those programs:

File: /etc/fail2ban/filter.d/sshd.conf

ignoreregex = : pam_unix\((cron|sshd):session\): session (open|clos)ed for user (daemon|munin|mysql|root)( by \(uid=0\))?$

: Successful su for (mysql) by root$

New session \d+ of user (mysql)\.$

Removed session \d+\.$

You’re free to tweak failregexs to block whatever you like now that you’ve filtered for each program’s logs.

How to Customize Failregexs

Fail2ban includes numerous filters, but you might prefer to customize them further or make your own based on your personal needs. Fail2ban utilizes regular expressions (regex) for log files parsing, searching for password failures and attempted break-ins. Python’s regex extensions are used by Fail2ban.

What’s the most effective way to learn how failregex functions? Write one yourself. While we don’t recommend letting Fail2ban monitor your WordPress’s access.log on websites with heavy traffic because of CPU concerns, it does give an instance of an easily-understood log file that you can utilize to learn about any failregex creation.

Writing a Fail2ban Regex

  1. Go to your website’s access.log (usually found at /var/www/example.com/logs/access.log) and locate a failed login attempt. This will look like:

File: /var/www/example.com/logs/access.log

123.45.67.89 - - [01/Oct/2015:12:46:34 -0400] "POST /wp-login.php HTTP/1.1" 200 1906 "http://example.com/wp-login.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:40.0) Gecko/20100101 Firefox/40.0"

You just need to track up to the 200:

File: /var/www/example.com/logs/access.log

123.45.67.89 - - [01/Oct/2015:12:46:34 -0400] "POST /wp-login.php HTTP/1.1" 200

  1. The IP address that the unsuccessful attempt came from will always be defined as . The few characters after never change and you can enter them as literals:

  2. - - \[

The \ before the [ indicates that you should read the square bracket literally.

  1. You can use regex expressions to write the subsequent section (the date on which the login attempt occurred) as grouped expressions. So, as per this example, the first portion (here, 01) may be written as (\d{2}): The parentheses form the expression group and \d searches for numerical digits. However, {2} notes that the expression is searching for a pair of digits in a row (e.g. the date, as in 24, 25, etc.).

By this point, you will have:

- - \[(\d{2})

The following forward slash is called using a literal forward slash. This is followed by \w{3}: this is looking for a series of three alpha-numeric characters (such as A-Z, 0-5, in any case). The next forward slash will also be literal:

- - \[(\d{2})/\w{3}/

The year section will be written in a similar way to the day but you don’t require a capture group, and for four characters in a row along with a literal colon:

- - \[(\d{2})/\w{3}/\d{4}:

  1. The subsequent sequence consists of a run of two-digit numbers that represent the time. As we defined the day of the month as a two-digit number in a capture group (in the parentheses), we’re able to backreference it with \1. This is because it’s the first capture group. The colons will be literals again:

  2. - - \[(\d{2})/\w{3}/\d{4}:\1:\1:\1

If you prefer not to utilize backreferences, you can also write this as:

- - \[\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}

  1. Write the -0400 segment in a similar way to the year, including the extra literal -: -\d{4}. You should close the square bracket (escaping with a backslash first) and end the rest with the literal string:

  2. - - \[(\d{2})/\w{3}/\d{4}:\1:\1:\1 -\d{4}\] "POST /wp-login.php HTTP/1.1" 200

Alternatively:

- - \[\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2} -\d{4}\] "POST /wp-login.php HTTP/1.1" 200

How to Apply the Failregex

Now that the failregex has been set up, it should be added to a filter:

  1. Go to Fail2ban’s filter.d directory:

  2. cd /etc/fail2ban/filter.d

  3. Make a file named wordpress.conf then add your failregex:

File: /etc/fail2ban/filter.d/wordpress.conf

# Fail2Ban filter for WordPress

[Definition]

failregex = - - \[(\d{2})/\w{3}/\d{4}:\1:\1:\1 -\d{4}\] "POST /wp-login.php HTTP/1.1" 200

ignoreregex =

Save and quit.

  1. Add a WordPress section to jail.local:

File: /etc/fail2ban/jail.local

[wordpress]

enabled = true

filter = wordpress

logpath = /var/www/html/andromeda/logs/access.log

port = 80,443

This utilizes the default ban and email action, though you may define additional actions if you add an action = line.

Save and exit. Restart Fail2ban.

How to Use the Fail2ban Client

Fail2ban gives you a command fail2ban-client, and you can utilize this for running Fail2ban from the command line:

fail2ban-client COMMAND

  • start: For starting the Fail2ban server and jails.

  • reload: To reload the Fail2ban configuration files.

  • reload JAIL: For switching JAIL with a Fail2ban jail’s name; this causes the jail to reload.

  • stop: To terminate the server.

  • status: For displaying the server status and enabling jails.

  • status JAIL: For displaying the jail status, including IPs that are banned currently.

If you wanted to check that the Fail2Ban is operating and the SSHd jail has been enabled, for example, you would run:

fail2ban-client status

The output would be:

Status

Number of jail: 1

Jail list: sshd

You can find more on fail2ban-client commands in the Fail2ban wiki.

Understanding Lockout Recovery

Imagine that you lock yourself out of your vps instance because of Fail2ban. But don’t worry: you’ll still be able to get entry via console access.

From here, you’re able to check your firewall rules to make sure Fail2ban blocked your IP, rather than something else. You can do this by inputting:

iptables -n -L

Search for your IP address within the source column of any Fail2ban chains (which are prefixed by fail2ban or fail2ban) to verify whether the Fail2ban service blocked you:

Chain f2b-sshd (1 references)

target prot opt source destination

REJECT all -- 203.0.113.0 0.0.0.0/0 reject-with icmp-e

If you want to take your IP address from a jail, you can enter the following command (but switch 203.0.113.0 and jailname with the IP address and jail name you intend to unban:

fail2ban-client set jailname unbanip 203.0.113.0

Please be aware:

If you’re unable to recall the name of your jail, you can list all jails with the following:

fail2ban-client status

You may input the following if you decide that you want to stop utilizing your Fail2ban service at any point:

fail2ban-client stop

However, with CentOS 7 and Fedora, two additional commands are required for fully stopping and disabling:

systemctl stop fail2ban

systemctl disable fail2ban

How Plesk and Fail2ban Work Together

In this section, we’ll look at how Plesk and Fail2ban work together.

Fail2Ban is enabled by default in Plesk Obsidian: every jail available will be turned on and Fail2Ban’s default settings will be utilized.

You can safeguard your server from brute force attacks through IP address banning ( Fail2Ban ). Fail2Ban utilizes regular expressions for monitoring log files and spotting patterns that may correspond to authentication failures, looking for exploits, and additional entries that may appear to be suspicious.

Log entries of these types are counted, and when their number reaches a predefined value, Fail2Ban will issue a notification email or ban the offending IP for a set period. But the IP address will be automatically unbanned when the ban period ends.

A number of jails determine Fail2Ban logic. A jail is a rule set related to a specific scenario. The jail settings define what will be done when an attack has been detected according to a preset filter (a set of one or more regular expressions for log monitoring).

You can adjust Fail2Ban settings like so:

  1. Navigate to Tools & Settings > IP Address Banning (Fail2Ban) (under “Security”).

  2. Make your way to the “Settings” tab, where you can tweak:

    • IP address ban period – the time interval that an IP address is banned for (in seconds). The IP address is automatically unbanned once this period has ended.

    • Time interval for detection of subsequent attacks – the time interval during which the system will count the amount of failed sign-in attempts and additional undesirable behaviors from an IP address (in seconds).

    • Number of failures before the IP address is banned – the amount of unsuccessful login attempts connected to the IP address.

  3. Click on OK .

You’ll see these limitations and peculiarities in Fail2Ban in Plesk:

  • Fail2Ban defends against attacks with IPv4 and IPv6 addresses.

  • Fail2Ban depends entirely on IPs (without hostname lookups) unless it’s reconfigured.

  • Fail2Ban is unable to safeguard against distributed brute force attacks, as it recognizes intruders through their IP address.

  • The VPS iptables records limit (numiptent) could have an impact on Fail2ban’s work if your Plesk is installed on a VPS. Fail2Ban will cease operating as it should once this limited is exceeded, and you’ll find a line like this in the Fail2ban log: fail2ban.actions.action: ERROR iptables -I fail2ban-plesk-proftpd 1 -s 12.34.56.78 -j REJECT --reject-with icmp-port-unreachable returned 100 In this situation, you should get in touch with your VPS hosting provider for a resolution.

If you don’t want to block an IP address:

  1. Navigate to Tools & Settings > IP Address Banning (Fail2 b an) > Trusted IP Addresses > Add Trusted IP .

  2. Next, enter an IP address n the IP address field, along with an IP range or a DNS host name before clicking OK .

You can look at (and download) Fail2ban log files by going to Tools & Settings > IP Address Banning (Fail2 b an) > the Logs tab.

You’re free to look at the banned IP addresses, unban them, or add them to your trusted address list in Tools & Settings > IP Address Banning (Fail2 b an) > the Banned IP Addresses tab.

You may check out your list of IP addresses you never want to be banned, add/remove IP addresses to/from this list in Tools & Settings > IP Address Banning (Fail2 b an) > the Trusted IP Addresses tab.

Thank you for reading this comprehensive Fail2ban configuration tutorial. Now, you should have all the insights you need to take advantage of Fail2ban to fully secure your server.

No comment yet, add your voice below!

Add a Comment

Your email address will not be published. Required fields are marked *

We are Plesk

Value simplicity and automation too? We help devs, sysadmins, and resellers run, manage and secure via our control panel solutions, extensions and hyperscale opportunites. Discover how you fit with us.

GET LATEST NEWS AND TIPS

  • Yes, please, I agree to receiving my personal Plesk Newsletter! Plesk International GmbH and its affiliates may store and process the data I provide for the purpose of delivering the newsletter according to the Plesk Privacy Policy. In order to tailor its offerings to me, Plesk may further use additional information like usage and behavior data (Profiling). I can unsubscribe from the newsletter at any time by sending an email to [email protected] or use the unsubscribe link in any of the newsletters.

Related Posts

Knowledge base

Search
Generic filters
Exact matches only
Search in title
Search in content
Search in excerpt