# /etc/pf.conf - minimal router/firewall with NAT for a LAN

# To load changes, run:
#   pfctl -f /etc/pf.conf

# Interfaces and networks
external_if = "em0"
local_if = "em1"
localnet = $local_if:network

# Table created by dhcpd (see /etc/rc.conf.local)
table <leased_ips> persist counters

# Table created by me (see /home/dave/bedtime)
table <bedtime_exempt> persist counters

# Default behaviors
set loginterface $external_if
set skip on lo
antispoof for $external_if
antispoof for $local_if

# Normalize traffic
#match in all scrub (no-df random-id max-mss 1440)

# NAT for LAN to the current $external_if address
# * Note that to enable NAT in the first place, the kernel has IP forwarding
#   turned on in /etc/sysctl.conf: net.inet.ip.forwarding=1
# The parens around ($external_if) are to allow the DHCP-assigned (from the
# ISP) IP address to change and for the rule to still work.
match out on $external_if inet from $localnet nat-to ($external_if)

# Packet rules
# ------------------------------------------------------------------
# Terminology (in the correct syntax order):
#   in/out = packet direction to the interface
#   on     = interface
#   from   = packet's origination
#   to     = packet's destination
#   port   = port

# Default deny
block all

# UDP for domain and network time protocols
# Without this rule, DNS lookup slowed down to a crawl. Standard DNS queries
# use udp!
pass quick proto udp to port { domain ntp }
# DNS also uses tcp sometimes
pass quick proto tcp to port domain

# Allow ping (echo) icmp packets both directions
# and MTU messages (unreach)
pass quick inet proto icmp icmp-type { echoreq unreach }
# Allow traceroute udp packets
pass out on $external_if inet proto udp to port 33433:33626

# Allow all traffic from LAN and from gateway itself to pass
# 'self' is a pf reserved word for all addresses assigned to interfaces on the
# local host.
pass proto tcp from self

# Here's the main rule allowing traffic from the local LAN to
# the internet. We modify this by changing the bedtime anchor
# via external tools. E.g.: echo "..." | pfctl -a bedtime -f -
anchor bedtime {
	# the default "awake" rule, bedtime not enforced
	pass proto tcp from <leased_ips>
}
