The examples in this section illustrate PF rules and rule sets.
Configuration files follow standard UNIX syntax rules:
The pound sign (#) indicates a comment.
Rules and comments can coexist on the same line.
Extraneous white space is allowed for readability.
Rules can be more than one line long. A backslash (\) at the end of a line indicates that the rule continues on the next line.
For more detailed syntax information, see Packet Filter Rule Syntax and the pf.conf(5) man page.
Example 7 PF Configuration File Based on an IP Filter Configuration FileThe following is an IP Filter configuration file.
## IP Filter configuration file # Anything in that we initiate is okay pass out quick all keep state keep frags # Drop all NETBIOS traffic but don't log it. block in quick from any to any port = 137 #netbios-ns block in quick from any to any port = 138 #netbios-dgm block in quick from any to any port = 139 #netbios-ssn # Allow incoming IKE/IPsec pass in quick proto udp from any to any port = ike pass in quick proto udp from any to any port = 4500 pass in quick proto esp from any to any # Allow ping and ICMP destination unreachable / fragmentation needed pass in quick proto icmp from any to any icmp-type echo pass in quick proto icmp from any to any icmp-type 3 # Allow routing info # pass in quick proto udp from any to port = route # pass in quick proto icmp from any to any icmp-type 9 # routeradvert # pass in quick proto igmp from any to any # Allow incoming SSH pass in quick proto tcp from any to any port = ssh # Allow DHCP - required pass in quick proto udp from any to port = bootpc # Block and log everything else that comes in block in log all block in from any to 255.255.255.255 block in from any to 127.0.0.1/32
Its PF counterpart is the following:
## PF configuration file with identical policy ## to preceding IP Filter configuration file anchor "_auto/*" ## anchor "_static/*" set skip on lo0 ## reassemble no allows an attacker to fragment ## packets in a smart way and bypass the firewall. ## yes no-df allows reassembly and clears the ## dont-fragment bit. set reassemble yes no-df block log ## Allow incoming SSH pass in proto tcp to any port 22 ## equals: pass in proto tcp from any to any port = 22 flags S/SA ## Allow DHCP pass in inet proto udp from port 67 to port 68 pass in inet6 proto udp from port 547 to port 546 ## Allow NAT traversal, hence _auto above pass in inet proto udp from any to any port 500 pass in inet6 proto udp from any to any port 4500 ## Allow incoming IKE/IPsec pass in inet proto esp from any to any pass in inet6 proto esp from any to any ## Too-big packets must be allowed by firewall. ## However, the later 'pass out' rule allows all ## inbound responses, including to 'icmp6-type 2' ## messages. So, remove IPF 'pass in' rule in PF. ## pass in inet6 proto ipv6-icmp icmp6-type 2 ## Allow routing info pass in inet6 proto ipv6-icmp icmp6-type 134 pass in inet6 proto ipv6-icmp icmp6-type 135 pass in inet6 proto ipv6-icmp icmp6-type 136 # Anything in that we initiate is okay pass outExample 8 Sample PF Configuration File
This annotated file expands on the basic configuration rule set.
## make IP reassembly work set reassemble yes no-df ## ignore loopback traffic set skip on lo0 ## block everything unless told otherwise ## and send TCP-RST/ICMP unreachable ## for every packet which gets blocked block return ## accept incoming SSH connections pass in proto tcp to any port 22 ## allow incoming messages from DHCP pass in inet proto udp from port 67 to port 68 pass in inet6 proto udp from port 547 to port 546 ## packet too big - needed for PMTUD pass in inet6 proto ipv6-icmp icmp6-type 2 ## router advertisement pass in inet6 proto ipv6-icmp icmp6-type 134 ## neighbor solicitation pass in inet6 proto ipv6-icmp icmp6-type 135 ## neighbor advertisement pass in inet6 proto ipv6-icmp icmp6-type 136 ## allow all connections initiated from this system, ## including DHCP requests pass out