Example PF Rules
Here’s a working set of PF rules that I’ve used before on my FreeBSD gateway. I posted this before on port80.
Hopefully it will help someone out there. It is sometimes easier to take a working set of rules, understand how it works, and modify to suit your own environment. Anyway, here goes.
ex_if is the external interface.
int_if is the internal interface.
pvt_net is your LAN.
dns_server would usually be your isp’s dns server.
ext_tcp_services are the tcp services that you want to allow the big bad world to access on your FreeBSD box. You can specify port numbers instead of the names, but I find the names to be more readable. For a list of services and (usually) associated ports, “more /etc/services”.
int_tcp_services are same, but for your internal LAN only.
port_rdr is the port you want to redirect. You can specify a port range as well, e.g 6500:6510.
client_rdr is the box to which you want the port redirected to.
## MACROS ext_if = "rl1" int_if = "rl0" pvt_net = "192.168.0.0/24" dns_server = "203.0.178.191" ext_tcp_services = "{ ftp, ssh, auth }" int_tcp_services = "{ ftp, ssh, http, 3306 }" # 3306 is for MySQL. allowed_icmp_types = "echoreq" netbios = "{ 137, 138, 139, 445 }" port_rdr = "<port YOU WANT TO REDIRECT>" client_rdr = "<ip TO WHICH YOU WANT THE PORT REDIRECTED TO>" ## TABLES table <firewall> const { self } table <rfc1918> const { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 } ## GLOBAL OPTIONS set block-policy drop #set state-policy if-bound #set loginterface $ext_if ## TRAFFIC NORMALIZATION scrub in on $ext_if all no-df #scrub all reassemble tcp fragment reassemble ## NETWORK ADDRESS TRANSLATION AND REDIRECTS nat on $ext_if from $pvt_net to any -> ($ext_if) # Port redirection: rdr on $ex_if proto tcp from any to ($ex_if) port $port_rdr -> $client_rdr port $port_rdr ## FILTER RULES # Setup a default deny policy. Remember that in PF the last matching rule wins. # Therefore, this rule is the catch-all rule. Anything not specifically allowed # will be matched by this rule, and dropped. block drop log all # Prevent spoofing block in log quick on $ext_if from </rfc1918><rfc1918> to any antispoof log quick for $int_if inet # Prevent netbios leakage (from Windows systems on our LAN) block in log quick on { $int_if, $ext_if } proto { tcp, udp } from any to any port $netbios # Allow loopback interface pass quick on lo0 all # Outgoing from firewall pass out quick on $ext_if inet proto tcp from ($ext_if) to any flags S/SA modulate state pass out quick on $ext_if inet proto { udp, icmp } from ($ext_if) to any keep state # Allow internal network send traffic to the internet pass in quick on $int_if inet proto tcp from $pvt_net to !<firewall> flags S/SA modulate state pass in quick on $int_if inet proto { udp, icmp } from $pvt_net to !</firewall><firewall> keep state # Allow dns traffic out pass out quick on $ext_if inet proto udp from ($ext_if) to $dns_server port domain keep state # Incoming to the firewall box, allow some services # Allow hosts from the Internet to access some services pass in quick on $ext_if inet proto tcp from any to ($ext_if) port $ext_tcp_services flags S/SA keep state # Allow hosts from our private LAN to access some services pass in quick on $int_if inet proto tcp from $pvt_net to ($int_if) port $int_tcp_services flags S/SA keep state # Allow bootp service to function on the firewall pass in quick on $int_if proto udp from any port bootpc to any port bootps pass out quick on $int_if proto udp from any port bootps to any port bootpc # Allow icmp pass in log quick inet proto icmp all icmp-type $allowed_icmp_types keep state # Incoming active ftp-data (tcp port 20). This is required for active ftp to work. pass in quick on $int_if inet proto tcp from any port ftp-data to ($int_if) port >= 1024 flags S/SA keep state pass in quick on $ext_if inet proto tcp from any port ftp-data to ($ext_if) port >= 1024 flags S/SA keep state # Allow passive ftp in pass in on $int_if proto tcp from $pvt_net to any port > 49151 keep state pass in on $ext_if proto tcp from any to any port > 49151 keep state