#!/bin/sh

# https://www.freebsd.org/doc/handbook/firewalls-ipfw.html
# ipfw -vated list

# IPFW configuration
#sysrc firewall_enable="YES"
#sysrc firewall_logif="YES"
#sysrc firewall_script="/mnt/config/ipfw.rules"

# NATd configuration
#sysrc gateway_enable="YES"
#sysrc natd_enable="YES"
#sysrc natd_interface="tun1"
#sysrc natd_flags="-f /mnt/config/natd.conf"
#natd.conf: redirect_port tcp 192.168.0.9:80 80

# Set rules command prefix
cmd="ipfw -q add"
lif="epair0b" # interface name of VNET attached to Local network
rif="tun0" # interface name of Tunnel attached to Remote network
skip="skipto 12000"

# Flush out the list before we begin.
ipfw -q -f flush

# gateway_enable already set in rc.conf
# sysctl net.inet.ip.forwarding=1

# Packets passing the stateful NAT may be re-injected into the firewall
# sysctl net.inet.ip.fw.one_pass=0
ipfw disable one_pass

# functionality is included in the divert action
#ipfw -q nat 1 config if $rif same_ports unreg_only reset

$cmd 00050 allow ip from any to any via $lif

$cmd 00100 allow ip from any to any via lo0

$cmd 00200 deny ip from any to 127.0.0.0/8
$cmd 00300 deny ip from 127.0.0.0/8 to any
$cmd 00400 deny ip from any to ::1
$cmd 00500 deny ip from ::1 to any

$cmd 00600 allow ipv6-icmp from :: to ff02::/16
$cmd 00700 allow ipv6-icmp from fe80::/10 to fe80::/10
$cmd 00800 allow ipv6-icmp from fe80::/10 to ff02::/16
$cmd 00900 allow ipv6-icmp from any to any icmp6types 1
$cmd 01000 allow ipv6-icmp from any to any icmp6types 2,135,136

# The reassemble rule is not needed with userland natd(8)
# because the internal workings of the IPFW divert action
# takes care of reassembling packets before delivery to the socket
#$cmd 01100 reass all from any to any in

$cmd 01200 divert natd ip from any to any in via $rif     # NAT any inbound packets

# Allow the packet through if it has an existing entry in the dynamic rules table
$cmd 01300 check-state

# Allow access to DNS
#$cmd 02110 $skip tcp from any to 192.168.0.5 53 out via $rif setup keep-state
#$cmd 02111 $skip udp from any to 192.168.0.5 53 out via $rif keep-state
#$cmd 02112 $skip tcp from any to fd01::5 53 out via $rif setup keep-state
#$cmd 02113 $skip udp from any to fd01::5 53 out via $rif keep-state

# Allow access to ISP's DHCP server for cable/DSL configurations.
# Use the first rule and check log for IP address.
# Then, uncomment the second rule, input the IP address, and delete the first rule
#$cmd 02120 $skip log udp from any to any 67 out via $rif keep-state
#$cmd 02120 $skip udp from any to x.x.x.x 67 out via $rif keep-state

# Allow outbound ping
$cmd 02210 $skip icmp from any to any out via $rif keep-state

# Allow outbound NTP
#$cmd 02220 $skip udp from any to any 123 out via $rif keep-state

# Allow outbound TCP traffic
$cmd 02500 $skip tcp from any to any 22,80,443,2024,3389,5904 out via $rif setup keep-state

# deny and log all other outbound connections
$cmd 02999 deny log all from any to any out via $rif

#### Lockdown incoming traffic
# Deny all inbound traffic from non-routable reserved address spaces
#$cmd 03110 deny all from 192.168.0.0/16 to any in via $rif     #RFC 1918 private IP
#$cmd 03111 deny all from 172.16.0.0/12 to any in via $rif      #RFC 1918 private IP
#$cmd 03112 deny all from 10.0.0.0/8 to any in via $rif         #RFC 1918 private IP
$cmd 03113 deny all from 127.0.0.0/8 to any in via $rif        #loopback
$cmd 03114 deny all from 0.0.0.0/8 to any in via $rif          #loopback
$cmd 03115 deny all from 169.254.0.0/16 to any in via $rif     #DHCP auto-config
$cmd 03116 deny all from 192.0.2.0/24 to any in via $rif       #reserved for docs
$cmd 03117 deny all from 204.152.64.0/23 to any in via $rif    #Sun cluster interconnect
$cmd 03118 deny all from 224.0.0.0/3 to any in via $rif        #Class D & E multicast

# Allow traffic from ISP's DHCP server.
# Replace x.x.x.x with the same IP address used in rule 02120.
#$cmd 03120 allow udp from any to x.x.x.x 67 in via $rif keep-state

# Deny public pings
#$cmd 03210 deny icmp from any to any in via $rif

# Deny ident
$cmd 03230 deny tcp from any to any 113 in via $rif

# Deny all Netbios services.
$cmd 03240 deny { tcp or udp } from any to any 81,137-139,445,1026,1027,1433,1434 in via $rif

# Deny fragments
$cmd 03250 deny all from any to any frag in via $rif

# Deny ACK packets that did not match the dynamic rule table
$cmd 03500 deny tcp from any to any established in via $rif

# Allow inbound SSH connections
#$cmd 03610 allow tcp from any to me 22 in via $rif setup limit src-addr 2

# Allow HTTP connections to internal web server
#$cmd 03620 allow tcp from any to me 80 in via $rif setup limit src-addr 2

# Reject and log all other incoming connections
$cmd 03999 deny log all from any to any in via $rif
#### lockdown in

$cmd 12000 divert natd ip from any to any out via $rif # skipto location for outbound stateful rules

$cmd 65000 allow ip from any to any

#$cmd 65535 deny ip from any to any
