This is not my article. I found a link to the original article on a Reddit post: https://www.reddit.com/r/openbsd/comments/5e6u61/fail2ban_on_openbsd_60/ The page no-longer exists. I dug up an old copy of the page from the Internet Archive Wayback Machine. The original article was found here: https://blog.gordonturner.com/2016/11/20/fail2ban-on-openbsd-6-0/ Gordon, if this is your article, please forgive the reprint.
If you have ever had a server exposed to the Internet, you will often see attempts to login to ssh on port 22.
After improving my log monitoring, these login attempts annoyed me enough to take action. So I installed Fail2ban.
Fail2ban monitors logs and will add ip addresses to your firewall to block based on rules. Fail2ban is written in Python and available for several platforms and can monitor different logs (not just ssh).
I have setup Fail2ban to watch for 3 failed logins (one failed login will allow 3 password attempts) and then block that IP address for 1 day.
The following instructions are for:
OpenBSD 6.0
Fail2ban 0.9.5
The instructions also assume that you have an OpenBSD server running with ssh port 22 exposed to the Internet and use Packet Filter (PF) for your firewall.
Install Python, when asked for version, select 3.5:
sudo pkg_add python
Download fail2ban-0.9.1.tar.bz2, uncompress and install:
cd ~/Downloads wget https://github.com/fail2ban/fail2ban/archive/0.9.5.tar.gz mv 0.9.5.tar.gz fail2ban-0.9.5.tar.gz tar -zvxf fail2ban-0.9.5.tar.gz cd fail2ban-0.9.5 sudo python3.5 setup.py install sudo mkdir /var/run/fail2ban
Next create a new rc file for Fail2ban. This will manage starting, stoping and checking for the status of Fail2ban. It is based on the rc.template, sabnzbd.rc and filebeat.rc.
http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/ports/infrastructure/templates/rc.template
http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/ports/news/sabnzbd/pkg/sabnzbd.rc
http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/ports/sysutils/beats/filebeat/pkg/filebeat.rc?rev=1.1.1.1&content-type=text/plain
It is worth noting that the rc file is a little non-traditional, because Fail2ban has two components, a client and a server. Normally rc files will start a daemon, check to see if the process is active and kill that process to stop. The `check` logic could probably be improved, but it works.
Create the rc file and paste in the content:
sudo vi /etc/rc.d/fail2ban
#!/bin/sh # # As the fail2ban-client is used to start the fail2ban-server, this rc is a little non-traditional. # # The rc_check looks for the fail2ban-server python thread (fail2ban-server as a parameter) # # The rc_stop can kill the fail2ban-server (The Nuclear Option) or the fail2ban-client (Polite Option). # # pkill -f "fail2ban-server" # # Avoiding The Nuclear Option. daemon="/usr/local/bin/fail2ban-client" . /etc/rc.d/rc.subr rc_bg=YES rc_reload=NO #pexp=fail2ban-server rc_pre() { install -d -o root -m 0700 /var/run/fail2ban } rc_start() { $${rcexec} "${daemon} start ${daemon_flags} ${_bg}" } rc_check() { pgrep -q -f "fail2ban-server" } rc_stop() { ${rcexec} "${daemon} stop" } rc_cmd $1
Set permissions:
sudo chmod 555 /etc/rc.d/fail2ban
Edit `/etc/rc.conf.local` to add the Fail2ban rc file:
sudo vi /etc/rc.conf.local
# ADDED pkg_scripts="fail2ban"
Need to configure fail2ban what an ssh login failure looks like. Please update `192.168.0.10` to your local server ip address.
A few comments here:
– Fail2ban is monitoring `/var/log/authlog`
– After an IP has 3 failed logins, the IP will be blocked
– The IP will be blocked for 1 day (86400 seconds)
– Exclude localhost IP
Create a new file `ssh-pf.local`:
sudo vi /etc/fail2ban/jail.d/ssh-pf.local
# NOTE: 192.168.0.10 is local ip # NOTE: 3600 = 1 hr # NOTE: 86400 = 1 day
[ssh-pf]
enabled = true filter = sshd action = pf[localhost=192.168.0.10] logpath = /var/log/authlog findtime = 600 maxretry = 3 bantime = 86400 ignoreip = 192.168.0.10
Configure fail2ban what action to take when the ssh login fails.
Existing configuration fail2ban for pf.conf is unchanged:
sudo vi /etc/fail2ban/action.d/pf.conf
# Fail2Ban configuration file # # OpenBSD pf ban/unban # # Author: Nick Hilliard <nick@foobar.org> # # [Definition] # Option: actionstart # Notes.: command executed once at the start of Fail2Ban. # Values: CMD # # we don't enable PF automatically, as it will be enabled elsewhere actionstart = # Option: actionstop # Notes.: command executed once at the end of Fail2Ban # Values: CMD # # we don't disable PF automatically either actionstop = # Option: actioncheck # Notes.: command executed once before each actionban command # Values: CMD # actioncheck = # Option: actionban # Notes.: command executed when banning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: IP address # number of failures # unix timestamp of the ban time # Values: CMD # actionban = /sbin/pfctl -t -T add /32 # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: IP address # number of failures # unix timestamp of the ban time # Values: CMD # # note -r option used to remove matching rule actionunban = /sbin/pfctl -t -T delete /32 [Init] # Option: tablename # Notes.: The pf table name. # Values: [ STRING ] # tablename = fail2ban
Setup OpenBSD Packet Filter with a new table to store the banned ip addresses
NOTE: that table names are always enclosed in < > angled brackets
Edit `/etc/pf.conf` and add to end:
sudo vi /etc/pf.conf
# BEGIN ADDED fail2ban # NOTE: ext_if is external interface device ext_if="vio0" table persist block quick proto tcp from to $ext_if port ssh # END ADDED fail2ban
Use rc scripts to manage:
sudo /etc/rc.d/fail2ban check sudo /etc/rc.d/fail2ban start sudo /etc/rc.d/fail2ban stop
Manually manage:
sudo fail2ban-client status sudo fail2ban-client start sudo fail2ban-client stop
Tail fail2ban log:
sudo tail -f /var/log/fail2ban.log
Print contents of table:
sudo pfctl -t fail2ban -Ts
Start and load pf.conf:
sudo pfctl -e sudo pfctl -f /etc/pf.conf
That’s it! It can be satisfying to login and print out the content of the PF fail2ban table and see the blocked IP addresses. Also, fewer spikes in the log monitoring of failed logins.