This article will detail how to configure an IPv4 only router and secure it with PF firewall.
Both router interfaces will be protected from inbound connections directly to the router itself, while allowing all outbound Internet routed traffic to pass through.
Configure System Startup
Configure the network interfaces, enable routing, and enable PF firewall by adding the following to /etc/rc.conf:
ifconfig_re0="SYNCDHCP" ifconfig_re1="inet 192.0.2.1 netmask 255.255.255.0" gateway_enable="YES" # PF pf_enable="YES" pf_rules="/etc/pf.conf" pflog_enable="YES" pflog_logfile="/var/log/pflog"
Configure the PF firewall rules
Edit /etc/pf.conf
#### Macros #### ext_if = re0 int_if = re1
either_if ="{ re0, re1 }"
neither_if ="{ ! re0, ! re1 }" # ICMP Types icmp_types = "{ echorep }" # Private and documentation example networks priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 255.255.255.255/32 }" doc_example_nets = "{ 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 }" #### Options #### set block-policy drop set skip on lo0 # Scrub scrub on $ext_if all no-df random-id fragment reassemble # NAT nat on $ext_if from 192.0.2.0/24 -> ($ext_if) #### Block #### block log all # Antispoof antispoof quick log for $ext_if block in on $ext_if from { urpf-failed, no-route } block in quick log on $ext_if from { $priv_nets, $doc_example_nets } # Block ICMP Port Unreachable Messages to Prevent and Mitigate DDOS and Other Attacks i.e. SAD DNS block out quick log on $ext_if inet proto icmp icmp-type unreach code port-unr
block out quick log on $ext_if inet proto icmp icmp-type unreach code proto-unr #### Allow #### # Allow routed traffic in on internal interface pass in on $int_if to $neither_if flags any # Allow all traffic out both interfaces pass out flags any # ICMP
pass in on $int_if inet proto icmp pass in on $ext_if proto icmp all icmp-type $icmp_types
### Inbound Services ###
# SSH
pass in on $int_if proto tcp to $int_if port ssh
Note: When PF loads the ruleset into memory it automatically appends keep state to all valid pass rules. If the rule is a TCP pass rule then flags S/SA keep state is appended. For example:
pass in on $ext_if proto tcp to port http
is written into memory as:
pass in on re0 proto tcp from any to any port = http flags S/SA keep state
Reboot the system watching the console for any errors during startup.
Login and confirm that you can access external Internet hosts.