irulan.net

pf Firewall Does Not Block Connections to Jail

If you redirect packets with pf to a FreeBSD jail, you can easily trip over this.

As pf’s rule order is

  • nat
  • rdr
  • block/pass

the rules are therefore processed in this very order. Since you rdr before you block, the packets have already been redirected before any block rule could catch them. The packets now originate from the loopback device. This is irritating but easy to fix.

Non-Working Example (Excerpt)

ext_if = "em0"
jail = "192.168.0.1"

table <badhosts> persist file "/etc/badhosts"

rdr pass on $ext_if inet proto tcp from any to any port 443  -> $jail port 443

block quick log from <badhosts>

You need to change from any to from !<badhosts> to explicitly deny IPs in the badhosts table and extend the block instruction to contain to any.

Working Example (Excerpt)

ext_if = "em0"
jail = "192.168.0.1"

table <badhosts> persist file "/etc/badhosts"

rdr pass on $ext_if inet proto tcp from !<badhosts> to any port 443  -> $jail port 443

block quick log from <badhosts> to any

Presto. Now reload the rules and check pflog for blocked connections matching the IPs in badhosts.

pfctl -f /etc/pf.conf
tcpdump -n -e -ttt -i pflog0