Last active
August 10, 2023 04:47
-
-
Save TGion/3012105dd4a97fd24d29cd0c61661370 to your computer and use it in GitHub Desktop.
Different BSD packet filter (pf) rule snippets - IPv4 only
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ext_if = "vtnet0" # Our external interface. | |
vpn_if = "wg0" # Wireguard interface | |
gsd_if = "wg-gsd" # Wireguard GSD interface | |
# TCP ports allowed for external / public interface. | |
TCP_EXT_OK = "{ domain-s, http, https, docsrv }" | |
UDP_EXT_OK = "{ domain-s, wireguard }" | |
# Stateful TCP options. | |
TCP_STATE = "flags S/FSRA keep state" | |
# TCP ports allowed outbound | |
# TCP_OUT_OK = "{ domain-s, http, https, smtps, imaps, ssh }" | |
# UDP ports allowed outbound | |
# UDP_OUT_OK = "{ domain-s, ntp }" | |
# IPv6 link local prefix. | |
#PFX_LNKLOC = "FE80::/10" | |
# IPv6 Solicited Node Multicast Prefix. | |
#MC_SOLNOD = "FF02::1:FF00:0/104" | |
# IPv6 All Nodes Link Local Multicast Address. | |
#MC_NODLNK = "FF02::1" | |
# IPv6 All Routers Link Local Multicast Address. | |
#MC_RTRLNK = "FF02::2" | |
### TABLES ### | |
# Non-routable adresses - should be ignored by me | |
table <martians> const { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \ | |
172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \ | |
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \ | |
240.0.0.0/4 255.255.255.255/32 } | |
# Abusers are added to this table, which is flushed after 24h | |
# IPs in this table have low bandwith assigned | |
table <flooders> persist counters | |
# Imported abusers table | |
# IPs in this table are blocked | |
# pf-badhost - https://geoghegan.ca/pub/pf-badhost/latest/install/freebsd.txt | |
table <pfbadhost> persist file "/etc/pf.badhost" | |
# table <pfgoodhost> persist file "/etc/pf.goodhost" # pf-goodhost - Hosts should always be allowed - careful | |
table <home> persist { fritzbox.gion.io } # DDNS Clients with priority access (e.g. FritzBox) | |
table <sslabs> const { 64.41.200.0/24 64.39.109.20 104.130.202.77 } # Allow servers from SSLabs more connection requests | |
# Crowdsec bouncer | |
table <crowdsec-blacklists> persist | |
# table <crowdsec6-blacklists> persist | |
### OPTIONS ### | |
set skip on lo0 | |
set block-policy drop | |
set loginterface $ext_if | |
set limit table-entries 400000 | |
### NORMALIZATION ### | |
scrub in all no-df fragment reassemble max-mss 1440 # Scrub for all incoming packets | |
scrub out all random-id # Randomize the ID field for all outgoing packets | |
### QUEUEING ### | |
altq on $ext_if cbq bandwidth 50Mb queue { q_default q_flooders } | |
queue q_default bandwidth 99% cbq(default borrow) | |
queue q_flooders bandwidth 1% | |
### TRANSLATION ### | |
nat on $ext_if from !($ext_if) -> ($ext_if) # Wireguard | |
antispoof quick for $ext_if # Apparently a good thing | |
### FILTERING ### | |
block all # By default all traffic is blocked and NOT logged unless explicitly stated otherwise. | |
pass in quick log on $ext_if proto tcp from { <home> } to port $TCP_EXT_OK $TCP_STATE queue q_default # More liberate access from inside home network | |
pass in quick log on $ext_if proto udp from { <home> } to port $UDP_EXT_OK queue q_default | |
pass in quick log on $vpn_if to any $TCP_STATE queue q_default # Allow traffic from Wireguard interface - no restrictions | |
block in quick log on $ext_if from { <martians>, <pfbadhost>, <crowdsec-blacklists> } label "block.in" # Block traffic from/to forbidden addresses. | |
block out quick log on $ext_if to { <martians>, <pfbadhost>, <crowdsec-blacklists> } label "block.out" # Block traffic from/to forbidden addresses. | |
block in quick log on $ext_if from { no-route, urpf-failed } # Block bogus incoming traffic. | |
pass in quick log on $ext_if proto udp to port $UDP_EXT_OK queue q_default # Allow access to services - UDP | |
pass in quick log on $ext_if proto tcp from { <flooders> } to port $TCP_EXT_OK $TCP_STATE queue q_flooders | |
pass in quick log on $ext_if proto udp from { <flooders> } to port $UDP_EXT_OK queue q_flooders # Allow access to services - <badhosts> - ALTQ - minimum bandwith TCP and UDP | |
pass in quick log on $ext_if proto tcp from { <sslabs> } to port { https } $TCP_STATE queue q_default # Allow SSLabs to hammer port 443 for scanning | |
# TODO: Add priority queue for ALTQ | |
pass in quick log on $ext_if proto tcp to port $TCP_EXT_OK $TCP_STATE \ | |
(max-src-conn 100, max-src-conn-rate 30/1, \ | |
overload <flooders> flush global) \ | |
queue q_default # General rule for all TCP access | |
# Allow traffic from home - should be get highest priority with ALTQ | |
# pass in quick on $ext_if proto tcp from { <dns:fritz> } to port $TCP_EXT_OK $TCP_STATE queue q_default | |
# pass in quick on $ext_if proto udp from { <dns:fritz> } to port $UDP_EXT_OK queue q_default | |
# Allow NS from unspecified to solicited node multicast address (DAD). | |
# pass quick inet6 proto icmp6 from :: to $MC_SOLNOD icmp6-type neighbrsol no state | |
pass quick inet proto udp from 0.0.0.0 port bootpc to 255.255.255.255 port bootps no state # Allow BOOTP/DHCP DISCOVER. | |
# Allow IPv6 Router Discovery (RA in / RS out). | |
# pass in quick inet6 proto icmp6 from $PFX_LNKLOC to $MC_NODLNK icmp6-type routeradv no state | |
# pass out quick inet6 proto icmp6 from ($ext_if) to $MC_RTRLNK icmp6-type routersol no state | |
# Allow IPv6 Neighbor Discovery (ND/NUD/DAD). | |
# pass in quick inet6 proto icmp6 from { $PFX_LNKLOC, ($ext_if:network) } to { ($ext_if), $MC_SOLNOD } icmp6-type neighbrsol no state | |
# pass in quick inet6 proto icmp6 from { $PFX_LNKLOC, ($ext_if:network) } to { ($ext_if), $MC_NODLNK } icmp6-type neighbradv no state | |
# pass out quick inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv } no state | |
# pass inet6 proto ipv6-icmp all icmp6-type neighbradv | |
# pass quick inet6 proto icmp6 icmp6-type echoreq | |
pass quick inet proto icmp icmp-type echoreq # Allow ping/ping6 in both directions (in/out). | |
pass out on $ext_if to any queue q_default # Allow all outbound traffic (for now) | |
pass out on $vpn_if to any queue q_default # vpn wg0 | |
pass out on $gsd_if to any queue q_default # vpn wg-gsd | |
# Allow outbound traffic through restricted ports | |
# pass out log on $ext_if proto tcp to port $TCP_OUT_OK $TCP_STATE | |
# pass out log on $ext_if proto udp to port $UDP_OUT_OK |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment