January 2009
This is an annotated example of a home PF setup under OpenBSD (on a Soekris 5501.
###################
### Definitions ###
###################
# Of NICs
ctl_if="sis0"
wan_if="sis1"
intranet_if="sis2"
datanet_if="sis3"
dmz_if="vr0"
localhost_if="lo0"
# Of attached networks
wan=$wan_if:network
datanet=$datanet_if:network
intranet=$intranet_if:network
dmz=$dmz_if:network
localhost=$localhost_if:network
# Some groupings of NICs
local_ifs="{" $ctl_if $intranet_if $datanet_if $dmz_if "}"
dhcp_ifs="{" $intranet_if $datanet_if $dmz_if "}"
ssh_ifs="{" $intranet_if "}"
# Some groupings of ports
client_out_tcp = "{ ftp-data, ftp, http, https, imaps, ntp, pop3, smtp, smtps, ssh }"
client_out_udp = "{ domain, ntp, tftp }"
intranet_windows_ports = "{ microsoft-ds, netbios-ns, netbios-dgm, netbios-ssn }"
# Some settings for port redirections
lenin=10.0.12.200
hosts_allowed_ssh_to_lenin="{ 130.89.40.71 }"
##############
### Tables ###
##############
table <bruteforce> persist
###################################
### Normalization and rewriting ###
###################################
scrub in all
################
### Queueing ###
################
# Define a high-priority queue in addition to a default
altq on $wan_if priq bandwidth 1800Kb queue { q_pri, q_def }
queue q_pri priority 7
queue q_def priority 1 priq(default)
###########
### NAT ###
###########
# SNAT on datanet
nat on $wan_if from $datanet to any -> ($wan_if:0)
# SNAT on intranet too
nat on $wan_if from $intranet to any -> ($wan_if:0)
# Traffic destined for inside the network shouldn't be directed out of course
no nat on $wan_if from $intranet to $intranet
no nat on $wan_if from $intranet to no-route
# FTP and TFTP are proxied, not NATted
no nat on $wan_if to port { tftp, ftp }
# There are proxies running on these ports
rdr on $datanet_if proto udp from $datanet to any port tftp -> 127.0.0.1 port 6969
rdr on $intranet_if proto udp from $intranet to any port tftp -> 127.0.0.1 port 6969
rdr on $datanet_if proto tcp from $datanet to any port ftp -> 127.0.0.1 port 8021
rdr on $intranet_if proto tcp from $intranet to any port ftp -> 127.0.0.1 port 8021
# Redirect ssh incoming from a few permitted hosts to Lenin on intranet
rdr log on $wan_if proto tcp from $hosts_allowed_ssh_to_lenin to $wan_if:0 port ssh -> $lenin
# The anchors for the proxies to insert their own rules
nat-anchor "tftp-proxy/*"
rdr-anchor "tftp-proxy/*"
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
#################
### Filtering ###
#################
# No need for localhost traffic to be checked
set skip on $localhost
# No funny packets are allowed to come in with outgoing addresses and the like
antispoof for $wan_if
antispoof for $datanet_if
antispoof for $localhost_if
# Block everything by default
block log all
# Misbehaving machines are blocked by IP
block quick from <bruteforce>
# We trust the loopback
pass log quick on $localhost_if
# Ssh is redirected but blocked unless we allow it in here
# Trial-and-error bruteforcers try about once a second, so will be caught
pass in on $wan_if inet proto tcp from $hosts_allowed_ssh_to_lenin to $lenin port ssh flags S/SA keep state \
(max-src-conn 40, max-src-conn-rate 5/10, overload <bruteforce> flush global)
# And we should allow it through on the inside interface as well
# Note that thsi and the previous rule can be removed if we attach the "pass" keyword to the redirect rule above
pass out on $intranet_if inet proto tcp from $hosts_allowed_ssh_to_lenin to $lenin port ssh
# Allow ping out (but don't allow it in from WAN)
pass out on $wan_if inet proto icmp all icmp-type echoreq queue ( q_def, q_pri )
# Allow some services to be used, but not all
pass out log on $wan_if inet proto tcp to any port $client_out_tcp queue ( q_def, q_pri )
pass out log on $wan_if inet proto udp to any port $client_out_udp queue ( q_def, q_pri )
# Don't allow ssh from intranet to the firewall
#pass in log on $intranet_if inet proto tcp from $intranet to 10.0.12.1 port ssh
# Allow some Windows protocols within intranet
pass log on $intranet_if proto tcp from $intranet to $intranet port $intranet_windows_ports
# Allow any contact within intranet
pass log on $intranet_if from $intranet to $intranet
anchor "tftp-proxy/*"
anchor "ftp-proxy/*"
################
### Comments ###
################