This explains how to quickly setup the amazing fail2ban, which monitors your log files for activity you specify and performs certain actions once a threshold is reached. Simplest case: Monitor authlog for failed ssh login attempts, and ban the originating IP after a few tries.
Intro
I think no system should be without fail2ban for its simple to extend and pretty effective in blocking all kinds of attacks on your server. In my example setup i used OpenBSD 5.2 on a laptop, configured a simple packet filter firewall, and configured fail2ban to block ssh brute force attacks. Of course fail2ban can do a lot more – such as destroying your attacker by automatically pointing a few thousand machines from your botnet against him – but that is left as an exercise to the reader.
Requirements
Fail2ban has few requirements and in my case simply having python2.7 was enough.
Download and install fail2ban
# wget https://github.com/fail2ban/fail2ban/archive/master.zip # unzip master.zip # cd fail2ban-master # python2.7 setup.py install
I do encourage you to read the relevant README files in the fail2ban directory and not just blindly copy & paste. Depending on your system you may need to do some other configuration.
Open /etc/fail2ban/jail.conf and setup a new “jail”, which specifies a logfile to monitor and an action to perform. You can append the below to jail.conf and adjust ignoreip to the IP of your machine
[ssh-pf] enabled = true filter = sshd action = pf[localhost=10.0.2.216] logpath = /var/log/authlog ignoreip = 10.0.2.216
The next step is to setup an action that fail2ban shall perform when it detects activity specified by the filter “sshd”. Create a new file called /etc/fail2ban/action.d/pf.conf and make sure it has below contents
[Definition] actionstart = actionstop = actioncheck = actionban = /sbin/pfctl -t fail2ban -T add/32 actionunban = /sbin/pfctl -t fail2ban -T delete /32 [Init]
Setting up PF
PF is a wonderful firewall created and maintained by the OpenBSD project. To use it together with fail2ban, we will add a new “table” that holds the IP addresses of our would be attackers. See below file for a very very simplistic /etc/pf.conf that i use on my testing machine
lan_int = "alc0" # my laptops network card set block-policy return set skip on lo set loginterface $lan_int tablepersist block log block in quick from { } to any pass out quick # On this machine, i just allow ssh access pass in quick inet proto tcp from any to any port 22
Depending on your current pf.conf, all you have to do is to add a new table called fail2ban and a subsequent block rule that drops all traffic from IP’s listed in that table. After you made your adjustments, issue pf -f /etc/pf.conf to reload your packet filter configuration.
Testing
Now that everything is in place, start fail2ban and then try to repeatedly login to your machine via ssh from another pc. After a few tries, fail2ban will tell pf to ban your IP address for 5 minutes. You may want to be careful playing with this when you are setting up fail2ban on a remote server without physical access. (Use cron to disable fail2ban each hour for example, in case you lock yourself out).
# Start fail2ban # failban-client start
To make sure both fail2ban and PF survive a reboot, make sure your that /etc/rc.conf.local contains PF=”YES” and that /etc/rc.local contains something like the following:
if [[ -x /usr/local/bin/fail2ban-client ]]; then
mkdir /var/run/fail2ban
/usr/local/bin/fail2ban-client start
fi
Remarks
My above outline works and is effective, yet it does no justice to how powerful fail2ban and PF are. As usual you want to do more reading on the subject by looking up it’s relevant documentation. Fail2ban and PF are cool products, and we will do a lot more with them in future posts.
I’m in the process of setting up a nice NetBSD-based server and noticed fail2ban isn’t provided by packages for that system.
So your guide will certainly be useful
There is something missing in your
snippets!eg.
actionban = /sbin/pfctl -t fail2ban -T add /32
should be :
actionban = /sbin/pfctl -t fail2ban -T add /32
and
table persist
should be :
table persist
etc…
oops, looks like the “inferior” and “superior” signs are being removed from posts (wordpress anti html tagging protection)
Hi Fred – thanks for your comment… YIKES you are right! I noticed also in another post; will fix it asap
I reckon wordpress’s editor is not easy when publishing technical stuff!
(I personally use the PRE html tag for code snippets)
Oh it’s me again!
I have a problem with this setup, on my NetBSD 6.0 system :
Each time I restart the system, the old bans come up again when fail2ban starts (not real bruteforcers, but my own tests). Maybe a log rotation problem? Still investigating…
Why go through the bother of installing and configuring fail2ban when PF can do this already ?
http://home.nuug.no/~peter/pf/en/bruteforce.html
Fail2ban is more than just anti ssh-bruteforcing, it has jails for many other applications : postfix, dovecot, apache-auth…
That’s why PF alone may not be sufficient.
Exactly. PF takes care on the banning or unbanning – fail2ban is for watching logfiles and once it sees something you define, triggering one or more actions. Two different responsibilities here entirely. The most common case for fail2ban i guess is to watch your auth.log and ban people that are hitting your ssh port – but other more complex cases are possible as well – basically anything you could think of – as long you know what to look for in a logfile and what you want to do once fail2ban triggers. Watch for a certain file download, and send you an email with the downloaders IP address and GEO IP Lookup. I dunno – imagination
Agreed. fail2ban can do a lot of things besides banning — provided you want to do more.
In this case, you want to protect $service from bruteforcing. PF has an integrated mechanism to accomplish this, along with rate limiting. Just expliciting this, since Fred’s comment suggests it only applies to ssh, which is not the case.
As far as I am concerned, I prefer the simplest approach to solve a problem, and IMO, the PF method is better in this case. You have PF running already, and implementing this is adding at most 1 line in your pf.conf which you are maintaining. The fail2ban approach requires you to install additional software *and* maintain it.