Fail2ban
To Unban ---> fail2ban-client set JAIL_NAME unbanip
Installing fail2ban
Installing fail2ban is simple on all the distributions we used to research this article. On Ubuntu 20.04, the command is as follows:
sudo apt-get install fail2ban
On Fedora 32, type:
sudo dnf install fail2ban
On Manjaro 20.0.1, we used pacman:
sudo pacman -Sy fail2ban
Configuring fail2ban
The fail2ban installation contains a default configuration file called jail.conf. This file is overwritten when fail2ban is upgraded, so we’ll lose our changes if we make customizations to this file.
Instead, we’ll copy the jail.conf file to one called jail.local. By putting our configuration changes in jail.local, they’ll persist across upgrades. Both files are automatically read by fail2ban.
This is how to copy the file:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Now open the file in your favorite editor. We’re going to use gedit:
We’ll look for two sections in the file: [DEFAULT] and [sshd]. Take care to find the actual sections, though. Those labels also appear near the top in a section that describes them, but that’s not what we want.
sudo gedit /etc/fail2ban/jail.local
You’ll find the [DEFAULT] section somewhere around line 40. It’s a long section with a lot of comments and explanations.
Scroll down to around line 90, and you’ll find the following four settings you need to know about:
ignoreip: A whitelist of IP addresses that will never be banned. They have a permanent Get Out of Jail Free card. The localhost IP address (127.0.0.1) is in the list by default, along with its IPv6 equivalent (::1). If there are other IP addresses you know should never be banned, add them to this list and leave a space between each one.
bantime: The duration for which an IP address is banned (the “m” stands for minutes). If you type a value without an “m” or “h” (for hours) it will be treated as seconds. A value of -1 will permanently ban an IP address. Be very careful not to permanently lock yourself out.
findtime: The amount of time within which too many failed connection attempts will result in an IP address being banned.
maxretry: The value for “too many failed attempts.”
If a connection from the same IP address makes maxretry failed connection attempts within the findtime period, they’re banned for the duration of the bantime. The only exceptions are the IP addresses in the ignoreip list.
fail2ban puts the IP addresses in jail for a set period of time. fail2ban supports many different jails, and each one represents holds the settings apply to a single connection type. This allows you to have different settings for various connection types. Or you can have fail2ban monitor only a chosen set of connection types.
You might have guessed it from the [DEFAULT] section name, but the settings we’ve looked at are the defaults. Now, let’s look at the settings for the SSH jail.
RELATED: How to Edit Text Files Graphically on Linux With gedit
Configuring a Jail
Jails let you move connection types in and out of fail2ban's monitoring. If the default settings don’t match those you want applied to the jail, you can set specific values for bantime, findtime, and maxretry.
Scroll down to about line 280, and you’ll see the [sshd] section.
This is where you can set values for the SSH connection jail. To include this jail in the monitoring and banning, we have to type the following line:
We also type this line:
The default setting was five, but we want to be more cautious with SSH connections. We dropped it to three, and then saved and closed the file.
We added this jail to fail2ban's monitoring, and overrode one of the default settings. A jail can use a combination of default and jail-specific settings.
Enabling fail2ban
So far, we’ve installed fail2ban and configured it. Now, we have to enable it to run as an auto-start service. Then, we need to test it to make sure it works as expected.
To enable fail2ban as a service, we use the systemctl command:
We also use it to start the service:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
enabled = true
maxretry = 3
We can check the status of the service using systemctl, too:
sudo systemctl status fail2ban.service
Everything looks good—we’ve got the green light, so all is well.
Let’s see if fail2ban agrees:
sudo fail2ban-client status
This reflects what we set up. We’ve enabled a single jail, named [sshd]. If we include the name of the jail with our previous command, we can take a deeper look at it:
sudo fail2ban-client status sshd
This lists the number of failures and banned IP addresses. Of course, all the statistics are zero at the moment.
Testing Our Jail
On another computer, we’ll make an SSH connection request to our test machine and purposefully mistype the password. You get three attempts to get the password right on each connection attempt.
The maxretry value will trigger after three failed connection attempts, not three failed password attempts. So, we have to type an incorrect password three times to fail connection attempt one.
We’ll then make another connection attempt and type the password incorrectly another three times. The first incorrect password attempt of the third connection request should trigger fail2ban.
After the first incorrect password on the third connection request, we don’t get a response from the remote machine. We don’t get any explanation; we just get the cold shoulder.
You must press Ctrl+C to return to the command prompt. If we try once more, we’ll get a different response:
ssh dave@ubuntu20-04.local
Previously, the error message was “Permission denied.” This time, the connection is outright refused. We’re persona non grata. We’ve been banned.
Let’s look at the details of the [sshd] jail again:
sudo fail2ban-client status sshd
There were three failures, and one IP address (192.168.4.25) was banned.
As we mentioned previously, fail2ban enforces bans by adding rules to the firewall ruleset. Let’s take another look at the ruleset (it was empty before):
sudo iptables -L
A rule has been added to the INPUT policy, sending SSH traffic to the f2b-sshd chain. The rule in the f2b-sshd chain rejects SSH connections from 192.168.4.25. We didn’t alter the default setting for bantime, so, in 10 minutes, that IP address will be unbanned and can make fresh connection requests.
If you set a longer ban duration (like several hours), but want to allow an IP address to make another connection request sooner, you can parole it early.
We type the following to do this:
sudo fail2ban-client set sshd unbanip 192.168.5.25
On our remote computer, if we make another SSH connection request and type the correct password, we’ll be allowed to connect:
ssh dave@ubuntu20-04.local
OLD Setup Info
Fail2Ban (authentication failure monitor) is an intrusion prevention software, written in Python. Fail2Ban analyzes various services log files (ssh, apache, postfix etc) and if it detects possible attacks (mainly Brute-force attacks), it creates rules on the firewall (iptables and many others) or tcp wrappers (/etc/ hosts.deny) to ban (temporarily or permanently) the wannabe hacker. Simultaneously, fail2Ban informs system administrator with email for its activity in real time.
Some activities which considered as attacks are:
multiple attempts for ssh connection using accounts that do not exist in the system
multiple attempts for ssh connection switching passwords
Apache requests for web pages often requested by bots and scanners.
You do not need fail2ban (not even iptables) if your hosting provider offers a dedicated hardware firewall. Of course, you must have the budget to pay for it and the knowledge to setup and manage it.
Hardware firewalls as Cisco ASA 550 series and even smaller devices as FortiGate-60C can offer protection, which fail2ban offers (and moreover).
Using apt-get, fail2ban 0.8.6-3wheezy1 will be installed:
After installation the following files have been created:
/etc/fail2ban/fail2ban.conf (basic settings)
/etc/fail2ban/jail.conf (settings for various services monitoring). Only ssh monitoring through iptables has been activated by default)
directory /etc/fail2ban/action.d/ actions to ban suspected IP
directory /etc/fail2ban/filter.d/ filters (regular expressions) through which fail2ban detects malicious attacks in log files
Also, log rotation settings for fail2ban has been created by Debian.
Do not use /etc/fail2ban/jail.conf, create /etc/fail2ban/jail.local instead:
In summary:
ignoreip: localhost (127.0.0.1) and server management IPs or any other trusted IP
bantime: 86400 one day (in seconds), the time after which ban will be removed (actionunban). Negative values (eg bantime = -1) make the ban permanent, but this is not particularly useful, as the bots will "seek" another server after the ban.
banaction: the preferred option to ban the suspected IP address
using "iptables-multiport" (recommended), iptables firewall will be used to ban the suspected IP
After system or fail2ban restart, all ban firewall rules will be cleared.
using "hostsdeny" tcp-wrappers (/etc/hosts.deny) will be used for ban
action: %(action_mwl)s (it means: ban and send an e-mail with whois report and relevant log lines)
So, my settings are:
REMARK: Remember to replace you@your-email.com with your email. destemail = you@your-email.com is not needed if you have forwarded root mail.
Setup
1
1
Configuration
nano /etc/fail2ban/jail.local
apt-get install fail2ban
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
[DEFAULT]
ignoreip = 127.0.0.1 82.192.71.9 95.211.46.207
bantime = 86400
destemail = you@your-email.com
banaction = iptables-multiport
action = %(action_mwl)s
# JAILS
[ssh]
enabled = true
maxretry = 3
[pam-generic]
enabled = true
banaction = iptables-allports
[ssh-ddos]
enabled = true
[webmin]
enabled = true
port = 10000,20000
filter = webmin-auth
banaction = iptables-multiport
action = %(action_mwl)s
logpath = /var/log/auth.log
maxretry = 3
[apache]
enabled = true
[apache-noscript]
enabled = true
port = http,https
banaction = iptables-multiport
action = %(action_mwl)s
[apache-overflows]
enabled = true
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
banaction = iptables-allports
action = %(action_mwl)s
logpath = /var/log/apache*/*access.log
maxretry = 1
[apache-nohome]
enabled = true
port = http,https
filter = apache-nohome
banaction = iptables-multiport
action = %(action_mwl)s
logpath = /var/log/apache*/*access.log
maxretry = 1
[php-url-fopen]
enabled = true
port = http,https
filter = php-url-fopen
logpath = /var/log/apache*/*access.log
maxretry = 1
[exim]
enabled = true
filter = exim
port = smtp,ssmtp
logpath = /var/log/exim*/rejectlog
maxretry = 1
[apache-w00tw00t]
enabled = true
port = http,https
filter = apache-w00tw00t
banaction = iptables-allports
action = %(action_mwl)s
logpath = /var/log/apache*/*error.log
maxretry = 1
[apache-myadmin]
enabled = true
port = http,https
filter = apache-myadmin
banaction = iptables-allports
action = %(action_mwl)s
logpath = /var/log/apache*/*error.log
maxretry = 2
apache-w00tw00t is a custom filter (details here). So, first create:
as follows
1
nano /etc/fail2ban/filter.d/apache-w00tw00t.conf
1
2
3
4
5
6
7
8
9
10
11
[Definition]
# Option: failregex
# Notes.: regex to match the w00tw00t scan messages in the logfile.
# Values: TEXT
failregex = ^.*\[client <HOST>\].*w00tw00t\.at\.ISC\.SANS\.DFind.*
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
ignoreregex =
apache-myadmin is a custom filter (details here). So, first create:
as follows
1
nano /etc/fail2ban/filter.d/apache-myadmin.conf
1
2
3
4
5
6
7
8
9
10
11
12
[Definition]
failregex = ^[[]client <HOST>[]] File does not exist: *myadmin* *\s*$
^[[]client <HOST>[]] File does not exist: *MyAdmin* *\s*$
^[[]client <HOST>[]] File does not exist: *mysqlmanager* *\s*$
^[[]client <HOST>[]] File does not exist: *setup.php* *\s*$
^[[]client <HOST>[]] File does not exist: *mysql* *\s*$
^[[]client <HOST>[]] File does not exist: *phpmanager* *\s*$
^[[]client <HOST>[]] File does not exist: *phpadmin* *\s*$
^[[]client <HOST>[]] File does not exist: *sqlmanager* *\s*$
^[[]client <HOST>[]] File does not exist: *sqlweb* *\s*$
^[[]client <HOST>[]] File does not exist: *webdb* *\s*
ignoreregex =
Start or restart fail2ban
Restart after system crash
Fail2ban will probably not start after system crash or power loss. In this case:
Recommended permanent solution
1
2
1
1
2
3
1
Other settings
nano /etc/default/fail2ban
...
FAIL2BAN_OPTS="-x"
...
rm /var/run/fail2ban/fail2ban.sock
systemctl restart fail2ban.service
systemctl start fail2ban.service
then
add the following (you can modify it to fit your needs)
-x forces sock deletion, if it exists after abnormal system shutdown.
Notification mail settings
Just edit the relevant file
Complex iptables structure
In systems with very complex iptables structure problems may occur during fail2ban chains creation. There is a workaround:
Add time.sleep(0.1) (line 145)
def __processCmd(self, cmd, showRet = True): beautifier = Beautifier() for c in cmd: time.sleep(0.1) beautifier.setInputCmd(c)
To check fail2ban activity:
Logs: tail /var/log/fail2ban.log
Check status: fail2ban-client status
Check status of certain service: fail2ban-client status ssh
Check regex results: fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
If unblock an IP is needed:
using iptables: iptables -D fail2ban-<CHAIN_NAME> -s <IP> -j DROP
using tcp-wrappers: remove IP from /etc/hosts.deny
There are some restrictions:
Fail2ban does not protect from distributed brute force attacks.
Fail2ban does not yet support ipv6.
Fail2Ban can monitor many other services. Here are some examples:
postfix
add the following
mod-security
Create the custom filter
as follows
1
1
2
3
4
5
6
7
1
1
2
3
4
5
6
7
8
1
1
2
3
1
1
Useful commands
Unblock IP
Restrictions
Other services
[apache-modsec]
enabled = true
port = http,https
filter = apache-modsec
banaction = iptables-multiport
action = %(action_mwl)s
logpath = /var/log/modsecurity/audit.log
maxretry = 1
nano /etc/fail2ban/jail.local
# Fail2Ban configuration file
#
# Author: Florian Roth
[Definition]
failregex = \[.*?\]\s[\w-]*\s<HOST>\s
ignoreregex =
nano /etc/fail2ban/filter.d/apache-modsec.conf
[postfix]
enabled = true
maxretry = 1
nano /etc/fail2ban/jail.local
nano /usr/bin/fail2ban-client
nano /etc/fail2ban/action.d/sendmail-whois-lines.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Fail2Ban configuration file
#
# Author: Xela
#
# $Revision: 728 $
#
[Definition]
# Option: failregex
# Notes.: regex to match the Forbidden log entrys in apache error.log
# maybe (but not only) provided by mod_evasive
#
# Values: TEXT
#
failregex = ^\[[^\]]*\]\s+\[error\]\s+\[client <HOST>\] client denied by server configuration:\s
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
then
add the following (you can modify it to fit your needs)
1
1
2
3
4
5
6
7
8
9
[apache-modevasive]
enabled = true
port = http,https
filter = apache-modevasive
banaction = iptables-allports
action = %(action_mwl)s
logpath = /var/log/apache*/*error.log
bantime = 600
maxretry = 3
nano /etc/fail2ban/jail.local
DDOS protection
Useful approaches to DDOS protection:
Fail2Ban sample reports:
--------------------------
Outside links --
http://www.pontikis.net/blog/fail2ban-install-config-debian-wheezy
http://www.howtoforge.com/fail2ban_debian_etch
http://www.ducea.com/2006/07/03/using-fail2ban-to-block-brute-force-attacks/
http://www.pseiko.nl/blog/288/persistent-iptables-bans-from-fail2ban