Back to the main page

Fail2ban for Apache


Fail2ban scans log files (e.g. /var/log/httpd/x-forwarded-for_log) and bans IPs (by updating iptables rules to reject IP for specified amount of time) that show the malicious signs, like too many password failures, seeking for exploits, etc.


Fail2ban is written in Python and it has one dependency that has to be installed first (python-inotify). So for example download python-inotify-0.1.0-1.2.el5.rf.x86_64.rpm and install it, then download fail2ban-0.8.14-1.el5.noarch.rpm and install it. Note, this is done on Oracle Linux 5.


The main config files are in the directory /etc/fail2ban/ and they shouldn't be edited since any future upgrade overwrites them. Instead create a .local file and put your configs there.

For example, to change fail2ban's log file, create the file /etc/fail2ban/fail2ban.local that has content like:
#  cat /etc/fail2ban/fail2ban.local
logtarget = /var/log/fail2ban/fail2ban.log

Another example, to change banned time, create file /etc/fail2ban/jail.local that has content like:
# cat /etc/fail2ban/jail.local
# "bantime" is the number of seconds that a host is banned.
# ban IP for 1h
bantime  = 3600

Fail2ban config file is fail2ban.conf and default values are used for now. The file jail.conf has default configs for services, do not edit this file. The custom jails for services are defined in directory /etc/fail2ban/jail.d/ . Filters are defined in directory /etc/fail2ban/filter.d/ .


This is example used for Apache service. Two default filters are used, they are apache-nohome and apache-overflows and config files are apache-nohome.conf and apache-overflows.conf. Also two additional filters are created, it's basically a file with defined regular expression that matches malicious activity. Files are apache-no_etcpasswd.conf and apache-no_megaindex.conf (in directory /etc/fail2ban/filter.d/).

$  cat apache-no_etcpasswd.conf 
# blocks line like this one
# - - [19/Dec/2015:21:47:33 -0800] "GET /styles/%f0%80%80%ae%0%80%80%ae/etc/passwd HTTP/1.1" 404 323 "-" "-"
# - - [19/Dec/2015:21:47:33 -0800] "GET /mailman/%f0%80%80%ae0%80%80%ae/etc/passwd HTTP/1.1" 404 324 "-" "-"
# - - [19/Dec/2015:21:47:33 -0800] "GET /expanded.php?conf=../../../../../../../etc/passwd HTTP/1.1" 404 210 "-" "-"
failregex = ^ -.*\"GET.*\/etc\/passwd.*HTTP.*
ignoreregex =

$  cat apache-no_megaindex.conf 
# blocks query from
failregex =  ^ -.*\"GET.**
ignoreregex =

There is the command to check a regular expression: The /tmp/filename is temp file with malicious activity and provided conf file contains regex that needs to match lines from temp file.

#  fail2ban-regex -v /tmp/filename apache-no_etc_passwd.conf 
Running tests
Use failregex file : apache-no_etc_passwd.conf
Use log file : /tmp/filename

Failregex: 12 total
|- #) [# of hits] regular expression
| 1) [12] ^ -.*\"GET.*\/etc\/passwd.*HTTP.*
| Sat Dec 19 21:47:11 2015
| Sat Dec 19 21:47:30 2015
| Sat Dec 19 21:47:33 2015


Then two jails are defined for these 2 filters (located in /etc/fail2ban/jail.d/). Files are apache-no_etcpasswd-iptables.local & apache-no_megaindex-iptables.local.

$  cat apache-no_etcpasswd-iptables.local 
enabled  = true
filter   = apache-no_etcpasswd
action   = iptables-multiport[name=apache-no_etcpasswd, port="80,443"]
logpath  = /var/log/httpd/x-forwarded-for_log
maxretry = 3

$  cat apache-no_megaindex-iptables.local 
enabled  = true
filter   = apache-no_megaindex
action   = iptables-multiport[name=apache-no_megaindex,port="80,443"]
logpath  = /var/log/httpd/x-forwarded-for_log
maxretry = 3

You can see that jail is enabled, there is the filter name (jail knows what's regular expression) and action (add drop rule in iptables and send me a email), there is the log file from where jail gets IP and number of malicious activities that triggers this jail.

Service management

Fail2ban is managed via chkconfig and service commands.

# chkconfig --list fail2ban
fail2ban 0:off 1:off 2:off 3:on 4:on 5:on 6:off

# service fail2ban status
fail2ban-server (pid 20804) is running...
|- Number of jail: 4
`- Jail list: apache-overflows, apache-no_etcpasswd, apache-nohome, apache-no_megaindex

# ps -ef | grep fail2ban
root 1534 21432 0 14:04 pts/0 00:00:00 grep fail2ban
root 20804 1 0 Jan02 ? 00:03:04 /usr/bin/python /usr/bin/fail2ban-server -b -s /var/run/fail2ban/fail2ban.sock -p /var/run/fail2ban/ -x

Some screenshots of fail2ban email and iptables but for SSH service.

Back to the main page