PF and sshguard

On my Digital Ocean account, I configured the firewall settings. Therefore I wouldn't need to setup a separate firewall. But there are a lot of failed login attempts via ssh and I want to get rid of them. My prefered method is to use sshguard that plugs in to my preferred firewall PF.

It won't be a complete, full fledged firewall setup (see pf.example.conf) but it should block failed ssh login attempts.

installing sshguard

PF is already installed in a FreeBSD setup, therefore only sshguard needs to be installed.

remote> sudo pkg install sshguard

We need to activate the PF backend for sshguard: edit /usr/local/etc/ssguard.conf and change the backend setting accordingly:

# Full path to backend executable (required, no default)
#BACKEND="/usr/local/libexec/sshg-fw-null"
#BACKEND="/usr/local/libexec/sshg-fw-ipfw"
BACKEND="/usr/local/libexec/sshg-fw-pf"

setting up PF

The configuration of the firewall should be straight forward. Add these lines to /etc/pf.conf or create the file if it doesn't exist

#    . 
#   / \     ONLY BLOCKS FAILED LOGIN ATTEMPTS
#  / ! \    DON'T USE AS SOLE FIREWALL SOLUTION
# /_____\   

# derived from a complete custom firewall
# basic setup from http://srobb.net/pf.html
# refined by https://home.nuug.no/~peter/pf/
# and https://www.openbsd.org/faq/pf/filter.html

#
# MACROS
#

# interfaces
ext_if = "vtnet0"

# tables
table <sshguard> persist


#
# HYGIENE
#

# skip rule on loopback device
set skip on lo0

# set the block policy
set block-policy return

# normalize fragmented packages:
scrub in all

# protect from spoofed or forged IP addresses
antispoof for $ext_if

#
# RULES
#

# pf processes from top to bottom
# last matching rule wins
# The general, highly simplified syntax for filter rules is:
#    action [direction] [log] [quick] [on interface] [af] [proto protocol]
#           [from src_addr [port src_port]] [to dst_addr [port dst_port]]
#           [flags tcp_flags] [state]


# WARNING! THIS RULE SHOULD BE CONSIDERED UNSAFE
# USE THIS APPROACH ONLY IF YOU HAVE AN EXTERNAL FIREWALL
# allow all traffic:
pass all

# block incoming traffic from addresses listed by sshguard
block drop in log quick from <sshguard> to any

security measures

Since it is very easy to log yourself out when configuring a firewall, at first a snapshot of the system is created on the Digital Ocean account, so the state (without a firewall) could be rolled back. To do this, the machine must be stopped first:

remote> sudo poweroff

enable the firewall

After powering up the droplet again, add these lines to the file /etc/rc.conf

sshguard_enable="YES"
pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"
pflog_logfile="/var/log/pflog"

Reboot the machine or start the serivices with:

remote> sudo service pf start
remote> sudo service sshguard start

You can check if sshguard works by monitoring /var/log/auth.log or /var/log/messages. Looking into the log of PF is a little bit more tricky, since file is in binary format but tcpdump(8) must be used.

remote> sudo tcpdump -n -e -ttt -r /var/log/pflog

To get an live update, you should monitor the pflog0 interface

remote> sudo tcpdump -n -e -ttt -i pflog0

cleanup

If everything works you might delete the snapshot created earlier.