FreeBSD Firewall Basics: IPFW, PF, and IPFilter for Home Networking

FreeBSD includes three built-in packet filters: IPFW, PF, and IPFILTER (IPF). All support stateful inspection, NAT, and IPv4/IPv6, but they differ in syntax and rule evaluation:

FirewallRule BehaviorSyntax StyleStrengths
IPFWFirst-match wins; numbered rulesShell-like, scriptableHigh performance, good for beginners
PFLast-match wins by default; quick for first-matchClean, macro-friendlyVery flexible, NAT/QoS support
IPFILTERLast-match wins unless quick is usedPF-likeCross-platform consistency

🏠 Typical Home Network Ruleset Goals

  • Allow full LAN communication (e.g., 192.168.1.0/24)
  • Permit outbound HTTP/HTTPS, DNS, NTP
  • Allow SSH access from LAN only
  • Block all other inbound traffic
  • Prevent spoofed or invalid traffic

Protocols: TCP on ports 80, 443, 22; UDP on 53, 123.


🛠 Example Configurations

✅ IPFW (First-match, numbered rules)

# /etc/ipfw.rules
ipfw -q -f flush
ipfw add 10 allow all from any to any via lo0
ipfw add 20 allow ip from 192.168.1.0/24 to any
ipfw add 30 allow ip from any to any out
ipfw add 40 allow ip from any to any established
ipfw add 50 allow tcp from any to any 80,443 out
ipfw add 60 allow udp from any to any 53,123 out
ipfw add 70 allow tcp from 192.168.1.0/24 to any 22
ipfw add 65534 deny ip from any to any

Enable and apply:

sudo sysrc firewall_enable="YES"
sudo sysrc firewall_script="/etc/ipfw.rules"
chmod +x /etc/ipfw.rules
sudo service ipfw restart

✅ PF (Last-match by default; use quick for early exceptions)

# /etc/pf.conf
ext_if = "em0"
lan_if = "re0"
lan_net = "192.168.1.0/24"

set skip on lo0
block all
pass out all keep state

pass in on $lan_if from $lan_net to any keep state
pass out proto { tcp, udp } to any port { 80 443 53 123 } keep state
pass in quick on $lan_if proto tcp from $lan_net to any port 22 keep state

Activate:

sudo sysrc pf_enable="YES"
sudo sysrc pf_rules="/etc/pf.conf"
sudo pfctl -f /etc/pf.conf
sudo service pf restart

✅ IPFILTER (Last-match; quick stops further processing)

# /etc/ipf.rules
pass in quick on lo0 all
pass out quick on lo0 all

pass in quick on rl0 from 192.168.1.0/24 to any keep state
pass out quick on rl0 all keep state

pass out quick proto tcp from any to any port = 80 keep state
pass out quick proto tcp from any to any port = 443 keep state
pass out quick proto udp from any to any port = 53 keep state
pass out quick proto udp from any to any port = 123 keep state

pass in quick proto tcp from 192.168.1.0/24 to any port = 22 keep state
block in all

Enable:

sudo sysrc ipfilter_enable="YES"
sudo sysrc ipfilter_rules="/etc/ipf.rules"
sudo service ipfilter restart

🧭 How to Choose?

  • IPFW – Great for simple setups; high performance; deep FreeBSD/Dummynet integration.
  • PF – Highly flexible, macros, NAT, QoS, logging—ideal for advanced configurations.
  • IPFILTER – If you need compatibility with other OSes and prefer PF-style syntax—less actively developed now.

📚 References

FreeBSD Handbook: https://docs.freebsd.org/en/books/handbook/firewalls/


Conclusion: For a home setup, IPFW offers simplicity and raw performance, PF gives you the most flexibility, and IPFILTER remains viable for legacy or cross-OS consistency. Remove unrelated details, reference the Handbook directly, and focus on practical configurations tailored for home use.

Post Comment

You May Have Missed