NAT problems 14.3+

From: Rob Bloemers <bsd_at_connectedserver.com>
Date: Tue, 21 Apr 2026 14:38:47 UTC
I seem to have issues with i think something trivial like a simple NAT on freebsd higher then 14.3.

I have a machine with a public interface, which i put in a bridge to share with jails to use public ip addresses. And a private bridge for internal LAN (10.10.2.0/24, 10.10.2.1 configured on the bridge) of some jails.

With this ipfw rules set

```
#!/bin/sh
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"

wanif="ice0"
lanif="bridge9"

lannet="10.10.2.0/24"

ipfw table badhosts create type addr
ipfw table goodhosts create type addr

ipfw table goodhosts add 123.123.123.123

# No restrictions on Loopback Interface
$cmd 00001 allow all from any to any via lo0

# No restrictions on LAN Interface
$cmd 00008 allow all from any to any via $lanif 

# Configure NAT-WAN interface
ipfw -q nat 1 config if $wanif log reset same_ports 

# Check inbound traffic for redirections
$cmd 00006 nat 1 ip from any to me in via $wanif

$cmd 50 deny all from "table(badhosts)" to any

# Allow dynamic rules table connections
$cmd 00101 check-state

# NAT Lan traffic:
$cmd 00104 skipto 1000 tcp from $lannet to any out via $wanif keep-state
$cmd 00105 skipto 1000 tcp from $lannet to any out via $wanif setup keep-state
$cmd 00106 skipto 1000 udp from $lannet to any out via $wanif keep-state
$cmd 00107 skipto 1000 icmp from $lannet to any out via $wanif keep-state

# -- Host Traffic --
# Allow access to public DNS
# DNS TCP
$cmd 00201 allow tcp from any to any 53 out via $wanif setup keep-state
$cmd 00202 allow tcp from any to any 853 out via $wanif keep-state

# DNS UDP
$cmd 00203 allow udp from any to any 53 out via $wanif keep-state

# Allow outbound ANY connections
$cmd 00299 allow tcp from me to any out via $wanif setup keep-state

# Allow outbound ping
$cmd 00500 allow icmp from me to any out via $wanif keep-state

# Allow outbound NTP
$cmd 00501 allow udp from me to any 123 out via $wanif keep-state

# Allow outbound SSH
$cmd 00680 allow tcp from me to any 22 out setup keep-state

# Allow inbound public pings
$cmd 00700 allow icmp from any to me in via $wanif

$cmd 800 allow all from "table(goodhosts)" to any
$cmd 810 allow all from any to "table(goodhosts)"

# Deny and log all other outbound connections
$cmd 00900 deny log all from any to any out

# NAT outbound traffiC
$cmd 01000 nat 1 ip from any to any out via $wanif keep-state
$cmd 01003 allow ip from any to any

$cmd 12900 deny log all from any to any out
```

/etc/rc.conf
```
hostname="probably.doing.something.wrong.tld"
ifconfig_ice0="DHCP"
ifconfig_ice0_ipv6="inet6 accept_rtadv"
cloned_interfaces="bridge0 bridge9"
ifconfig_bridge0="addm ice0 up"
ifconfig_bridge9="inet 10.10.2.1 netmask 255.255.255.0 up"

sshd_enable="YES"
ntpd_enable="YES"
ntpd_sync_on_start="YES"
moused_nondefault_enable="NO"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="NO"
zfs_enable="YES"

firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"
firewall_logif="YES"

ipfw_nat_load="YES"
gateway_enable="YES"
```

added to default /boot/loader.conf
```
ipfw_load="YES"
ipfw_nat_load="YES"
```

Then i create a jail in this case with iocage.
```
iocage create -r 14.3-RELEASE -n test-jail
iocage set vnet=on test-jail
iocage set bpf=on test-jail
iocage set boot=on test-jail
iocage set defaultrouter=10.10.2.1 test-jail
iocage set dhcp=none test-jail
iocage set interfaces="vnet0:bridge9" test-jail
iocage set ip4_addr="vnet0|10.10.2.101/24" test-jail
```

And this works fine. icmp/udp/tcp it all works as expected, and how i have been since quite a few versions of FreeBSD

Then i noticed the 14.3 EOL warning a week ago, and i figured lets upgrade. But after the upgrade my NAT no longer functions as expected with 14.4. And it's been keeping me busy since.

icmp still works, udp (dns) too, though i need to change from the ISP dns to 1.1.1.1 (which is a bit odd). But tcp nothing seems to work anymore.

ipfw -d show at this point does show my outgoing tcp connection, but inside the jail it times out.

15.0-RELEASE (15.0 jail) with these settings behave even stranger, problematic i would say. Because with the rc.conf/ipfw rules loaded (that i have been using for many versions), ipfw seems to starts 'looping' packets as soon as i send out a packet from the jail be it a dns lookup or a fetch http://ip. And this renders the machine unavailable and i have to power cycle it. 

If anybody can shed a light on what changed, what i'm doing wrong, i'd highly appreciate it. And if i need to provide any more information i'll gladly do so. (i have try a ton of settings, and other firewall rulesets, even from the bsd manual for NAT, but no success)

Kind Regards
Rob