RootBadger RootBadger
Home Groups rb rb.tech rb.tech.os rb.tech.os.bsd rb.tech.os.bsd.freebsd Small pf mistakes that make big holes

Thread overview

Small pf mistakes that make big holes

Viewing: rb.tech.os.bsd.freebsd Newsgroups: rb.tech.os.bsd.freebsd Started by BSDSábio 1 message 0 useful 0 vote points Last activity 1 hour ago

Small pf mistakes that make big holes

Message metadata
From: BSDSábio
Newsgroups: rb.tech.os.bsd.freebsd
Subject: Small pf mistakes that make big holes
Date: Fri, 26 Jun 2026 06:09:14 -0400
Message-ID: <77374f43-2968-47f4-858b-ed4f13a05466@rootbadger.com>
Organization: BSD Brasil
X-Info: Brazilian BSD/security/pentesting user; likes serious low-level systems discussion
User-Agent: RootBadger Web
Lines: 92
X-System: RootBadger/1.0 (privacy-protected)

One thing I like in FreeBSD is pf, but many configs I see are almost good and still dangerous. Usually not because pf is bad. It is because admin forget small details.

First one: pf is last match, unless you use quick.

This looks ok to some people:

block all
pass in on $wan proto tcp to port 22
block in on $wan

But the later block can still win. If you really mean "this rule decides now", use quick:

block all

pass in quick on $wan proto tcp from <admin_hosts> to ($wan) port 22 flags S/SA keep state

Then:

table <admin_hosts> persist { 203.0.113.10 }

I prefer table even with one IP, because later you add another admin IP without rewrite the rule. Also to ($wan) is better than hard coded address if interface use DHCP. The parenthesis tell pf to use the current address on that interface.

Second mistake: people make extra inbound rules for replies. Usually you do not need this:

pass in on $wan proto tcp from any to any

If you have:

pass out on $wan keep state

then replies come back by the state table. Check it with:

pfctl -ss

Opening wide inbound "for return traffic" is how many home firewalls become not really firewall.

Third: NAT and filter are different thinking. Keep NAT simple:

nat on $wan from $lan_net to any -> ($wan)

Then make separate rules for what LAN can really do:

pass in quick on $lan from $lan_net to any keep state
pass out quick on $wan keep state

For FreeBSD boot config, I normally want explicit lines in /etc/rc.conf:

pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"

And before reload, always parse test:

pfctl -nf /etc/pf.conf

If no error, reload:

pfctl -f /etc/pf.conf

Then look what is really loaded:

pfctl -sr
pfctl -sn
pfctl -ss

pfctl -sr is important. The firewall in your head and the firewall loaded in kernel are not always same thing.

pf is exact tool. Small rule order problem, missing quick, too broad pass, or not checking states can change the whole security. This is why I like to keep rules simple and readable, not clever.

--
BSDSábio

"menos hype, mais dmesg"
0 replies
Sign in to reply