Jacobs "Blog"

Fail2ban for SMTP: CentOS 6

In this episode, I take Fail2Ban, chuck it onto CentOS 6 and make it stop idiots trying to brute force passwords from my systems.


Install Fail2Ban

yum -y install epel-release
yum -y install fail2ban

The Regex

Let's look at this incredibly simple regex

warning:.*\[([0-9]{1,3}\.){3}[0-9]{1,3}\]: SASL (PLAIN|LOGIN) authentication failed: authentication failure

This will match anything prefixed by "warning:", that contains the IP as denoted by the regex string "([0-9]{1,3}.){3}[0-9]{1,3}" encased with square brackets ([*]), suffixed by "SASL ... authentication failed.." where the first ... has the words "PLAIN" or "LOGIN" in it's place.

To make this fail2banny, change the IP regex to so fail2ban understands where to pull the host information from. You can test the above regex against your mail log (/var/log/maillog?) to see if it returns what you're chasing.

Configure Fail2Ban

SMTP Rule/Regex

# cat /etc/fail2ban/filter.d/smtp-auth.conf
[Definition]
failregex = warning:.*\[<HOST>\]: SASL (PLAIN|LOGIN) authentication failed: authentication failure
ignoreregex =

Testing your Rule/Regex

# fail2ban-regex /var/log/maillog /etc/fail2ban/filter.d/smtp-auth.conf
Running tests
=============

Use   failregex filter file : smtp-auth, basedir: /etc/fail2ban
Use      log file : /var/log/maillog
Use      encoding : UTF-8

Results
=======

Failregex: 4694 total
|-  #) [# of hits] regular expression
|   1) [4694] warning:.*\[<HOST>\]: SASL (PLAIN|LOGIN) authentication failed: authentication failure
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [331920] (?:DAY )?MON Day 24hour:Minute:Second(?:\.Microseconds)?(?: Year)?
`-

Lines: 331920 lines, 0 ignored, 4694 matched, 327226 missed
[processed in 43.29 sec]

Missed line(s): too many to print.  Use --print-all-missed to print all 327226 lines

jail.local

fail2ban will automatically look for this file. Having a .local file will override what's in the .conf file, and the .local file will not be overwritten like the .conf file will be when the application is updated.

# cat /etc/fail2ban/jail.local
[smtp-auth]
enabled      = true
filter        = smtp-auth
action        = iptables[name=SMTP, port=smtp, protocol=tcp]
logpath      = /var/log/maillog
maxretry        = 5

Using/Checking Fail2Ban

Start Fail2Ban

/etc/init.d/fail2ban start

Enable Fail2Ban on Boot

chkconfig --add fail2ban

Check Fail2Ban Configured Jails

fail2ban-client status

Check if things are being blocked

# iptables -L
Chain INPUT (policy ACCEPT)
target   prot opt source               destination
f2b-SMTP   tcp  --  anywhere             anywhere           tcp dpt:smtp

# cat /var/log/messages | grep -i fail2ban
Jan 22 15:35:46 server yum[22455]: Installed: fail2ban-0.9.6-1.el6.1.noarch
Jan 22 16:08:38 server fail2ban.server[7306]: INFO Changed logging target to SYSLOG (/dev/log) for Fail2ban v0.9.6
Jan 22 16:08:38 server fail2ban.database[7306]: INFO Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
Jan 22 16:08:38 server fail2ban.database[7306]: WARNING New database created. Version '2'
Jan 22 16:08:38 server fail2ban.jail[7306]: INFO Creating new jail 'smtp-auth'
Jan 22 16:08:38 server fail2ban.jail[7306]: INFO Jail 'smtp-auth' uses pyinotify {}
Jan 22 16:08:38 server fail2ban.jail[7306]: INFO Initiated 'pyinotify' backend
Jan 22 16:08:38 server fail2ban.filter[7306]: INFO Added logfile = /var/log/maillog
Jan 22 16:08:38 server fail2ban.filter[7306]: INFO Set maxRetry = 5
Jan 22 16:08:38 server fail2ban.filter[7306]: INFO Set jail log file encoding to UTF-8
Jan 22 16:08:38 server fail2ban.actions[7306]: INFO Set banTime = 600
Jan 22 16:08:38 server fail2ban.filter[7306]: INFO Set findtime = 600
Jan 22 16:08:38 server fail2ban.jail[7306]: INFO Jail 'smtp-auth' started
Jan 22 16:09:30 server fail2ban.filter[7306]: INFO [smtp-auth] Found x.x.x.x
Jan 22 16:09:30 server fail2ban.filter[7306]: INFO [smtp-auth] Found x.x.x.x
Jan 22 16:09:30 server fail2ban.filter[7306]: INFO [smtp-auth] Found x.x.x.x
Jan 22 16:09:30 server fail2ban.filter[7306]: INFO [smtp-auth] Found x.x.x.x
Jan 22 16:09:30 server fail2ban.filter[7306]: INFO [smtp-auth] Found x.x.x.x
Jan 22 16:09:30 server fail2ban.filter[7306]: INFO [smtp-auth] Found x.x.x.x

If you see "Found x.x.x.x" but not "Ban x.x.x.x", this is simply info saying "I found something using this match", but it hasn't hit the "maxretry" during the "findtime". You should configure these inside your jail.local configuration. Feel free to set [DEFAULT] values.

After Word

It's worth mentioning that with this configuration, fail2ban did ban IP's attempting to brute force passwords on our SMTP server HOWEVER I have noticed a lot of IP's trying once or twice then giving it a rest. If you get targeted like we do you should adjust the values above according to how people attempt to attack you.

If you were being targetted, I highly recommend re-evaluating your edge MTA to ensure that emails spoofing your domain are not sent, as this can cause issues as well. We had @gmail.com sending us phishing emails two days after I started banning a certain botnet weilding individual.