I’m deploying IPv6 for my employer. While getting corporate servers up on IPv6 is nice and all, of course I put priority on my own personal Web server.
Just because IPv6 is still populated mostly by early adopters, doesn’t mean we can neglect basic system security. That means that the server needs a packet filter for both IPv4 and IPv6. PF supports filtering both protocols in one ruleset.
The following is a unified IPv4/IPv6 PF ruleset for a small server. It:
Fill in the IPv4 and IPv6 external addresses, define your interface, adjust the permitted services to match your environment, and you’re ready to go.
ext_if="em0"
ext_addr="{192.0.2.40, 192.0.2.41}"
ext_v6="2001:db8:0:12::2"
table <mgmt_hosts> const {172.16.0.0/24, 172.16.5.0/24}
table <v6_mgmt_hosts> const {2001:db8:1:4::2}
set block-policy return
set loginterface $ext_if
set skip on lo0
scrub in all no-df
block in all
pass in on $ext_if proto icmp all
pass in on $ext_if proto icmp6 all
pass in on $ext_if inet from <mgmt_hosts>
pass in on $ext_if inet6 from <v6_mgmt_hosts>
pass out on $ext_if inet from $ext_addr to any
pass out on $ext_if inet6 from $ext_v6 to any
#services we permit
pass in on $ext_if proto tcp from any to $ext_addr port {25,53,80}
pass in on $ext_if proto udp from any to $ext_addr port 53
pass in on $ext_if inet6 proto tcp from any to $ext_v6 port {53,80}
pass in on $ext_if inet6 proto udp from any to $ext_v6 port 53