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).
Setup
Using apt-get, fail2ban 0.8.6-3wheezy1 will be installed:
apt-get install fail2ban
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.
Configuration
Do not use /etc/fail2ban/jail.conf, create /etc/fail2ban/jail.local instead:
nano /etc/fail2ban/jail.local
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
- using “iptables-multiport” (recommended), iptables firewall
will be used to ban the suspected IP
- 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.
[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:
nano /etc/fail2ban/filter.d/apache-w00tw00t.conf
as follows
[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:
nano /etc/fail2ban/filter.d/apache-myadmin.conf
as follows
[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
systemctl start fail2ban.service
Other settings
Restart after system crash
Fail2ban will probably not start after system crash or power loss. In this case:
rm /var/run/fail2ban/fail2ban.sock
systemctl restart fail2ban.service
Recommended permanent solution
nano /etc/default/fail2ban
...
FAIL2BAN_OPTS="-x"
...
-x forces sock deletion, if it exists after abnormal system shutdown.
Notification mail settings
Just edit the relevant file
nano /etc/fail2ban/action.d/sendmail-whois-lines.conf
Complex iptables structure
In systems with very complex iptables structure problems may occur during fail2ban chains creation. There is a workaround:
nano /usr/bin/fail2ban-client
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)
Useful commands
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
Unblock IP
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
Restrictions
There are some restrictions:
- Fail2ban does not protect from distributed brute force attacks.
- Fail2ban does not yet support ipv6.
Other services
Fail2Ban can monitor many other services. Here are some examples:
postfix
nano /etc/fail2ban/jail.local
add the following
[postfix]
enabled = true
maxretry = 1
mod-security
Create the custom filter
nano /etc/fail2ban/filter.d/apache-modsec.conf
as follows
# Fail2Ban configuration file
#
# Author: Florian Roth
[Definition]
failregex = [.*?]s[w-]*s<HOST>s
ignoreregex =
then
nano /etc/fail2ban/jail.local
add the following (you can modify it to fit your needs)
[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
mod-evasive
Create the custom filter
nano /etc/fail2ban/filter.d/apache-modevasive.conf
as follows
# 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
nano /etc/fail2ban/jail.local
add the following (you can modify it to fit your needs)
[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
DDOS protection
Useful approaches to DDOS protection:
Examples
Fail2Ban sample reports:
Entrepreneur | Full-stack developer | Founder of MediSign Ltd. I have over 15 years of professional experience designing and developing web applications. I am also very experienced in managing (web) projects.