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 ### ################