FreeBSD as Router/Firewall
BASIC FREEBSD CONFIGURATION
# install same commonly used
pkg install vim bash sudo htop tree xauth wget curl nmap git cpuid pftop bind-tools sysutils/bsdinfo lsof freecolor lscpu bwm-ng dmidecode
pkg install dnsmasq tailscale vnstat radvd
# OpenBSD Packet Filter (PF) & ALTQ
kldload pf.ko
service pf enable
service pflog enable
service pfsync enable
/boot/loader.conf
bridge_load="YES"
NETWORK INTERFACES & SERVICE
/etc/rc.conf
hostname="gw.example.net"
defaultrouter="10.11.1.1"
ifconfig_igc0="inet 10.11.1.254/24"
ifconfig_igc1="inet 10.20.0.1/16"
gateway_enable="YES"
ipv6_privacy="YES"
ifconfig_igc0_ipv6="inet6 accept_rtadv"
ifconfig_igc1_ipv6="inet6 xxxx:xxxx::1/64"
ipv6_gateway_enable="YES"
ipv6_defaultrouter="fe80::1%igc0"
netwait_enable="YES"
netwait_if="igc0"
sshd_enable="YES"
ntpd_enable="YES"
ntpd_sync_on_start="YES"
pf_enable="YES"
pflog_enable="YES"
pfsync_enable="YES"
dnsmasq_enable="YES"
vnstat_enable="YES"
tailscaled_enable="YES"
rtsold_enable="YES"
radvd_enable="YES"
kld_list="tcp_rack tcp_bbr"
/usr/local/etc/radvd.conf
interface igc1 {
AdvSendAdvert on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
AdvDefaultPreference medium;
AdvManagedFlag off;
AdvOtherConfigFlag off;
prefix ::/64 {
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
AdvPreferredLifetime 3600;
AdvValidLifetime 7200;
};
route ::/0 {
AdvRoutePreference medium;
AdvRouteLifetime 1800;
};
RDNSS xxxx:xxxx::1 {
AdvRDNSSLifetime 3600;
};
DNSSL example.net {
AdvDNSSLLifetime 3600;
};
};
ROUTING
/etc/rc.conf
# routing
static_routes="asus"
route_asus="192.168.33.0/24 192.168.33.1"
service routing restart
PF SETUP
/etc/pf.conf
#################################
#### Packet Firewall Ruleset ####
#################################
#### Variables ####
ext_if="igc0"
int_if="igc1"
# Set allowed ICMP types
icmp_types = "{ 0, 3, 4, 8, 11, 12, 134 }"
icmp6_types = "{1,2,3,4,128,129,133,134,135,136,137}"
# Allow inbound traffic ports
in_ports = "{ 22, 80, 443, 8118, 8388, 8389 }"
# Internal networks
internal_nets = "{ 10.20.0.0/16, 10.21.0.0/16 10.22.1.0/16, 192.168.3.0/24 }"
#### Options and Optimizations #######
set loginterface $ext_if
set skip on lo0
set optimization aggressive
set block-policy return
scrub on $ext_if all no-df fragment reassemble
#### NAT Settings ####
nat on $ext_if from $int_if:network to any -> ($ext_if)
nat on $ext_if inet6 from $int_if:network to any -> ($ext_if)
#### Firewall Configuration #######
# ipv6
pass in on $int_if inet6 all
pass out on $int_if inet6 all
# pass in on $ext_if inet6 proto icmp6 all
pass in on $ext_if inet6 all
pass out on $ext_if inet6 all
#### Rules inbound (int_if) ####
# Allow all traffic on internal interfaces
pass in log on $int_if from $int_if:network to any
#### Rules outbound (int_if) ####
# Allow all traffic outbound from internal interfaces
pass out log on $int_if from any to any
#### Rules inbound (ext_if) ####
# Allow inbound traffic on external interface for specific services
pass in log on $ext_if inet proto {tcp, udp} to ($ext_if) port $in_ports
pass in log on $ext_if inet6 proto {tcp, udp} to ($ext_if) port $in_ports
# Allow ICMP
pass in quick on $ext_if inet proto icmp all icmp-type $icmp_types
pass in quick proto icmp6 all keep state
pass out quick proto icmp6 all keep state
#### Rules outbound (ext_if) ####
# Allow outbound traffic from the external interface
pass out log on $ext_if from any to any
# tailscale
pass in quick on tailscale0 proto udp from any to any port 41641
pass out quick on tailscale0 proto { udp, tcp } from any to { 100.100.100.100, 100.73.97.124 } port 53
pfctl -f /etc/pf.conf
check pflog
tcpdump -n -e -ttt -i pflog0
tshark -i pflog0 -f "src net (10.20.0.0/16 or 192.168.31.0/24) and (tcp port 80 or tcp port 443)"
tshark -i pflog0 -f "src net (10.20.0.0/16 or 192.168.31.0/24) and (tcp port 80 or tcp port 443)" -T fields -e frame.time -e ip.src -e ip.dst -e tcp.dstport -e http.host -e tls.handshake.extensions_server_name
KERNEL && FORWARDING
/etc/sysctl.conf
# forwarding
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
# set autotuning maximum to at least 16MB too
net.inet.tcp.sendbuf_max=16777216
net.inet.tcp.recvbuf_max=16777216
net.inet.tcp.sendbuf_auto=1
net.inet.tcp.recvbuf_auto=1
kern.ipc.maxsockbuf=16777216
kern.ipc.nmbclusters=988914
net.inet.tcp.sendbuf_inc=16384
# socket max connect
kern.ipc.somaxconn=32768
# ack delayed
net.inet.tcp.delayed_ack=1
kern.ipc.nmbjumbop=247228
net.inet.tcp.cc.algorithm=cubic
net.inet.udp.recvspace=2097152
net.inet.icmp.icmplim=300
net.inet.tcp.msl=2000
net.inet.tcp.fast_finwait2_recycle=1
net.inet.ip.intr_queue_maxlen=4096
net.inet.tcp.functions_default=bbr
net.inet6.icmp6.errppslimit=1000
/boot/loader.conf
tcp_bbr_load="YES"
autoboot_delay="3"
coretemp_load="YES"
net.isr.maxthreads=4
net.isr.bindthreads=0
net.inet.tcp.syncache.hashsize="2048"
net.inet.tcp.syncache.bucketlimit="128"
DNSMASQ
/usr/local/etc/dnsmasq.conf
bind-interfaces
port=53
except-interface=igc0
no-dhcp-interface=lo
conf-dir=/usr/local/etc/dnsmasq.d
# Log
log-queries
log-dhcp
log-facility=/var/log/dnsmasq/dnsmasq.log
log-async=120
# Domain & Hosts
local=/example.net/
domain=example.net
address=/.example.net/10.20.0.1
# expand-hosts
no-hosts
expand-hosts
addn-hosts=/usr/local/etc/dnsmasq.hosts
# option:ntp-server
dhcp-option=42,10.20.0.1
# DNS
all-servers
# dnssec
# strict-order
# cache-size=1048576
cache-size=4096
max-cache-ttl=86400
min-cache-ttl=60
resolv-file=/usr/local/etc/dnsmasq.resolv.conf
# strict-order
dns-forward-max=512
localise-queries
# bogus-priv
# bogus-nxdomain=39.156.66.10
dns-loop-detect
server=223.5.5.5
/usr/local/etc/dnsmasq.d/dhcp.conf
# optimization sort
dhcp-authoritative
dhcp-rapid-commit
dhcp-ignore-clid
# dhcp-leasefile=/var/db/dnsmasq.leases
# dhcpd
interface=igc1
dhcp-option=option:domain-search,example.net
dhcp-range=10.20.2.1,10.20.5.254,48h
# gateway
dhcp-option=1,255.255.0.0 # option:subnet-mask
dhcp-option=3,10.20.0.1 # option:router
dhcp-option=6,10.20.0.1 # option:dns-server
dhcp-option=15,example.net # option:domain-name
dhcp-option=28,10.20.255.255 # option:broadcast
# bypass
dhcp-option=tag:bypass,3,10.20.0.3
## bypass host
dhcp-host=xx:xx:xx:xx:xx:xx,set:bypass
# static hosts
dhcp-host=wifi-master,xx:xx:xx:xx:xx:xx,10.20.0.166,infinite
/usr/local/etc/dnsmasq.resolv.conf
server=10.20.0.1
server=114.114.114.114
server=/cn/114.114.114.114
/usr/local/etc/dnsmasq.hosts
10.20.0.1 gw.example.net example.net wpad.example.net
/etc/dnsmasq.d/adblock-for-dnsmasq.conf github.com/privacy-protection-tools/anti-AD.git
wget https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/adblock-for-dnsmasq.conf -O /etc/dnsmasq.d/adblock-for-dnsmasq.conf
VNSTAT
mkdir -p /var/db/vnstat/
chown -R vnstat:vnstat /var/db/vnstat
service vnstat enable
service vnstat start
TEMPERATURE
kldload coretemp
echo 'coretemp_load="YES"' >> /boot/loader.conf
echo 'sysctl -a | grep temperature' > /usr/local/bin/sensors
chmod +x /usr/local/bin/sensors
REFERENCE
https://github.com/shaojing1779/ufrt/blob/main/docs/freebsd-rt.md