FreeBSD IPFW rules for WireGuard
Usage
You've installed WireGuard on FreeBSD EC2 server - now we need to configure IPFW rules correctly.
Scripts
/etc/rc.conf
Make sure the following is present in /etc/rc.conf
firewall_enable="YES"firewall_nat_enable="YES"firewall_script="/usr/local/etc/IPFW.rules"firewall_logging="YES"
We can use the following commands to make sure /etc/rc.conf
has all of the required parameters:
sed -i -E 's/firewall_enable=.*//g' /etc/rc.confsed -i -E 's/firewall_nat_enable=.*//g' /etc/rc.confsed -i -E 's/firewall_script=.*//g' /etc/rc.confsed -i -E 's/firewall_logging=.*//g' /etc/rc.confsed -i -E 's/gateway_enable=.*//g' /etc/rc.conf
printf %b\\n "gateway_enable=\"YES\"firewall_enable=\"YES\"firewall_nat_enable=\"YES\"firewall_script=\"/usr/local/etc/IPFW.rules\"firewall_logging=\"YES\"" | tee -a /etc/rc.conf >/dev/null
sysctl
We need the following options set
# Disable TCP segmentation offloading to use in-kernel NAT# See 30.4.4. In-kernel NAT in https://www.freebsd.org/doc/handbook/firewalls-ipfw.html$ sudo sed -i -E 's/net.inet.tcp.tso=.*//g' /etc/sysctl.conf$ sudo printf %b\\n "net.inet.tcp.tso=0" | tee -a /etc/sysctl.conf >/dev/null$ sudo sysctl net.inet.tcp.tso="0"
#Enable IP forwarding$ sudo sysctl net.inet.ip.forwarding="1"
/usr/local/etc/IPFW.rules
Use the following for a firewall config template. Pay attention to vif
, ssh_port
, pub_dns
, wg_port
and wg_subnet
varibles, they will be unique to your setup.
#!/bin/sh
# ipfw config/rules# from FBSD Handbook, rc.firewall, et. al.
# Flush all rules before we begin.ipfw -q -f flush
# Set rules command prefixcmd="ipfw -q add "# Internet-facing ifacevif="xn0"# Used for outboud NAT rulesskip="skipto 1000"# sshd portssh_port="22"
#### WG-specific Options ##### DNS Serverpub_dns="1.1.1.1"# Listen Portwg_port="9201"# Subnetwg_subnet="10.10.0.0/24"
# Wireguard interface, matching the name in /etc/wireguard/*.confwg_iface="wg0"
# Allow NATipfw disable one_passipfw -q nat 1 config if $vif same_ports unreg_only reset
# allow all for localhost$cmd 00010 allow ip from any to any via lo0$cmd 00011 allow ip from any to any via $wg_iface
# NAT-specifig rules$cmd 00099 reass all from any to any in # reassamble inbound packets$cmd 00100 nat 1 ip from any to any in via $vif # NAT any inbound packets
# checks stateful rules. If marked as "keep-state" the packet has# already passed through filters and is "OK" without futher# rule matching$cmd 00101 check-state
# allow DNS out$cmd 00110 $skip tcp from any to $pub_dns dst-port 53 out via $vif setup keep-state$cmd 00111 $skip udp from any to $pub_dns dst-port 53 out via $vif keep-state
# allow dhclient connection out (port numbers are important)$cmd 00120 $skip udp from me 68 to any dst-port 67 out via $vif keep-state
# allow HTTP HTTPS replies$cmd 00200 $skip tcp from any to any dst-port 80 out via $vif setup keep-state$cmd 00220 $skip tcp from any to any dst-port 443 out via $vif setup keep-state
# allow outbound mail$cmd 00230 $skip tcp from any to any dst-port 25 out via $vif setup keep-state$cmd 00231 $skip tcp from any to any dst-port 465 out via $vif setup keep-state$cmd 00232 $skip tcp from any to any dst-port 587 out via $vif setup keep-state
# allow WG$cmd 00233 $skip udp from any to any src-port $wg_port out via $vif keep-state$cmd 00234 $skip udp from $wg_subnet to any out via $vif keep-state$cmd 00235 $skip tcp from $wg_subnet to any out via $vif setup keep-state
# allow icmp re: ping, et. al. # comment this out to disable ping, et.al.$cmd 00250 $skip icmp from any to any out via $vif keep-state
# alllow timeserver out$cmd 00260 $skip tcp from any to any dst-port 37 out via $vif setup keep-state
# allow ntp out$cmd 00270 $skip udp from any to any dst-port 123 out via $vif keep-state
# allow outbound SSH traffic$cmd 00280 $skip tcp from any to any dst-port 22 out via $vif setup keep-state
# otherwise deny outbound packets# outbound catchall. $cmd 00299 deny log ip from any to any out via $vif
# inbound rules# deny inbound traffic to restricted addresses$cmd 00300 deny ip from 192.168.0.0/16 to any in via $vif$cmd 00301 deny all from 172.16.0.0/12 to any in via $vif #RFC 1918 private IP$cmd 00302 deny ip from 10.0.0.0/8 to any in via $vif$cmd 00303 deny ip from 127.0.0.0/8 to any in via $vif$cmd 00304 deny ip from 0.0.0.0/8 to any in via $vif$cmd 00305 deny ip from 169.254.0.0/16 to any in via $vif$cmd 00306 deny ip from 192.0.2.0/24 to any in via $vif$cmd 00307 deny ip from 204.152.64.0/23 to any in via $vif$cmd 00308 deny ip from 224.0.0.0/3 to any in via $vif
# deny inbound packets on these ports# auth 113, netbios (services) 137/138/139, hosts-nameserver 81 $cmd 00315 deny tcp from any to any dst-port 113 in via $vif$cmd 00320 deny tcp from any to any dst-port 137 in via $vif$cmd 00321 deny tcp from any to any dst-port 138 in via $vif$cmd 00322 deny tcp from any to any dst-port 139 in via $vif$cmd 00323 deny tcp from any to any dst-port 81 in via $vif
# deny partial packets$cmd 00330 deny ip from any to any frag in via $vif$cmd 00332 deny tcp from any to any established in via $vif
# allowing icmp re: ping, etc.$cmd 00310 allow icmp from any to any in via $vif
# allowing inbound mail, dhcp, http, https
$cmd 00370 allow udp from any 67 to me dst-port 68 in via $vif keep-state
# allow inbound ssh, mail. PROTECTED SERVICES: numbered ABOVE sshguard blacklist range $cmd 700 allow tcp from any to me dst-port $ssh_port in via $vif setup limit src-addr 2$cmd 702 allow udp from any to any dst-port $wg_port in via $vif keep-state
# deny everything else, and log it# inbound catchall$cmd 999 deny log ip from any to any in via $vif
# NAT$cmd 1000 nat 1 ip from any to any out via $vif # skipto location for outbound stateful rules$cmd 1001 allow ip from any to any
# ipfw built-in default, don't uncomment# $cmd 65535 deny ip from any to any
Enable IPFW
$ sudo service ipfw start