[nolan@nprescott.com] $>  cat blog archive feed

Configuring fail2ban


I was browing this webserver's load average history and trying to correlate "spikes" with activity in logs. This eventually lead to browsing the logs for fail2ban, with some notable results.

An example of the log format is as follows:

2018-05-05 01:35:48,628 fail2ban.filter  [446]: INFO   [sshd] Found
2018-05-05 01:38:27,333 fail2ban.filter  [446]: INFO   [sshd] Found
2018-05-05 01:38:27,767 fail2ban.actions [446]: NOTICE [sshd] Ban
2018-05-05 01:48:28,696 fail2ban.actions [446]: NOTICE [sshd] Unban
2018-05-05 01:54:06,607 fail2ban.filter  [446]: INFO   [sshd] Found
2018-05-05 01:57:06,275 fail2ban.filter  [446]: INFO   [sshd] Found

fail2ban performs what is basically a pattern match across a variety of logs, in my case it watches SSH log-in attempts through auth.log. Looking into the number of IP address bans reveals some potentially interesting patterns:

awk '$7 ~ /Ban/ { print $1, $2, $8 }' /var/log/fail2ban.log \
 | sed -e 's/,[0-9]..//g' \
       -e 's/ /:/' \
 | sort -k2,2 \
 | uniq -f1 -c
Attempts Date IP Address
13 2018-05-02:08:51:52
17 2018-05-02:04:56:22
8 2018-04-29:12:47:34
1 2018-05-03:20:43:08
18 2018-05-03:05:46:26
4 2018-05-02:15:30:19
4 2018-04-30:23:49:15
3 2018-05-05:01:05:50
9 2018-05-02:10:39:12
3 2018-04-30:06:14:38

And because it is fun to play around with gnuplot, the same information graphically:

set xdata time
set timefmt "%Y-%m-%d:%H:%M:%S"
set terminal svg size 800, 400
set output "ip-bans.svg"
plot "bans.dat" using 2:1:3 with labels offset 0,-1 \
point pointtype 7 notitle

IP bans over time

It seems that while some log-in attempts are tried and just as quickly given up, other try repeatedly (none of which will succeed because I've disabled anything but private key log-ins). I got curious about a better way to force a longer cool-off between attempts, because it is somehow annoying to know that in a single day a host is getting banned 18 times.

Looking at the default configuration for fail2ban reveals:

# "bantime" is the number of seconds that a host is banned.
bantime  = 600

Reading more about the project in this presentation, I found reference to local configuration for this exact scenario. To overwrite this default ban-time setting for failed SSH attempts I have to create a jail.local file at /etc/fail2ban/jail.local with the following:


bantime  = 3600

Which should serve to ban any IP for an hour between attempts. I've no idea if that'll change anything, but it could signal something to these automated log-in attempts and cause them to abort earlier. Time will tell I suppose.

Work For Later

The whole fail2ban project is pretty neat and has me thinking of ways I could extend it's uses. I've made some small attempts in the past at automating the recognition of this kind of abusive activity in my own pastebin, but I stopped short of permanently blocking IP ranges due to the finality of it. I'm now wondering if I could write a fail2ban filter to do a count of uploads and then use the same IP-block action.

[nolan@nprescott.com] $> █