snork.ca ... making kittens cry since 2001


Fail2ban Multiline Filters On Jessie 2018-11-19


I like to use Fail2ban on some of my machines to keep some of the losers at bay. It basically keeps an eye on your log files and when it sees someone (an IP address usually) doing something stupid, it can perform an action (usually banning that IP in some kind of firewall). Most of the machines I have that require Fail2ban are running Debian Jessie which comes with version 0.8.13-1 of Fail2ban. This works fine for most of my needs but on my mail server I have been seeing a LOT of this crap in my log files:

Nov 19 13:17:32 mx2 postfix/smtpd[29473]: connect from unknown[60.31.214.44]
Nov 19 13:17:38 mx2 postfix/smtpd[29473]: disconnect from unknown[60.31.214.44]
Nov 19 13:19:45 mx2 postfix/smtpd[29480]: connect from unknown[60.31.214.44]
Nov 19 13:19:47 mx2 postfix/smtpd[29480]: disconnect from unknown[60.31.214.44]
Nov 19 13:20:26 mx2 postfix/smtpd[29480]: connect from unknown[185.36.81.43]
Nov 19 13:20:27 mx2 postfix/smtpd[29480]: disconnect from unknown[185.36.81.43]
Nov 19 13:22:03 mx2 postfix/smtpd[29480]: connect from unknown[60.31.214.44]
Nov 19 13:22:04 mx2 postfix/smtpd[29480]: disconnect from unknown[60.31.214.44]
Nov 19 13:24:02 mx2 postfix/smtpd[29486]: connect from unknown[185.36.81.43]
Nov 19 13:24:02 mx2 postfix/smtpd[29486]: disconnect from unknown[185.36.81.43]
Nov 19 13:24:24 mx2 postfix/smtpd[29486]: connect from unknown[60.31.214.44]
Nov 19 13:24:29 mx2 postfix/smtpd[29486]: disconnect from unknown[60.31.214.44]
Nov 19 13:26:44 mx2 postfix/smtpd[29490]: connect from unknown[60.31.214.44]
Nov 19 13:26:45 mx2 postfix/smtpd[29490]: disconnect from unknown[60.31.214.44]
Nov 19 13:27:42 mx2 postfix/smtpd[29490]: connect from unknown[185.36.81.43]
Nov 19 13:27:42 mx2 postfix/smtpd[29490]: disconnect from unknown[185.36.81.43]
Nov 19 13:29:02 mx2 postfix/smtpd[29490]: connect from unknown[60.31.214.44]
Nov 19 13:29:04 mx2 postfix/smtpd[29490]: disconnect from unknown[60.31.214.44]
Nov 19 13:31:18 mx2 postfix/smtpd[29495]: connect from unknown[60.31.214.44]
Nov 19 13:31:19 mx2 postfix/smtpd[29495]: disconnect from unknown[60.31.214.44]
Nov 19 13:31:21 mx2 postfix/smtpd[29495]: connect from unknown[185.36.81.43]
Nov 19 13:31:21 mx2 postfix/smtpd[29495]: disconnect from unknown[185.36.81.43]
Nov 19 13:33:33 mx2 postfix/smtpd[29497]: connect from unknown[60.31.214.44]
Nov 19 13:33:44 mx2 postfix/smtpd[29497]: disconnect from unknown[60.31.214.44]
Nov 19 13:35:06 mx2 postfix/smtpd[29497]: connect from unknown[185.36.81.43]
Nov 19 13:35:07 mx2 postfix/smtpd[29497]: disconnect from unknown[185.36.81.43]
Nov 19 13:35:58 mx2 postfix/smtpd[29497]: connect from unknown[60.31.214.44]
Nov 19 13:35:59 mx2 postfix/smtpd[29497]: disconnect from unknown[60.31.214.44]
theback The view from around back.

There is nothing terribly harmful there, but this gets pretty tiresome for someone who actually looks at logs. Those of you who do not look at logs can just wink back at Marigold's ass and close this tab. Those of you who would suggest that I could filter that crap from my log analysis application can just wink back at Marigold's ass and close this tab. Those of you who find yourselves thinking:

Hey, you can't write a Fail2ban rule for that because those "connect" and "disconnect" lines happen for every legitimate message that arrives at your mail server!

may be interested in what follows. Yes, v0.8.x of Fail2ban can not filter based on multiple lines... but v0.9.x can. To get v0.9.x on Jessie one might try the Stretch .deb file or the NeuroDebian repos (yes, that is an http link), but it is actually easier than that. If you scratch around in the Fail2ban documentation you'll find a couple of little items that make it a breeze to get v0.9.x working on your Jessie box. All it really takes is this (yes, logged in as root):

# apt-get update
# apt-get install python-pyinotify
# cd ~ && mkdir f2btmp && cd f2btmp
# wget https://github.com/fail2ban/fail2ban/archive/0.9.4.tar.gz
# tar -xzf 0.9.4.tar.gz
# cd fail2ban-0.9.4
# python setup.py install
# cp files/debian-initd /etc/init.d/fail2ban
# cd ~
# rm -R f2btmp/
# update-rc.d fail2ban defaults
# /etc/init.d/fail2ban start

Once you have Fail2ban running you will also need to configure three parts for your filter.

  1. a jail
  2. a filter
  3. an action

The jail basically defines your new filter system, such as how many times the line must appear, in how many minutes, what filter to use, and what action to take. The filter is one or more regular expressions that tell Fail2ban what to look for in the logs, and the action tells it what to do when it finds it. To block the garbage listed above you would create a new jail.local file like this:

/etc/fail2ban/jail.local [fu_smtp_empty]
enabled = true
logpath = /var/log/mail.log
maxretry = 1
findtime = 60
bantime = 86400
banaction = fu_smtp_empty

In short, if Fail2ban finds the filter 1 time, in less than 60 seconds, it will ban the IP for 86400 seconds (one day), based on the "fu_smtp_empty" action file. Next, the file defining the actual filter needs to be created:

/etc/fail2ban/fileter.d/fu_smtp_empty.conf [Init]
maxlines = 4

[Definition]
failregex = ^.* mx2 postfix\/smtpd\[\d*\]: connect from .*\[<HOST>\]\n.* mx2 postfix\/smtpd\[\d*\]: disconnect from .*\[.*\]$

ignoreregex =

The "maxlines" directive limits how many lines this filter can span. I chose 4 [possibly foolishly] because I wanted to account for the possibility that log lines from unrelated connections may creep between the two I am looking for, and because I wanted the number to be significantly less than I would normally see in a legitimate session. The failregex line of course tells Fail2ban what to look for, and the "ignoreregex" can be used in case an exception needs to be made. Note the use of \n in the failregex to show that Fail2ban should see a newline to span multiple lines. Finally, an action file is required:

/etc/fail2ban/action.d/fu_smtp_empty.conf [Definition]
actionstart =
actionstop =
actioncheck =

actionban = iptables -I INPUT -s <ip> -j DROP
            logger -t "smtp/fail2ban" -i -p mail.info ALERT <ip> BANNED FOR EMPTY SMTP SESSIONS

actionunban = iptables -D INPUT -s <ip> -j DROP

This pretty simple ban action will add an iptables rule that drops all traffic from this IP address and also barfs a log entry in my mail.log to show that the IP has been dumped. When the 86400 seconds elapses, the actionunban line will remove the iptables rule and allow traffic from that IP address once again.

Made using Notepad++ & FastStone. Hosted on Debian with nginx & php. Powered by North Korean mushrooms.