Fail2ban is an intrusion prevention framework written in the Python programming language.
How does it work
Fail2ban scan log files and bans IPs that show the malicious signs: too many password failures, seeking for exploits, etc. Generally Fail2Ban then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action could also be configured. Out of the box Fail2Ban comes with filters for various services.
Installing Fail2ban using apt-get
sudo apt-get install fail2ban
Security against SSH brute-force attack
This is an exemple how to configure fail2ban to block automatically IPs of hosts who tries brute-force attack on port 22 (SSH).
If someone fails to connect more than 3 times in a row to the SSH server then TCP/SSH will be blocked during 15 minutes.
Fail2ban scans this log file: /var/log/auth.log by applying this filter /etc/fail2ban/filter.d/sshd.conf. The definition of this jail is going to be in this file: /etc/fail2ban/jail.conf
sudo vim /etc/fail2ban/jail.conf
# SSH # 3 failed retry: Ban for 15 minutes [ssh] enabled = true port = ssh filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] mail-whois-lines[name=%(__name__)s, dest=%(destemail)s, logpath=%(logpath)s] logpath = /var/log/auth.log maxretry = 3 bantime = 900 [ssh-ddos] enabled = true port = ssh filter = sshd-ddos action = iptables[name=SSH, port=ssh, protocol=tcp] logpath = /var/log/auth.log maxretry = 10
If an IP is going to continuously attempt to break into the system, it makes sense to ban it forever. This is done by monitoring fail2ban’s own logs for multiple bans over a certain time period.
Create the filter file /etc/fail2ban/filter.d/fail2ban.conf by adding the following
[Definition] failregex = fail2ban.actions: WARNING \[(.*)\] Ban <HOST> ignoreregex = fail2ban.actions: WARNING \[fail2ban\] Ban <HOST>
The rule to add in /etc/fail2ban/jail.conf file
# Track fail2ban's own logging and ban an IP permanently after 3 bans. [fail2ban] enabled = true filter = fail2ban action = iptables-allports[name=fail2ban] mail-whois-lines[name=%(__name__)s, dest=%(destemail)s, logpath=%(logpath)s] logpath = /var/log/fail2ban.log maxretry = 3 # findtime: 5 days findtime = 432000 # bantime: FOREVER bantime = -1
All you have to do now is restarting the service
sudo service fail2ban restart
See also how to secure your Linux server by disabling SSH connection to root user
Protection against DOS attack HTTP/GET
Denial-of-service attacks involves saturating the target machine with external communications requests, so much so that it cannot respond to legitimate traffic, or responds so slowly as to be rendered essentially unavailable.
In my Web architecture I have a caching server Varnish, first step is going to prepare Varnish log for fail2ban
Check that this file /etc/init.d/varnishncsa contains the following
It is important that this get to start automatically
Otherwise you’ll have problems with logrotate
It’s possible that you need to create the log file/folder manually
chown varnishlog:varnishlog -R /var/log/varnish/
Check that this file /etc/default/varnishncsa contains
If the value is equal to 0, it won’t start at boot
Now we are ready to configure fail2ban on the varnish server
In this exemple I consider that more than 360 requests in 2 minutes to my web server is an attack and will ban his IP for 10 minutes
sudo vim /etc/fail2ban/jail.conf
# Protect against DOS # 360 requests in 2 min :Ban for 10 min [http-get-dos] enabled = true port = http,https filter = http-get-dos logpath = /var/log/varnish/varnishncsa.log maxretry = 360 findtime = 120 action = iptables[name=HTTP, port=http, protocol=tcp] mail-whois-lines[name=%(__name__)s, dest=%(destemail)s, logpath=%(logpath)s] bantime = 600
Create the filter file /etc/fail2ban/filter.d/http-get-dos.conf by adding this
# Fail2Ban configuration file [Definition] # Option: failregex # Note: This regex will match any GET entry in your logs, so basically all valid and not valid entries are a match. # You should set up in the jail.conf file, the maxretry and findtime carefully in order to avoid false positives. failregex = ^<HOST>.*"GET # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT ignoreregex =
Now lets restart the service and get it activated
sudo /etc/init.d/fail2ban restart
Ban all DFind w00tw00t request
To protect your Apache server from w00tw00t, in the file /etc/fail2ban/jail.conf add
[apache-w00tw00t] enabled = true filter = apache-w00tw00t action = iptables[name=Apache-w00tw00t,port=80,protocol=tcp] mail-whois-lines[name=%(__name__)s, dest=%(destemail)s, logpath=%(logpath)s] logpath = /var/log/apache2/access*.log maxretry = 1
This is the rules file /etc/fail2ban/filter.d/apache-w00tw00t.conf
sudo vim /etc/fail2ban/filter.d/apache-w00tw00t.conf
[Definition] failregex = ^<HOST> -.*"GET \/w00tw00t\.at\.ISC\.SANS\.DFind\:\).*".* ignoreregex =
Now you can test the rule to check if it works fine by running this
sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-w00tw00t.conf
After every IP ban it is possible to receive an Email by editing /etc/fail2ban/jail.conf under the [DEFAULT] section
destemail = email@example.com
And replace action = %(action_)s by action = %(action_mwl)s or action = %(action_mw)s
You should receive an email when you restart the service
sudo /etc/init.d/fail2ban restart
You will receive an email every time a new IP is banned to the address firstname.lastname@example.org.
Checking if fail2ban is operational
On the server you can check what’s happening with this command
fail2ban-client status ssh
Another way to check the list of banned IP for all jails
Create this script
#!/bin/bash #lancer le script en sudo JAILS=$(fail2ban-client status | grep " Jail list:" | sed 's/`- Jail list:\t\t//g' | sed 's/,//g') for j in $JAILS do echo "$j $(fail2ban-client status $j | grep " Currently banned:" | sed 's/ |- Currently banned:\t//g')" done
Give it execution rights
sudo chmod +x checklist_ban
Now you can test the script by running it like this
You can also check if fail2ban is working correctly by looking into the log file /var/log/fail2ban.log
sudo tail -f /var/log/fail2ban.log
To find out the IP to unban run the following
iptables -L -n
Now as root run the following commands
fail2ban-client get <jailname> actionunban <ip address>
sudo iptables -D <jailname> -s <ip address> -j DROP
Replace <ip address> by the IP you wish to unban. To find out the <jailname> check the fail2ban config if you don’t know the jail name. The default SSH jailname is ssh-iptables.
Whitelist an IP
To prevent having your IP banned, I would like to add the “ignoreip” directive to all my jail conf
ignoreip = space separated list of IP’s to be ignored by fail2ban.