Protect your web site with Fail2Ban!


from WiKi:

Fail2Ban operates by monitoring log files (e.g. /var/log/auth.log, /var/log/apache/access.log, etc.) for selected entries and running scripts based on them. Most commonly this is used to block selected IP addresses that may belong to hosts that are trying to breach the system's security. It can ban any host IP address that makes too many login attempts or performs any other unwanted action within a time frame defined by the administrator. Fail2Ban is typically set up to unban a blocked host within a certain period, so as to not "lock out" any genuine connections that may have been temporarily misconfigured. However, an unban time of several minutes is usually enough to stop a network connection being flooded by malicious connections, as well as reducing the likelihood of a successful dictionary attack.

Install and Configure fail2ban on Ubuntu server

Warning! all actions required root privileges!

Update system:

$sudo apt-get update
$Install fail2ban
$sudo apt-get install fail2ban

go to /etc/fail2ban

$cd /etc/fail2ban/

need copy jail.conf to jail.local

$sudo cp jail.conf jail.local

it will be main config file for fail2ban

For first time fail2ban is ready to protect your server by default:

on port tcp 22 (ssh)  

in file /etc/fail2ban/jail.local:

enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6

it means

listening log file /var/log/auth.log and fail2ban will look for errors attempts like this:

May 14 20:43:12 exim auth worker: PASSV: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot [email protected] rhost=45.58.99.<hidden>

and after 6 attempts will be blocked by iptables

filter = sshd

it means:

used filter sshd

go to /etc/fail2ban/filter.d/

file sshd.conf is a filter

find block reg exp in file:
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sReceived disconnect from <HOST>: 3: \S+: Auth fail$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
^(?P<__prefix>%(__prefix_line)s)User .+ not allowed because account is locked<SKIPLINES>(?P=__prefix)(?:error: )?Received disconnect from <HOST>: 11: .+ \[preauth\]$
^(?P<__prefix>%(__prefix_line)s)Disconnecting: Too many authentication failures for .+? \[preauth\]<SKIPLINES>(?P=__prefix)(?:error: )?Connection closed by <HOST> \[preauth\]$
^(?P<__prefix>%(__prefix_line)s)Connection from <HOST> port \d+(?: on \S+ port \d+)?<SKIPLINES>(?P=__prefix)Disconnecting: Too many authentication failures for .+? \[preauth\]$
^%(__prefix_line)spam_unix\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=\S*\s*rhost=<HOST>\s.*$

these are all reg exp wich willl be catch in log file /var/log/auth.log

You can add yourself filtters and reg exp

For wordpress site you can create filter:

$sudo touch /etc/fail2ban/filter.d/wp-auth.conf

and copy and paster to it:

# WordPress brute force auth filter: /etc/fail2ban/filter.d/wp-auth.conf:
# Block IPs trying to auth wp wordpress
# Matches e.g.
# pay attention in this raw:
# - [07/Jun/2014:11:15:29] "POST /wp/wp-login.php HTTP/1.0" 200 4523
# - [07/Jun/2014:11:15:29] "GET /wp-content HTTP/1.0" 200 4523

# fail2ban will scan log file and will be find like this and block ip address

failregex = ^<HOST> .* "GET \/(wp-login.php|xmlrpc.php)

ignoreregex =

fail2ban looking for regexp in log file:

^<HOST> .* "GET \/(wp-login.php|xmlrpc.php)

and create jail for it:

go to file /etc/fail2ban/jail.local and put it to the bottom of file:

enabled = true
filter = wp-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath = /var/www/mezzanine/logs/ssl_access.log # pls change to your log file
bantime = 86400
maxretry = 3

after 3 attempts fail2ban will block ip address for 86400 secconds (24hs)

If you would like to enter in admin panel only from your IP address, add in section [DEFAULT] in file /etc/fail2ban/jail.local

ignoreip = <your ip_address>  

# with no symbols '<>' 

and save it

fail2ban will be ignore your ip ddresses 

If you use your own filters you can check it by command:

$fail2ban-regex ssl_access.log /etc/fail2ban/filter.d/wp-auth.conf
Running tests
Use failregex file : /etc/fail2ban/filter.d/wp-auth.conf
Use log file : ssl_access.log
Failregex: 5540 total
|- #) [# of hits] regular expression
| 1) [4686] ^<HOST> .* "GET \/(wp-login.php|xmlrpc.php)
| 2) [854] ^<HOST> .* "GET \/(wp-content)

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
| [19758] Day/MONTH/Year:Hour:Minute:Second

Lines: 19758 lines, 0 ignored, 5540 matched, 14218 missed
Missed line(s):: too many to print. Use --print-all-missed to print all 14218 lines

all filters work fine.

After that you should restart fail2ban

$sudo service fail2ban restart

All detailed info you can see at 


Who banned or unbanned:

2017-05-21 06:48:30,205 fail2ban.server : INFO Changed logging target to /var/log/fail2ban.log for Fail2ban v0.8.11
2017-05-22 01:42:51,534 fail2ban.actions: WARNING [wp-auth] Ban
2017-05-22 01:42:53,597 fail2ban.actions: INFO [wp-auth] 60.241.112.<hidden>. already banned
2017-05-22 01:42:56,601 fail2ban.actions: INFO [wp-auth] 60.241.112.<hidden>. already banned
2017-05-23 01:42:52,254 fail2ban.actions: WARNING [wp-auth] Unban
2017-05-23 09:37:02,946 fail2ban.actions: WARNING [wp-auth] Ban
2017-05-23 10:07:06,785 fail2ban.server : INFO Stopping all jails
2017-05-23 10:07:07,541 fail2ban.actions: WARNING [wp-auth] Unban

also you can see status iptables:

$sudo iptables -S
-N fail2ban-NoAuthFailures
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoAuthFailures
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A FORWARD -i tun0 -j ACCEPT
-A FORWARD -o tun0 -j ACCEPT
-A FORWARD -o eth0 -j ACCEPT
-A FORWARD -i eth0 -j ACCEPT
-A fail2ban-NoAuthFailures -j RETURN
-A fail2ban-ssh -j RETURN

nobody banned yet )


Currently unrated


There are currently no comments

New Comment


required (not published)