After graduating college, I am moving from Brooklyn, NY to Redmond, WA (guess where I got a job). I always wanted to re-do my OPNsense firewall (currently a HP T730) with stock FreeBSD and IPFW’s in-kernel NAT.
Why IPFW? Benchmarks have shown
IPFW to be faster
which is especially good for my Tor relay, and because I can! However, one
downside of IPFW is less documentation vs PF, even less without
we’re not using), and this took me time to figure this out.
But since my T730 is already packed, I am testing this on a old PC with two NICs, and my laptop  as a client with an USB-to-Ethernet adapter.
So you may ask how do we do this?
First, you need the
ipfw_nat kernel modules. To load them, run:
kldload ipfw ipfw_nat
Then, you need a firewall ruleset. A basic ruleset is as follows:
#!/bin/sh ipfw -q flush ipfw nat 1 config if fxp0 redirect_port tcp 192.168.1.10:9001 9001 ipfw add 100 nat 1 ip4 from any to me in via fxp0 ipfw add 200 nat 1 ip4 from 192.168.1.0/24 to any out via fxp0 ipfw add allow ip from any to any
This setup sets up NAT with
fxp0 as the WAN interface, and sets up a port
192.168.1.10 at port
Then, you should enable the firewall in
/PATH/TO/RULES with the path to the IPFW ruleset, and don’t forget to
chmod a+x /PATH/TO/RULES (to be safe).
And enable the NAT firewall with
service ipfw start.
What does all this mean?
ipfw line flushes the existing ruleset, which you should do for
obvious reasons when reloading.
In the second
nat 1 config if fxp0part sets up NAT with
fxp0as the WAN interface. Replace
fxp0with your WAN interface name.
redirect_port tcp 192.168.1.10:9001 9001sets up a port forward to
9001with the IP:Port combo you want to forward. This can be repeated multiple times.
ipfw line allows traffic to come in to the internal network via
ipfw line allows outgoing NAT traffic from the
subnet to go through
192.168.1.0/24 with the subnet you want
to use. If you have multiple noncontiguous subnets, repeat this line with each
You can also expand the ruleset, as explained in the
ipfw(8) man page.
 - FreeBSD, not Windows at the time of writing. My job could change this, who knows?
 - You will not have NAT reflection/hairpinning. If you need to access an external domain from your internal network, consider split-horizon DNS.