Sshguard, PF and FreeBSD

We recently had a problem with sshguard. Some IP that were blocked were still able to send packets through because the associated states were not killed properly with pfctl -k $ip. We used an older version until then, so I just did an upgrade to the latest port.

From this point however sshguard did not block anything anymore. In fact it didn’t recognize the correct backend to use to block those IP. Not sure if we always have to specify it manually in the configuration or if there is some kind of broken-autodetect. But you can force the backend inside the configuration file in /usr/local/etc/sshguard.conf (see /usr/local/etc/sshguard.conf.sample):

BACKEND="/usr/local/libexec/sshg-fw-pf"

WIDE DHCPv6 flood

On FreeBSD we generally use WIDE DHCPv6 (also known as KAME DHCPv6, dhcp6c or simply dhcp6) as DHCPv6 client. However a rare bug can trigger this client to flood the DHCP server with requests. This happened to us and quickly prompted online.net to block our server for outgoing flood. This scared me a bit at first, as I thought we might have been part of a DDoS attack. Thankfully that was not the case.

But we still had to disable dhcp6 (and consequently IPv6). On Linux it is generally recommended to limit the DHCPv6 traffic using iptables rules. However this is not as simple with PF on FreeBSD. You cannot provide a limit on the packet rate per rule. You can limit the connection rate (see max-src-conn-rate), but I’m not sure this could be of any use here. It should be possible to use altq but this is not part of the GENERIC kernel. I really didn’t want to compile a custom kernel just as a workaround.

Instead I used another DHCPv6 client, namely ISC DHCP client (isc-dhcp43-client). Just create /usr/local/etc/dhclient6.conf and configure your DUID:

interface "igb0" {
  send dhcp6.client-id <DUID>;
}

On FreeBSD, isc-dhcp43-client doesn’t come with any rc starting script, so here is one for DHCPv6 (you should place it in /usr/local/etc/rc.d/dhclient6:

#!/bin/sh
#
# PROVIDE: dhclient6
# REQUIRE: DAEMON
# KEYWORD: dhcp
#
# Add the following lines to /etc/rc.conf to enable dhclient6:
#
# dhclient6_enable="YES"
#

. /etc/rc.subr

name="dhclient6"
desc="ISC DHCPv6 client"
rcvar="dhclient6_enable"

start_cmd="dhclient6_start"
stop_cmd="dhclient6_stop"

dhclient6_start()
{
  /usr/local/sbin/dhclient -cf "${dhclient6_conf}" -P -v "${dhclient6_iface}"
}

dhclient6_stop()
{
  if [ -r "${dhclient6_pid}" ]
  then
    kill -- -$(cat "${dhclient6_pid}")
    rm -f "${dhclient6_pid}"
  fi
}

load_rc_config ${name}

: ${dhclient6_enable="NO"}
: ${dhclient6_pid="/var/run/dhclient6.pid"}
: ${dhclient6_conf="/usr/local/etc/dhclient6.conf"}
: ${dhclient6_iface=""}

run_rc_command "$1"

Finally enable this in /etc/rc.conf:

dhclient6_iface="igb0"
dhclient6_enable="YES"