If you arrived here, it’s because you are tired of script kiddies attempting to brute force your server with sshd and polluting its logs.

The good news is that NetBSD has preinstalled a solution to deal with such situations that is more convenient than the famous fail2ban: the blocklistd.

The blocklistd is a deamon that has only one life purpose: monitor the number of failed connection attempt with some system service. After a defined threshold of failures, it will block the connection for a predefined time, for example, 6 hours.

Configuring npf (firewall)

The first step is to configure the NetBSD firewall if its still not:

NBSDCore# cp /usr/share/examples/blocklist/npf.conf /etc/npf.conf
NBSDCore# ifconfig npflog0 create
NBSDCore# echo create > /etc/ifconfig.npflog0

Now edit /etc/npf.conf pointing the variable $ext_if to your network interface that is being used to connect with the internet.

Now check if the necessary modules are loaded by the kernel:

NBSDCore# modstat | egrep "npf|jit"
if_npflog                  driver   builtin  -        0       - -
npf                        misc     builtin  -        4       - bpf
npf_alg_icmp               misc     builtin  -        0       - npf
npf_ext_log                misc     builtin  -        0       - npf
npf_ext_normalize          misc     builtin  -        0       - npf
npf_ext_rndblock           misc     builtin  -        0       - npf

Usually nfp, responsible for NetBSD firewall, is already loaded. In that case, only loading bpfjit is necessary and to configure for it to load on boot, and also a few tweaks on sysctl:

NBSDCore# modload bpfjit
NBSDCore# echo bpfjit >> /etc/modules
NBSDCore# echo modules=yes >> /etc/rc.conf
NBSDCore# sysctl -w net.bpf.jit=1
net.bpf.jit: 0 -> 1
NBSDCore# sysctl -w net.bpf.maxbufsize=4194304
net.bpf.maxbufsize: 1048576 -> 4194304
NBSDCore# echo net.bpf.jit=1 >> /etc/sysctl.conf
NBSDCore# echo net.bpf.maxbufsize=4194304 >> /etc/sysctl.conf

Configure blocklistd

Let’s start by also copying the sample configuration file provided by the system:

NBSDCore# cp /usr/share/examples/blocklist/blocklistd.conf /etc/blocklistd.conf

Edit /etc/blocklistd.conf to add or remove services that should be monitored. The file syntax is simple, where [local] is the service block list and [remote] is the list of IPs and domains that connection should always be allowed.

# Blocklist rule
# adr/mask:port type    proto   owner           name    nfail   disable
[local]
ssh             stream  *       *               *       3       6h
ftp             stream  *       *               *       3       6h
domain          *       *       named           *       3       12h
#6161           stream  tcp6    christos        *       2       10m
*               *       *       *               *       3       60

# adr/mask:port type    proto   owner           name    nfail   disable
[remote]
#129.168.0.0/16 *       *       *               =       *       *
#[2001:db8::]/32:ssh    *       *       *               =       *       *
#6161           =       =       =               =/24    =       =
#*              stream  tcp     *               =       =       =

After that, start all services and add them to system initialization:

NBSDCore# service npfd onestart
Starting npfd...
NBSDCore# service npf onestart
Enabling NPF /etc/npf.conf
NBSDCore# service blocklistd onestart
Starting blocklistd.
NBSDCore# echo npf=yes >> /etc/rc.conf
NBSDCore# echo npfd=yes >> /etc/rc.conf
NBSDCore# echo blocklistd=yes >> /etc/rc.conf
NBSDCore# echo blocklistd_flags=-r >> /etc/rc.conf

If everything is ok, the rule for blocklistd should be available at the firewall:

NBSDCore# npfctl show
# filtering:    inactive
# config:       loaded

group "external" on eth0 { # id="1" 
        ruleset "blocklistd" # id="2" 
        pass final all # id="3" 
}

group default { # id="4" 
        pass final all # id="5" 
}

Restart every service added at /etc/blocklistd.conf and tell the firewall to began processing it’s rules if not active:

NBSDCore# service sshd restart
Stopping sshd.
Starting sshd.
NBSDCore# npfctl start

If your server is already receiving failed connection attempts, your blocklist should contain a list of IPs that soon will be blocked:

NBSDCore# blocklistctl dump -a
        address/ma:port id      nfail   last access
  193.32.162.94/32:22           2/3     2024/06/28 03:42:07
   85.209.11.27/32:22           2/3     2024/06/28 03:48:57
  92.118.39.133/32:22   1       4/3     2024/06/28 03:47:42

And with that, your logs will become much cleaner. Taking out the sshd from it’s default port also help, given these kinds of attacks are usually automated.