Automate server intrusion detection and banning with Fail2ban
Monitors server access logs and automatically bans IP addresses of bots and attackers
5 min read
A Fail2Ban installation monitors server access logs and automatically bans IP addresses of bots and attacking users in iptables. Fail2Ban analyses server logs and identifies a pattern where a suspicious user or bot is trying to access restricted areas on the server. Brute force attacks repeatedly fail and use combinations of login credentials on after another. Fail to ban can detect failed login attempts on SSH and Apache webserver.
Installation is straight forward update
apt-get and run instal fail2ban as a root user. Theses are Debian/Ubuntu commands for CentOS
yum would replace
apt-get and paths/locations might differ for configuration files. Check this tutorial for non-Debian operating systems.
sudo apt-get update sudo apt-get install fail2ban
Fail2Ban can keep server admin updated with emails but to keep it simple, let’s not configure this additional feature. The configuration file /etc/fail2ban/fail2ban.conf is superseded by fail2ban.local file. So this local config file needs to be created to keep additional settings. Here is part of the default installation config file.
[Definition] # Option: loglevel # Notes.: Set the log level output. # CRITICAL # ERROR # WARNING # NOTICE # INFO # DEBUG # Values: [ LEVEL ] Default: ERROR # loglevel = INFO logtarget = /var/log/fail2ban.log # Options: dbfile # Notes.: Set the file for the fail2ban persistent data to be stored. # A value of ":memory:" means database is only stored in memory # and data is lost when fail2ban is stopped. # A value of "None" disables the database. # Values: [ None :memory: FILE ] Default: /var/lib/fail2ban/fail2ban.sqlite3 dbfile = /var/lib/fail2ban/fail2ban.sqlite3 # Options: dbpurgeage # Notes.: Sets age at which bans should be purged from the database # Values: [ SECONDS ] Default: 86400 (24hours) dbpurgeage = 86400
Fail2ban focuses on failed SSH login attempts by default. Using custom config file jails for HTTP web server like Apache, FTP and mail server can be enabled.
Fail2Ban Apache Jail Configuration
[apache-auth] enabled = true port = http,https logpath = /var/log/apache2/error.log maxretry = 3 findtime = 600 bantime = 1h
So here we have set up fail2ban to look apache2 error logs for brute force attack using one password after another. Three failed login attempts within 600 seconds would lead to an IP address ban for an hour. Restart fail2ban for the changes to take effect sudo systemctl restart fail2ban. To enable fail2ban service to start with boot use sudo systemctl enable fail2ban.
Other Apache error log jails
Apache no script
[apache-noscript] port = http,https logpath = %(apache_error_log)s ignoreip = localhost or an IP
Fail2ban analyses errors of not found .php, .asp, .pl scripts. Client attempting to exploit known scripts are banned.
[apache-overflows] logpath = %(apache_error_log)s maxretry = 2
Detects apache buffer overflow attempts by the client using long suspicious URLs.
Apache no home
[apache-nohome] port = http,https
Detects failures to find a home directory on a server.
Apache bot search
[apache-botsearch] enabled = true port = http,https maxretry = 2
Alternative to apache-noscript filter this filter aims at blocking specific URLs, script or webservices.
Apache access log jails
Beware, access logs of busy websites can be huge. Setting Fail2ban to monitor access log can have a negative impact on server performance. So think about costs and benefits of access log jails before enabling them.
Apache bad bots
Bans bots identified as spammer robots crawling the web for email addresses.
[apache-badbots] port = http,https logpath = %(apache_access_log)s
PHP URL fopen
Matches and blocks fopen URL PHP injection attacks
[php-url-fopen] port = http,https
Jails for roundcude, openwebmail and horde are available, just add the location of log file in these jails.
[roundcube-auth] port = http,https logpath = %(roundcube_errors_log)s #if roundcube logs to journal then use following. #backend = %(syslog_backend)s [openwebmail] port = http,https logpath = /var/log/openwebmail.log [horde] port = http,https logpath = /var/log/horde/horde.log
Fail2ban custom filters and jail for WordPress
Error logs have multiple failed requests to WordPress login URLs or files like wp_login.php. This blog post creates a custom regular expression to scan failed WordPress logins in the error log. Using this RegEx a new filter file is created in Fail2ban directory. Once the filter is in place a [wordpress] jail can be added in jail.local. You can easily create your own filters with custom RegEx. Try online regular expression services like regex101.com with your error log to create a regular expression.
Fail2ban client and commands
Use Fail2ban client to setup configuration or check status of jail and banned IP addresses.
- Check status of Fail2ban
sudo fail2ban-client status
- Check status of Apache jail
sudo fail2ban-client status apache
- Ban an IP address directly with client
sudo fail2ban-client set apache banip x.x.x.x
- Similarly unban an IP address
sudo fail2ban-client set apache unbanip x.x.x.x
- Restart after editing jail configuration for changes to take effect
sudo systemctl restart fail2ban
- Check firewall rules added to iptables
sudo iptables -L
- Start fail2ban on boot
sudo systemctl enable fail2ban
I am also on Twitter. You can follow me there as I regularly tweet about my journey.
- How To Protect an Apache Server with Fail2Ban on Ubuntu 14.04 — By Justin Ellingwood, Digitalocean.com/community
- Fail2ban jail configuration — Github.com/fail2ban
- Set Up Fail2ban To Protect An Apache Web Server — hitjethva, devops.ionos.com/tutorials
- A Tutorial for Using Fail2ban to Secure Your Server — Linode.com