PF – Packet Filter (Part 1)


# echo 'pf=YES' >> /etc/rc.conf.local

# pfctl -e    -> activate PF
# pfctl -d    -> deactivate PF 

Note:Note that this just enables or disables PF, it doesn’t actually load a ruleset. The ruleset must be loaded separately, either before or after PF is enabled.

# pfctl -f /etc/pf.confLoad the pf.conf file
# pfctl -nf /etc/pf.conf    Parse the file, but don't load it
# pfctl -Nf /etc/pf.conf    Load only the NAT rules from the file
# pfctl -Rf /etc/pf.conf    Load only the filter rules from the file

# pfctl -sn   		    Show the current NAT rules 
# pfctl -sr                 Show the current filter rules
# pfctl -ss                 Show the current state table
# pfctl -si                 Show filter stats and counters
# pfctl -sa                 Show EVERYTHING it can show


Lists are defined by specifying items within { } brackets:

block out on fxp0 from {, } to any
block out on fxp0 proto { tcp udp } from {, } to any port { ssh telnet }

trusted = “{ }”
pass in inet proto tcp from { $trusted } to port 22

Note:The commas between list items are optional.


table { }
table const {,, }
table persist file “/etc/spammers”

block in on fxp0 from { , } to any
pass in on fxp0 from to any

Table Address Matching

An address lookup against a table will return the most narrowly matching entry. This allows for the creation of tables such as:

table {, !, }

block in on dc0 all
pass in on dc0 from to any

Any packet coming in through dc0 will have its source address matched against the table :
• – narrowest match is; packet matches the table and will be passed
• – narrowest match is !; packet matches an entry in the table but that entry is negated (uses the “!” modifier); packet does not match the table and will be blocked
• – exactly matches; packet matches the table and will be passed
• – does not match the table and will be blocked

Manipulating with pfctl

Tables can be manipulated on the fly by using pfctl(8). For instance, to add entries to the table created above:

# pfctl -t spammers -T add 

This will also create the table if it doesn’t already exist. To list the addresses in a table:

# pfctl -t spammers -T show 

The -v argument can also be used with -Tshow to display statistics for each table entry. To remove addresses from a table:

# pfctl -t spammers -T delete 

FreeBSD Policy Routing

Policy routing is the art of deviating from destination-based shortest-path routing decisions of dynamic routing protocols. Policy routing considers aspects such as source/destination address, ports, protocol, type of service (ToS), and entry interfaces; do not confuse it with a routing policy or traffic policing. Traffic policing and shaping are sometimes summarized as traffic conditioning. Linux offers by far the most evolved policy routing approach of all Unices via multiple routing tables, the Routing Policy Database (RPDB), and the iproute2 (ip and tc) package for administration. Most other UNIX implementations implement policy routing via firewall marks and packet-mangling hooks.
Policy-routing setup on BSD platforms is pretty straightforward, limited, and essentially integrated into firewall architectures . Firewalling, NAT, and policy enforcement are done by basically the same “packet-mangling” structures.

# pass out quick on bge0 to bge1: from to any
# pass out log quick on bge0 route-to le0: proto icmp from le0 to any
# pass out log quick on bge0 proto icmp from any to any

Original Document: