PF pf rules not loading at boot

Hello,

I'm trying to setup freebsd 14.0 as a home router and my one hump is getting pf rules to load at boot. Any help would be appreciated

Here's a copy of my /etc/pf.conf and /etc/rc.conf

Code:
# /etc/pf.conf
# Rules must be in order: options, normalization, queueing, translation, filtering
# macros
ext_if = "igb0"
int_if = "igb1"
wg_if = "wg0"

table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16     \
           172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
           192.168.0.0/16 198.18.0.0/15 198.51.100.0/24        \
           203.0.113.0/24 }
# Set allowed ICMP types
# Blocking ICMP entirely is bad practice and will break things,
# FreeBSD applies rate limiting by default to mitigate attacks.
icmp_types = "{ 0, 3, 4, 8, 11, 12 }"

#####    options    #####
set block-policy return
set loginterface $ext_if
set skip on lo0
set skip on igb3

##### normalization #####
scrub in all fragment reassemble no-df max-mss 1440

#####  translation  #####
nat on $ext_if from $int_if:network to any -> ($ext_if)
nat on $ext_if from $wg_if:network to any -> ($ext_if)
# upnp
# To test install miniupnpc (client) on another machine and run:
# `upnpc -e "upnpc test" -a $IP 5001 5001 TCP`
# tail the miniupnpd logs and check the anchor with:
# `pfctl -a miniupnpd -s nat`
rdr-anchor miniupnpd

### port forward ###

rdr pass on $ext_if inet proto tcp from any to ($ext_if) port { 80 } -> 10.0.0.10 port 80
rdr pass on $ext_if inet proto tcp from any to ($ext_if) port { 443 } -> 10.0.0.10 port 443

#####   filtering   #####
anchor "miniupnpd"
pass in quick on $ext_if inet proto udp to port 57820
pass in quick on $ext_if inet proto icmp all icmp-type $icmp_types
pass in quick on { $wg_if } inet
# antispoof quick for { $ext_if $int_if }
block in quick on $ext_if from <martians> to any
block return out quick on egress from any to <martians>
block all
pass out quick inet
pass in on { $int_if } inet


And my rc.conf
Code:
# /etc/rc.conf
clear_tmp_enable="YES"
syslogd_flags="-ss"
sendmail_enable="NONE"
hostname="apu"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="NO"
zfs_enable="YES"

### network ###
ip6addrctl_enable="NO"
ifconfig_igb0="DHCP"
ifconfig_igb1="inet 10.0.0.1 netmask 255.255.255.0"
gateway_enable="YES"
pf_enable="YES"
pflog_enable="YES"
# wireguard
wireguard_enable="YES"
wireguard_interfaces="wg0"
# emergency direct connect nic
ifconfig_igb3="inet 192.168.0.1 netmask 255.255.255.0"

### services ###
ntpdate_enable="YES"
sshd_enable="YES"
miniupnpd_enable="YES"
dnsmasq_enable="YES"
dnscrypt_proxy_enable="YES"

After a reboot, NAT isn't working, and the firewall is open (ie i can connect to ssh on from the internet). But if i either a) load in rules manually with `pfctl -f /etc/pf.conf` or b) `service pf stop; service pf start` then it'll disconnect my ssh connection but the rules are then loaded and everything works as expected.

Code:
ndrew@apu ~> uptime
 8:56AM  up 2 mins, 2 users, load averages: 0.12, 0.06, 0.02
andrew@apu ~> sudo pfctl -sr
Password:
andrew@apu ~> sudo service pf status
Status: Enabled for 0 days 00:01:47           Debug: Urgent

State Table                          Total             Rate
  current entries                        0               
  searches                            3187           29.8/s
  inserts                                0            0.0/s
  removals                               0            0.0/s
Counters
  match                               3187           29.8/s
  bad-offset                             0            0.0/s
  fragment                               0            0.0/s
  short                                  0            0.0/s
  normalize                              0            0.0/s
  memory                                 0            0.0/s
  bad-timestamp                          0            0.0/s
  congestion                             0            0.0/s
  ip-option                              2            0.0/s
  proto-cksum                            0            0.0/s
  state-mismatch                         0            0.0/s
  state-insert                           0            0.0/s
  state-limit                            0            0.0/s
  src-limit                              0            0.0/s
  synproxy                               0            0.0/s
  map-failed                             0            0.0/s
 
I think i figured it out! Hope this helps someone else.

I didn't even think about using () on non-dhcp interfaces.

Code:
andrew@apu ~/apu (master)> git diff
diff --git a/pf.conf b/pf.conf
index 660330c..d9c45b2 100644
--- a/pf.conf
+++ b/pf.conf
@@ -28,8 +28,8 @@ scrub in all fragment reassemble no-df max-mss 1440
 
 
 #####  translation  #####
-nat on $ext_if from $int_if:network to any -> ($ext_if)
-nat on $ext_if from $wg_if:network to any -> ($ext_if)
+nat on $ext_if from ($int_if:network) to any -> ($ext_if)
+nat on $ext_if from ($wg_if:network) to any -> ($ext_if)
 # upnp
 # To test install miniupnpc (client) on another machine and run: 
 # `upnpc -e "upnpc test" -a $IP 5001 5001 TCP`
 
Back
Top