version=pmwiki-2.2.130 ordered=1 urlencoded=1 agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 author=miniontoby charset=UTF-8 csum= ctime=1609294740 host=77.168.188.164 name=Openbsd.PFStable rev=31 targets=Openbsd.Netadmin,Openbsd.Buyvm,Openbsd.Vmmuser,Openbsd.Tcpdump,Openbsd.SYNFlood,Openbsd.Ilines,Openbsd.Ntpd,Openbsd.Nsd,Openbsd.Sshbackdoor,Openbsd.Iked,Openbsd.Pf,Openbsd.Ddos text=(:title Sample PF for Stable:)%0a%0a'''NOTE''': This guide is '''no''' substitute for reading the [[https://www.openbsd.org/faq/pf|Packet Filter Guide]]. In particular, you must read the Basic Configuration section and the [[openbsd/netadmin|NetAdmin Code]].%0a%0a!! Ruleset with Explanation%0a%0aHere's a sample /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers). We include a rule-by-rule explanation. For the complete ruleset (without commentary), see the next section.%0a%0a[@%0aExtIf = "vio0"%0aIP4 = "10.0.0.1"%0aUnIP4 = "192.168.0.1"%0aIP6 = "2001:db8::/80"%0a@]%0a%0aExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmuser|VMM]] users), IP4 is your DDoS-filtered IPv4 address, UnIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a%0a[@%0aFlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes 200, max-src-states 200)"%0aFlush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 500/10 overload %3cbadhosts> flush global)"%0aFlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-rate 50/10 overload %3cbadhosts> flush global)"%0a@]%0a%0aThis defines 3 macros.%0a%0aFor FlushUDP, if the packet rate exceeds 10000 packets per 10 seconds, PF will refuse to process any further packets. It will keep track of state for ICMP and UDP packets; if there are more than 1000 state entries, it will stop accepting new packets. If there are more than 200 unique IPs in the state entry table, or if a single IP has more than 200 entries, it will stop accepting new connections.%0a%0aFor Flush, if there are 1000 state entries, it will stop accepting new connections. If there are more than 200 unique IPs in the state entry table, or if a single IP makes more than 500 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a%0aFlushStrict is the same but more strict. If there are 100 state entries, it will stop accepting new connections. If there are more than 20 unique IPs in the state entry table, or if a single IP makes more than 50 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a%0a[@%0aset skip on lo0%0aset loginterface $ExtIf%0a#set ruleset-optimization profile%0aset syncookies adaptive (start 25%25, end 12%25)%0a@]%0a%0aWe skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can view these using [[openbsd/tcpdump|tcpdump]] in /var/log/pflog*. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/SYNFlood|synflood]] attacks.%0a%0a[@%0atable %3cilines> persist file "/etc/pf/ilines"%0atable %3cbadhosts> persist file "/etc/pf/badhosts"%0a@]%0a%0aWe load two tables, one with [[openbsd/ilines|ilines]] (with IRCNow-approved IPs), and another with a list of '''badhosts''' (known criminals and enemies).%0a%0a[@%0ablock in log quick from %3cbadhosts>%0apass in log quick proto udp to {$IP4 $IP6} port domain $FlushUDP%0apass in log quick proto udp to {$UnIP4 $IP6} port ntp $FlushUDP%0apass in log quick proto udp to {$IP4 $IP6} port {isakmp ipsec-nat-t} $FlushUDP%0ablock in log quick proto udp to {$IP4 $IP6}%0ablock in log quick from urpf-failed%0amatch in log all scrub (no-df random-id max-mss 1440)%0a@]%0a%0aWe immediately block all packets from '''badhosts'''. We pass in all DNS UDP packets on the DDoS-filtered IPv4 and IPv6 subnet (but not the secret unfiltered IPv4 address). We pass in all NTP UDP packets for the unfiltered IPv4 address and IPv6 subnet, but not the DDoS-filtered IPv4 address because NTP packets get mangled by DDoS-filtering.%0a%0a'''WARNING''': Please follow the [[openbsd/ntpd|ntpd guide]] to set it up properly -- if you do not, your system's time will be wrong, causing all sorts of hard to troubleshoot problems like issues with [[openbsd/nsd|nsd]].%0a%0a[@%0apass in log quick on $ExtIf inet proto icmp icmp-type 8 code 0 $FlushUDP # icmp packets%0apass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag (MTU)%0apass in log quick on $ExtIf proto ipv6-icmp $FlushUDP%0a@]%0a%0aWe allow in ICMP and ICMPv6 packets passing through our external interface. '''NOTE''': Do '''not''' block ICMP packets, or else strange and hard to diagnose problems can occur. For example, blocking ICMPv6 packets can interfere with proper IPv6 routing.%0a%0a[@%0apass in log quick proto tcp to {$IP4 $IP6} port domain $Flush%0apass in log quick proto tcp to {$IP4 $IP6} port auth $Flush%0apass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 pop3s} $Flush%0apass in log quick proto tcp to {$IP4 $IP6} port {gopher http https} $Flush%0apass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } #irc%0apass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } $Flush #irc%0apass in log quick proto tcp to {$IP4 $IP6} port { 1314 13140 1337 31337 } $Flush #bnc%0apass in log quick proto tcp to {$IP4 $IP6} port { 12742 29173 } $Flush #wraith%0apass in log quick proto tcp to {$IP4 $IP6} port 7777 $Flush #paster%0apass in log quick proto tcp to {$IP4 $UnIP4 $IP6} port ssh $FlushStrict%0a@]%0a%0aWe immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's for DNS (domain), ident (auth), sending mail (smtp submission smtps), reading mail (imap imaps pop3 pop3s), gopher, the web (http https).%0a%0aIf the sender is present on our ilines, we pass in all IRC traffic without normal Flush limits. If not, we have normal Flush limits.%0a%0aWe immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's headed for the bouncer, wraith, or the paster.%0a%0aFor ssh, we allow incoming packets to the secret, unfiltered IPv4 address and we apply more strict rules to prevent bruteforce attacks. The unfiltered IPv4 address will provide a [[openbsd/sshbackdoor|hidden backdoor]] to access the server in case of a DDoS attack.%0a%0a[@%0a# road warrior vpn%0apass in log inet proto udp to {$IP4 $IP6} port {isakmp, ipsec-nat-t} tag IKED%0apass in log inet proto esp to {$IP4 $IP6} tag IKED%0apass log on enc0 inet tagged ROADW%0amatch out log on $ExtIf inet tagged ROADW nat-to $IP4%0amatch in log quick on enc0 inet proto { tcp, udp } to port 53 rdr-to 127.0.0.1 port 53%0a@]%0a%0aThis section is for IPSec VPNs using [[openbsd/iked|iked]].%0a%0a[@%0ablock in log all%0ablock out log on $UnIP4%0apass out quick from {$IP4 $IP6} # allow non-spoofed packets%0apass out quick proto tcp from $UnIP4 to port ssh%0apass out quick proto udp from $UnIP4 to port ntp%0apass out quick proto {udp tcp} from $UnIP4 to port {domain}%0apass out quick inet proto icmp from $UnIP4 # allow ICMP%0a@]%0a%0aWe block all incoming packets but '''not''' immediately. By default, if the '''quick''' keyword is missing, the last rule that matches applies to a packet. We then block all outgoing packets from the secret, unfiltered IPv4 address except whitelisted traffic for ssh, ntp, dns, and ICMP packets.%0a%0a!! Complete Ruleset%0a%0aHere's the /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers) without any commentary:%0a%0a[@%0aExtIf = "vio0"%0aIP4 = "10.0.0.1"%0aUnIP4 = "192.168.0.1"%0aIP6 = "2001:db8::/80"%0aFlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes 200, max-src-states 200)"%0aFlush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 500/10 overload %3cbadhosts> flush global)"%0aFlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-rate 50/10 overload %3cbadhosts> flush global)"%0a%0aset skip on lo0%0aset loginterface $ExtIf%0a#set ruleset-optimization profile%0aset syncookies adaptive (start 25%25, end 12%25)%0a%0atable %3cilines> persist file "/etc/pf/ilines"%0atable %3cbadhosts> persist file "/etc/pf/badhosts"%0a%0a# udp and icmp%0ablock in log quick from %3cbadhosts>%0apass in log quick proto udp to {$IP4 $IP6} port domain $FlushUDP%0apass in log quick proto udp to {$UnIP4 $IP6} port ntp $FlushUDP%0apass in log quick proto udp to {$IP4 $IP6} port {isakmp ipsec-nat-t} $FlushUDP%0ablock in log quick proto udp to {$IP4 $IP6}%0ablock in log quick from urpf-failed%0amatch in log all scrub (no-df random-id max-mss 1440)%0apass in log quick on $ExtIf inet proto icmp icmp-type 8 code 0 $FlushUDP # icmp packets%0apass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag (MTU)%0apass in log quick on $ExtIf proto ipv6-icmp $FlushUDP%0a# tcp%0apass in log quick proto tcp to {$IP4 $IP6} port domain $Flush%0apass in log quick proto tcp to {$IP4 $IP6} port auth $Flush%0apass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 pop3s} $Flush%0apass in log quick proto tcp to {$IP4 $IP6} port {gopher http https} $Flush%0apass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } #irc%0apass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } $Flush #irc%0apass in log quick proto tcp to {$IP4 $IP6} port { 1314 13140 1337 31337 } $Flush #bnc%0apass in log quick proto tcp to {$IP4 $IP6} port 29173 $Flush #wraith%0apass in log quick proto tcp to {$IP4 $IP6} port 7777 $Flush #paster%0apass in log quick proto tcp to {$IP4 $UnIP4 $IP6} port ssh $FlushStrict%0a%0a# road warrior vpn%0apass in log inet proto udp to {$IP4 $IP6} port {isakmp, ipsec-nat-t} tag IKED%0apass in log inet proto esp to {$IP4 $IP6} tag IKED%0apass log on enc0 inet tagged ROADW%0amatch out log on $ExtIf inet tagged ROADW nat-to $IP4%0amatch in log quick on enc0 inet proto { tcp, udp } to port 53 rdr-to 127.0.0.1 port 53%0a%0ablock in log all%0ablock out log on $UnIP4%0apass out quick from {$IP4 $IP6} # allow non-spoofed packets%0apass out quick proto tcp from $UnIP4 to port ssh%0apass out quick proto udp from $UnIP4 to port ntp%0apass out quick proto {udp tcp} from $UnIP4 to port {domain}%0apass out quick inet proto icmp from $UnIP4 # allow ICMP%0a@]%0a%0aYou will then need to create a folder:%0a%0a[@%0a$ doas mkdir /etc/pf/%0a@]%0a%0aThen, add the list of [[openbsd/ilines|ilines]] to /etc/pf/ilines.%0a%0a[@%0a198.251.89.130%0a198.251.83.183%0a209.141.39.184%0a209.141.39.228%0a198.251.84.240%0a198.251.80.229%0a198.251.81.119%0a209.141.39.173%0a198.251.89.91%0a198.251.81.44%0a209.141.38.137%0a198.251.81.133%0a2605:6400:0030:f8de::/64%0a2605:6400:0010:071b::/64%0a2605:6400:0020:0434::/64%0a2605:6400:0020:00b4::/64%0a2605:6400:0010:05bf::/64%0a2605:6400:0030:fc15::/64%0a2605:6400:0020:1290::/64%0a2605:6400:0020:0bb8::/64%0a2605:6400:0030:faa1::/64%0a2605:6400:0010:069d::/64%0a2605:6400:0020:05cc::/64%0a2605:6400:0010:00fe::/64%0a@]%0a%0aAfterwards, any badhosts can be added to /etc/pf/badhosts:%0a%0a[@%0a0.0.0.0/8%0a127.0.0.0/8%0a169.254.0.0/16%0a172.16.0.0/12%0a192.0.0.0/24%0a192.0.2.0/24%0a224.0.0.0/3%0a192.168.0.0/16%0a198.18.0.0/15%0a198.51.100.0/24%0a203.0.113.0/24%0a@]%0a%0aThese are all reserved IPs and no authentic traffic should come from these source IPs. Note that we deliberately leave out 10.0.0.0/8 because we will use this subnet for IPSec.%0a%0aTo load the new configuration:%0a%0a[@%0a$ doas pfctl -f /etc/pf.conf%0a@]%0a%0a!! Troubleshooting%0a%0a'''WARNING''': When you apply new firewall rules, '''make sure''' to test that all services are working after the rules have been applied. If you do not test, you might break something for users and not notice it for days or weeks!%0a%0aTo test, connect to each and every one of the services you provide, both from your home IP address and another proxy (vpn, vps) that you have.%0a%0aPlease also set aside 24-48 hours to monitor any bug reports from users.%0a%0a!! See Also%0a%0a|| [[openbsd/pf|PF Guide]] || [[openbsd/ddos|DDoS Filtering Guide]] || [[openbsd/tcpdump|tcpdump]] ||%0a time=1632497293 title=Sample PF for Stable author:1632497293=miniontoby diff:1632497293:1621206957:=64c64,65%0a%3c pass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag (MTU)%0a---%0a> pass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag%0a> (MTU)%0a144c145,146%0a%3c pass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag (MTU)%0a---%0a> pass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag%0a> (MTU)%0a host:1632497293=77.168.188.164 author:1621206957=jrmu diff:1621206957:1619703735:=80d79%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port 7777 $Flush #paster%0a88,89c87,88%0a%3c We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's headed for the bouncer, wraith, or the paster.%0a%3c %0a---%0a> We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's headed for the bouncer or wraith.%0a> %0a157d155%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port 7777 $Flush #paster%0a245c243%0a%3c || [[openbsd/pf|PF Guide]] || [[openbsd/ddos|DDoS Filtering Guide]] || [[openbsd/tcpdump|tcpdump]] ||%0a---%0a> || [[openbsd/pf|PF Guide]] || [[openbsd/ddos|DDoS Filtering Guide]] || [[openbsd/tcpdump|tcpdump]] ||%0a\ No newline at end of file%0a host:1621206957=38.81.163.143 author:1619703735=jrmu diff:1619703735:1612701835:=16c16%0a%3c ExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmuser|VMM]] users), IP4 is your DDoS-filtered IPv4 address, UnIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a---%0a> ExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmusers|VMM]] users), IP4 is your DDoS-filtered IPv4 address, UnIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a host:1619703735=198.251.81.119 author:1612701835=jrmu diff:1612701835:1611849771:=12c12%0a%3c UnIP4 = "192.168.0.1"%0a---%0a> IntIP4 = "192.168.0.1"%0a16,17c16,17%0a%3c ExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmusers|VMM]] users), IP4 is your DDoS-filtered IPv4 address, UnIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a%3c %0a---%0a> ExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmusers|VMM]] users), IP4 is your DDoS-filtered IPv4 address, IntIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a> %0a51c51%0a%3c pass in log quick proto udp to {$UnIP4 $IP6} port ntp $FlushUDP%0a---%0a> pass in log quick proto udp to {$IntIP4 $IP6} port ntp $FlushUDP%0a80c80%0a%3c pass in log quick proto tcp to {$IP4 $UnIP4 $IP6} port ssh $FlushStrict%0a---%0a> pass in log quick proto tcp to {$IP4 $IntIP4 $IP6} port ssh $FlushStrict%0a104c104%0a%3c block out log on $UnIP4%0a---%0a> block out log on $IntIP4%0a106,109c106,109%0a%3c pass out quick proto tcp from $UnIP4 to port ssh%0a%3c pass out quick proto udp from $UnIP4 to port ntp%0a%3c pass out quick proto {udp tcp} from $UnIP4 to port {domain}%0a%3c pass out quick inet proto icmp from $UnIP4 # allow ICMP%0a---%0a> pass out quick proto tcp from $IntIP4 to port ssh%0a> pass out quick proto udp from $IntIP4 to port ntp%0a> pass out quick proto {udp tcp} from $IntIP4 to port {domain}%0a> pass out quick inet proto icmp from $IntIP4 # allow ICMP%0a121c121%0a%3c UnIP4 = "192.168.0.1"%0a---%0a> IntIP4 = "192.168.0.1"%0a138c138%0a%3c pass in log quick proto udp to {$UnIP4 $IP6} port ntp $FlushUDP%0a---%0a> pass in log quick proto udp to {$IntIP4 $IP6} port ntp $FlushUDP%0a156,157c156,157%0a%3c pass in log quick proto tcp to {$IP4 $UnIP4 $IP6} port ssh $FlushStrict%0a%3c %0a---%0a> pass in log quick proto tcp to {$IP4 $IntIP4 $IP6} port ssh $FlushStrict%0a> %0a166c166%0a%3c block out log on $UnIP4%0a---%0a> block out log on $IntIP4%0a168,171c168,171%0a%3c pass out quick proto tcp from $UnIP4 to port ssh%0a%3c pass out quick proto udp from $UnIP4 to port ntp%0a%3c pass out quick proto {udp tcp} from $UnIP4 to port {domain}%0a%3c pass out quick inet proto icmp from $UnIP4 # allow ICMP%0a---%0a> pass out quick proto tcp from $IntIP4 to port ssh%0a> pass out quick proto udp from $IntIP4 to port ntp%0a> pass out quick proto {udp tcp} from $IntIP4 to port {domain}%0a> pass out quick inet proto icmp from $IntIP4 # allow ICMP%0a host:1612701835=198.251.81.119 author:1611849771=jrmu diff:1611849771:1609501291:=79c79%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 12742 29173 } $Flush #wraith%0a---%0a> pass in log quick proto tcp to {$IP4 $IP6} port 29173 $Flush #wraith%0a host:1611849771=125.231.24.226 author:1609501291=jrmu diff:1609501291:1609500859:=213,214c213,214%0a%3c 127.0.0.0/8%0a%3c 169.254.0.0/16%0a---%0a> 127.0.0.0/8 %0a> 169.254.0.0/16 %0a217,218c217,218%0a%3c 192.0.2.0/24%0a%3c 224.0.0.0/3%0a---%0a> 192.0.2.0/24 %0a> 224.0.0.0/3 %0a220,221c220,221%0a%3c 198.18.0.0/15%0a%3c 198.51.100.0/24%0a---%0a> 198.18.0.0/15 %0a> 198.51.100.0/24 %0a host:1609501291=198.251.81.119 author:1609500859=jrmu diff:1609500859:1609470430:=209,225c209%0a%3c Afterwards, any badhosts can be added to /etc/pf/badhosts:%0a%3c %0a%3c [@%0a%3c 0.0.0.0/8%0a%3c 127.0.0.0/8 %0a%3c 169.254.0.0/16 %0a%3c 172.16.0.0/12%0a%3c 192.0.0.0/24%0a%3c 192.0.2.0/24 %0a%3c 224.0.0.0/3 %0a%3c 192.168.0.0/16%0a%3c 198.18.0.0/15 %0a%3c 198.51.100.0/24 %0a%3c 203.0.113.0/24%0a%3c @]%0a%3c %0a%3c These are all reserved IPs and no authentic traffic should come from these source IPs. Note that we deliberately leave out 10.0.0.0/8 because we will use this subnet for IPSec.%0a---%0a> Afterwards, any badhosts can be added to /etc/pf/badhosts.%0a host:1609500859=198.251.81.119 author:1609470430=jrmu diff:1609470430:1609332077:=5,8c5,6%0a%3c !! Ruleset with Explanation%0a%3c %0a%3c Here's a sample /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers). We include a rule-by-rule explanation. For the complete ruleset (without commentary), see the next section.%0a%3c %0a---%0a> Here's a sample /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers). See the Comments section below for a rule-by-rule explanation:%0a> %0a14,18d11%0a%3c @]%0a%3c %0a%3c ExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmusers|VMM]] users), IP4 is your DDoS-filtered IPv4 address, IntIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a%3c %0a%3c [@%0a22,32c15%0a%3c @]%0a%3c %0a%3c This defines 3 macros.%0a%3c %0a%3c For FlushUDP, if the packet rate exceeds 10000 packets per 10 seconds, PF will refuse to process any further packets. It will keep track of state for ICMP and UDP packets; if there are more than 1000 state entries, it will stop accepting new packets. If there are more than 200 unique IPs in the state entry table, or if a single IP has more than 200 entries, it will stop accepting new connections.%0a%3c %0a%3c For Flush, if there are 1000 state entries, it will stop accepting new connections. If there are more than 200 unique IPs in the state entry table, or if a single IP makes more than 500 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a%3c %0a%3c FlushStrict is the same but more strict. If there are 100 state entries, it will stop accepting new connections. If there are more than 20 unique IPs in the state entry table, or if a single IP makes more than 50 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a%3c %0a%3c [@%0a---%0a> %0a37,41c20%0a%3c @]%0a%3c %0a%3c We skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can view these using [[openbsd/tcpdump|tcpdump]] in /var/log/pflog*. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/SYNFlood|synflood]] attacks.%0a%3c %0a%3c [@%0a---%0a> %0a44,48c23,24%0a%3c @]%0a%3c %0a%3c We load two tables, one with [[openbsd/ilines|ilines]] (with IRCNow-approved IPs), and another with a list of '''badhosts''' (known criminals and enemies).%0a%3c %0a%3c [@%0a---%0a> %0a> # udp and icmp%0a56,62d31%0a%3c @]%0a%3c %0a%3c We immediately block all packets from '''badhosts'''. We pass in all DNS UDP packets on the DDoS-filtered IPv4 and IPv6 subnet (but not the secret unfiltered IPv4 address). We pass in all NTP UDP packets for the unfiltered IPv4 address and IPv6 subnet, but not the DDoS-filtered IPv4 address because NTP packets get mangled by DDoS-filtering.%0a%3c %0a%3c '''WARNING''': Please follow the [[openbsd/ntpd|ntpd guide]] to set it up properly -- if you do not, your system's time will be wrong, causing all sorts of hard to troubleshoot problems like issues with [[openbsd/nsd|nsd]].%0a%3c %0a%3c [@%0a67,71c36%0a%3c @]%0a%3c %0a%3c We allow in ICMP and ICMPv6 packets passing through our external interface. '''NOTE''': Do '''not''' block ICMP packets, or else strange and hard to diagnose problems can occur. For example, blocking ICMPv6 packets can interfere with proper IPv6 routing.%0a%3c %0a%3c [@%0a---%0a> # tcp%0a81,91c46%0a%3c @]%0a%3c %0a%3c We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's for DNS (domain), ident (auth), sending mail (smtp submission smtps), reading mail (imap imaps pop3 pop3s), gopher, the web (http https).%0a%3c %0a%3c If the sender is present on our ilines, we pass in all IRC traffic without normal Flush limits. If not, we have normal Flush limits.%0a%3c %0a%3c We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's headed for the bouncer or wraith.%0a%3c %0a%3c For ssh, we allow incoming packets to the secret, unfiltered IPv4 address and we apply more strict rules to prevent bruteforce attacks. The unfiltered IPv4 address will provide a [[openbsd/sshbackdoor|hidden backdoor]] to access the server in case of a DDoS attack.%0a%3c %0a%3c [@%0a---%0a> %0a98,102c53%0a%3c @]%0a%3c %0a%3c This section is for IPSec VPNs using [[openbsd/iked|iked]].%0a%3c %0a%3c [@%0a---%0a> %0a112,117c63,64%0a%3c We block all incoming packets but '''not''' immediately. By default, if the '''quick''' keyword is missing, the last rule that matches applies to a packet. We then block all outgoing packets from the secret, unfiltered IPv4 address except whitelisted traffic for ssh, ntp, dns, and ICMP packets.%0a%3c %0a%3c !! Complete Ruleset%0a%3c %0a%3c Here's the /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers) without any commentary:%0a%3c %0a---%0a> You will then need to create a folder:%0a> %0a118a66,116%0a> $ doas mkdir /etc/pf/%0a> @]%0a> %0a> Then, add the list of [[openbsd/ilines|ilines]] to /etc/pf/ilines.%0a> %0a> [@%0a> 198.251.89.130%0a> 198.251.83.183%0a> 209.141.39.184%0a> 209.141.39.228%0a> 198.251.84.240%0a> 198.251.80.229%0a> 198.251.81.119%0a> 209.141.39.173%0a> 198.251.89.91%0a> 198.251.81.44%0a> 209.141.38.137%0a> 198.251.81.133%0a> 2605:6400:0030:f8de::/64%0a> 2605:6400:0010:071b::/64%0a> 2605:6400:0020:0434::/64%0a> 2605:6400:0020:00b4::/64%0a> 2605:6400:0010:05bf::/64%0a> 2605:6400:0030:fc15::/64%0a> 2605:6400:0020:1290::/64%0a> 2605:6400:0020:0bb8::/64%0a> 2605:6400:0030:faa1::/64%0a> 2605:6400:0010:069d::/64%0a> 2605:6400:0020:05cc::/64%0a> 2605:6400:0010:00fe::/64%0a> @]%0a> %0a> Afterwards, any badhosts can be added to /etc/pf/badhosts.%0a> %0a> To load the new configuration:%0a> %0a> [@%0a> $ doas pfctl -f /etc/pf.conf%0a> @]%0a> %0a> !! Troubleshooting%0a> %0a> '''WARNING''': When you apply new firewall rules, '''make sure''' to test that all services are working after the rules have been applied. If you do not test, you might break something for users and not notice it for days or weeks!%0a> %0a> To test, connect to each and every one of the services you provide, both from your home IP address and another proxy (vpn, vps) that you have.%0a> %0a> Please also set aside 24-48 hours to monitor any bug reports from users.%0a> %0a> !! Comments%0a> %0a> [@%0a122a121,125%0a> @]%0a> %0a> ExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmusers|VMM]] users), IP4 is your DDoS-filtered IPv4 address, IntIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a> %0a> [@%0a126c129,139%0a%3c %0a---%0a> @]%0a> %0a> This defines 3 macros.%0a> %0a> For FlushUDP, if the packet rate exceeds 10000 packets per 10 seconds, PF will refuse to process any further packets. It will keep track of state for ICMP and UDP packets; if there are more than 1000 state entries, it will stop accepting new packets. If there are more than 200 unique IPs in the state entry table, or if a single IP has more than 200 entries, it will stop accepting new connections.%0a> %0a> For Flush, if there are 1000 state entries, it will stop accepting new connections. If there are more than 200 unique IPs in the state entry table, or if a single IP makes more than 500 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a> %0a> FlushStrict is the same but more strict. If there are 100 state entries, it will stop accepting new connections. If there are more than 20 unique IPs in the state entry table, or if a single IP makes more than 50 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a> %0a> [@%0a131c144,148%0a%3c %0a---%0a> @]%0a> %0a> We skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can view these using [[openbsd/tcpdump|tcpdump]] in /var/log/pflog*. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/SYNFlood|synflood]] attacks.%0a> %0a> [@%0a134,135c151,155%0a%3c %0a%3c # udp and icmp%0a---%0a> @]%0a> %0a> We load two tables, one with [[openbsd/ilines|ilines]] (with IRCNow-approved IPs), and another with a list of '''badhosts''' (known criminals and enemies).%0a> %0a> [@%0a142a163,169%0a> @]%0a> %0a> We immediately block all packets from '''badhosts'''. We pass in all DNS UDP packets on the DDoS-filtered IPv4 and IPv6 subnet (but not the secret unfiltered IPv4 address). We pass in all NTP UDP packets for the unfiltered IPv4 address and IPv6 subnet, but not the DDoS-filtered IPv4 address because NTP packets get mangled by DDoS-filtering.%0a> %0a> '''WARNING''': Please follow the [[openbsd/ntpd|ntpd guide]] to set it up properly -- if you do not, your system's time will be wrong, causing all sorts of hard to troubleshoot problems like issues with [[openbsd/nsd|nsd]].%0a> %0a> [@%0a147c174,178%0a%3c # tcp%0a---%0a> @]%0a> %0a> We allow in ICMP and ICMPv6 packets passing through our external interface. '''NOTE''': Do '''not''' block ICMP packets, or else strange and hard to diagnose problems can occur. For example, blocking ICMPv6 packets can interfere with proper IPv6 routing.%0a> %0a> [@%0a157c188,198%0a%3c %0a---%0a> @]%0a> %0a> We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's for DNS (domain), ident (auth), sending mail (smtp submission smtps), reading mail (imap imaps pop3 pop3s), gopher, the web (http https).%0a> %0a> If the sender is present on our ilines, we pass in all IRC traffic without normal Flush limits. If not, we have normal Flush limits.%0a> %0a> We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's headed for the bouncer or wraith.%0a> %0a> For ssh, we allow incoming packets to the secret, unfiltered IPv4 address and we apply more strict rules to prevent bruteforce attacks. The unfiltered IPv4 address will provide a [[openbsd/sshbackdoor|hidden backdoor]] to access the server in case of a DDoS attack.%0a> %0a> [@%0a164c205,209%0a%3c %0a---%0a> @]%0a> %0a> This section is for IPSec VPNs using [[openbsd/iked|iked]].%0a> %0a> [@%0a174,223c219%0a%3c You will then need to create a folder:%0a%3c %0a%3c [@%0a%3c $ doas mkdir /etc/pf/%0a%3c @]%0a%3c %0a%3c Then, add the list of [[openbsd/ilines|ilines]] to /etc/pf/ilines.%0a%3c %0a%3c [@%0a%3c 198.251.89.130%0a%3c 198.251.83.183%0a%3c 209.141.39.184%0a%3c 209.141.39.228%0a%3c 198.251.84.240%0a%3c 198.251.80.229%0a%3c 198.251.81.119%0a%3c 209.141.39.173%0a%3c 198.251.89.91%0a%3c 198.251.81.44%0a%3c 209.141.38.137%0a%3c 198.251.81.133%0a%3c 2605:6400:0030:f8de::/64%0a%3c 2605:6400:0010:071b::/64%0a%3c 2605:6400:0020:0434::/64%0a%3c 2605:6400:0020:00b4::/64%0a%3c 2605:6400:0010:05bf::/64%0a%3c 2605:6400:0030:fc15::/64%0a%3c 2605:6400:0020:1290::/64%0a%3c 2605:6400:0020:0bb8::/64%0a%3c 2605:6400:0030:faa1::/64%0a%3c 2605:6400:0010:069d::/64%0a%3c 2605:6400:0020:05cc::/64%0a%3c 2605:6400:0010:00fe::/64%0a%3c @]%0a%3c %0a%3c Afterwards, any badhosts can be added to /etc/pf/badhosts.%0a%3c %0a%3c To load the new configuration:%0a%3c %0a%3c [@%0a%3c $ doas pfctl -f /etc/pf.conf%0a%3c @]%0a%3c %0a%3c !! Troubleshooting%0a%3c %0a%3c '''WARNING''': When you apply new firewall rules, '''make sure''' to test that all services are working after the rules have been applied. If you do not test, you might break something for users and not notice it for days or weeks!%0a%3c %0a%3c To test, connect to each and every one of the services you provide, both from your home IP address and another proxy (vpn, vps) that you have.%0a%3c %0a%3c Please also set aside 24-48 hours to monitor any bug reports from users.%0a---%0a> We block all incoming packets but '''not''' immediately. By default, if the '''quick''' keyword is missing, the last rule that matches applies to a packet. We then block all outgoing packets from the secret, unfiltered IPv4 address except whitelisted traffic for ssh, ntp, dns, and ICMP packets.%0a host:1609470430=198.251.81.119 author:1609332077=jrmu diff:1609332077:1609331006:=105,112d104%0a%3c %0a%3c !! Troubleshooting%0a%3c %0a%3c '''WARNING''': When you apply new firewall rules, '''make sure''' to test that all services are working after the rules have been applied. If you do not test, you might break something for users and not notice it for days or weeks!%0a%3c %0a%3c To test, connect to each and every one of the services you provide, both from your home IP address and another proxy (vpn, vps) that you have.%0a%3c %0a%3c Please also set aside 24-48 hours to monitor any bug reports from users.%0a host:1609332077=198.251.81.119 author:1609331006=jrmu diff:1609331006:1609330964:=57,58c57%0a%3c pass out quick proto tcp from $IntIP4 to port ssh%0a%3c pass out quick proto udp from $IntIP4 to port ntp%0a---%0a> pass out quick proto tcp from $IntIP4 to port {ssh ntp}%0a205,206c204%0a%3c pass out quick proto tcp from $IntIP4 to port ssh%0a%3c pass out quick proto udp from $IntIP4 to port ntp%0a---%0a> pass out quick proto tcp from $IntIP4 to port {ssh ntp}%0a host:1609331006=198.251.81.119 author:1609330964=jrmu diff:1609330964:1609330938:=57c57%0a%3c pass out quick proto tcp from $IntIP4 to port {ssh ntp}%0a---%0a> pass out quick proto tcp from $IntIP4 to port ssh%0a host:1609330964=198.251.81.119 author:1609330938=jrmu diff:1609330938:1609330893:=209c209%0a%3c We block all incoming packets but '''not''' immediately. By default, if the '''quick''' keyword is missing, the last rule that matches applies to a packet. We then block all outgoing packets from the secret, unfiltered IPv4 address except whitelisted traffic for ssh, ntp, dns, and ICMP packets.%0a---%0a> We block all incoming packets but '''not''' immediately. By default, if the '''quick''' keyword is missing, the last rule that matches applies to a packet. We then block all outgoing packets from the secret, unfiltered IPv4 address except whitelisted traffic for ssh domain queries%0a host:1609330938=198.251.81.119 author:1609330893=jrmu diff:1609330893:1609329879:=137,138c137,138%0a%3c We skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can view these using [[openbsd/tcpdump|tcpdump]] in /var/log/pflog*. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/SYNFlood|synflood]] attacks.%0a%3c %0a---%0a> We skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/SYNFlood|synflood]] attacks.%0a> %0a204c204%0a%3c pass out quick proto tcp from $IntIP4 to port {ssh ntp}%0a---%0a> pass out quick proto tcp from $IntIP4 to port ssh%0a208,209d207%0a%3c %0a%3c We block all incoming packets but '''not''' immediately. By default, if the '''quick''' keyword is missing, the last rule that matches applies to a packet. We then block all outgoing packets from the secret, unfiltered IPv4 address except whitelisted traffic for ssh domain queries%0a host:1609330893=198.251.81.119 author:1609329879=jrmu diff:1609329879:1609329539:=172c172,173%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 pop3s} $Flush%0a---%0a> pass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 p%0a> op3s} $Flush%0a174,175c175,178%0a%3c pass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } #irc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } $Flush #irc%0a---%0a> pass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000%0a> 9999 16667 16697 } #irc%0a> pass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16%0a> 697 } $Flush #irc%0a181,187c184%0a%3c We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's for DNS (domain), ident (auth), sending mail (smtp submission smtps), reading mail (imap imaps pop3 pop3s), gopher, the web (http https).%0a%3c %0a%3c If the sender is present on our ilines, we pass in all IRC traffic without normal Flush limits. If not, we have normal Flush limits.%0a%3c %0a%3c We immediately pass in all TCP packets for the public IPv4 address and IPv6 subnet if it's headed for the bouncer or wraith.%0a%3c %0a%3c For ssh, we allow incoming packets to the secret, unfiltered IPv4 address and we apply more strict rules to prevent bruteforce attacks. The unfiltered IPv4 address will provide a [[openbsd/sshbackdoor|hidden backdoor]] to access the server in case of a DDoS attack.%0a---%0a> We allow%0a host:1609329879=198.251.81.119 author:1609329539=jrmu diff:1609329539:1609329326:=160d159%0a%3c [@%0a165,169c164%0a%3c @]%0a%3c %0a%3c We allow in ICMP and ICMPv6 packets passing through our external interface. '''NOTE''': Do '''not''' block ICMP packets, or else strange and hard to diagnose problems can occur. For example, blocking ICMPv6 packets can interfere with proper IPv6 routing.%0a%3c %0a%3c [@%0a---%0a> # tcp%0a182,186c177%0a%3c @]%0a%3c %0a%3c We allow%0a%3c %0a%3c [@%0a---%0a> %0a193,197c184%0a%3c @]%0a%3c %0a%3c This section is for IPSec VPNs using [[openbsd/iked|iked]].%0a%3c %0a%3c [@%0a---%0a> %0a204c191%0a%3c @]%0a---%0a> %0a host:1609329539=198.251.81.119 author:1609329326=jrmu diff:1609329326:1609329124:=156,158c156%0a%3c We immediately block all packets from '''badhosts'''. We pass in all DNS UDP packets on the DDoS-filtered IPv4 and IPv6 subnet (but not the secret unfiltered IPv4 address). We pass in all NTP UDP packets for the unfiltered IPv4 address and IPv6 subnet, but not the DDoS-filtered IPv4 address because NTP packets get mangled by DDoS-filtering.%0a%3c %0a%3c '''WARNING''': Please follow the [[openbsd/ntpd|ntpd guide]] to set it up properly -- if you do not, your system's time will be wrong, causing all sorts of hard to troubleshoot problems like issues with [[openbsd/nsd|nsd]].%0a---%0a> We immediately block all packets from '''badhosts'''%0a host:1609329326=198.251.81.119 author:1609329124=jrmu diff:1609329124:1609328928:=144,145c144,145%0a%3c We load two tables, one with [[openbsd/ilines|ilines]] (with IRCNow-approved IPs), and another with a list of '''badhosts''' (known criminals and enemies).%0a%3c %0a---%0a> We load two tables, one with ilines (with IRCNow-approved IPs), and another with a list of badhosts (known criminals and enemies).%0a> %0a146a147%0a> # udp and icmp%0a155,156d155%0a%3c %0a%3c We immediately block all packets from '''badhosts'''%0a host:1609329124=198.251.81.119 author:1609328928=jrmu diff:1609328928:1609328423:=139d138%0a%3c [@%0a142,146c141%0a%3c @]%0a%3c %0a%3c We load two tables, one with ilines (with IRCNow-approved IPs), and another with a list of badhosts (known criminals and enemies).%0a%3c %0a%3c [@%0a---%0a> %0a155,156d149%0a%3c @]%0a%3c %0a host:1609328928=198.251.81.119 author:1609328423=jrmu diff:1609328423:1609328369:=3c3,21%0a%3c '''NOTE''': This guide is '''no''' substitute for reading the [[https://www.openbsd.org/faq/pf|Packet Filter Guide]]. In particular, you must read the Basic Configuration section and the [[openbsd/netadmin|NetAdmin Code]].%0a---%0a> '''NOTE''': This guide is '''no''' substitute for reading the [[https://www.openbsd.org/faq/pf|Packet Filter Guide]]. In particular, you must read the Basic Configuration section.%0a> %0a> [@%0a> Repeat after me:%0a> %0a> This is my network. %0a> %0a> It is mine %0a> technically it belongs to WE THE USERS%0a> it is my responsibility %0a> and I care for it with all my heart%0a> %0a> there are many other networks a lot like mine,%0a> but none are just like it.%0a> %0a> I will not mindlessly paste from HOWTOs.%0a> @]%0a> %0a> (Based on [[https://bsdly.blogspot.com/2011/01/i-will-not-mindlessly-paste-from-howtos.html]])%0a host:1609328423=198.251.81.119 author:1609328369=jrmu diff:1609328369:1609328346:=6,7d5%0a%3c Repeat after me:%0a%3c %0a host:1609328369=198.251.81.119 author:1609328346=jrmu diff:1609328346:1609328098:=4,19d3%0a%3c %0a%3c [@%0a%3c This is my network. %0a%3c %0a%3c It is mine %0a%3c technically it belongs to WE THE USERS%0a%3c it is my responsibility %0a%3c and I care for it with all my heart%0a%3c %0a%3c there are many other networks a lot like mine,%0a%3c but none are just like it.%0a%3c %0a%3c I will not mindlessly paste from HOWTOs.%0a%3c @]%0a%3c %0a%3c (Based on [[https://bsdly.blogspot.com/2011/01/i-will-not-mindlessly-paste-from-howtos.html]])%0a host:1609328346=198.251.81.119 author:1609328098=jrmu diff:1609328098:1609328021:=137c137%0a%3c We skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/SYNFlood|synflood]] attacks.%0a---%0a> We skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/synflood|synflood]] attacks.%0a host:1609328098=198.251.81.119 author:1609328021=jrmu diff:1609328021:1609327950:=5c5%0a%3c Here's a sample /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers). See the Comments section below for a rule-by-rule explanation:%0a---%0a> Here's a sample /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers):%0a host:1609328021=198.251.81.119 author:1609327950=jrmu diff:1609327950:1609327811:=2,3d1%0a%3c %0a%3c '''NOTE''': This guide is '''no''' substitute for reading the [[https://www.openbsd.org/faq/pf|Packet Filter Guide]]. In particular, you must read the Basic Configuration section.%0a host:1609327950=198.251.81.119 author:1609327811=jrmu diff:1609327811:1609327575:=16c16%0a%3c #set ruleset-optimization profile%0a---%0a> set ruleset-optimization profile%0a126,128c126%0a%3c FlushStrict is the same but more strict. If there are 100 state entries, it will stop accepting new connections. If there are more than 20 unique IPs in the state entry table, or if a single IP makes more than 50 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a%3c %0a%3c [@%0a---%0a> %0a131c129%0a%3c #set ruleset-optimization profile%0a---%0a> set ruleset-optimization profile%0a133,135d130%0a%3c @]%0a%3c %0a%3c We skip filtering on loopback (localhost). We are going to log all packets that pass through the external interface vio0. You can optionally optimize the ruleset based on the profile, but I have not yet tested to see if the optimization is intelligent, so I left it commented out. We will use syncookies to defend against [[openbsd/synflood|synflood]] attacks.%0a host:1609327811=198.251.81.119 author:1609327575=jrmu diff:1609327575:1609327314:=10,13c10,16%0a%3c FlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes 200, max-src-states 200)"%0a%3c Flush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 500/10 overload %3cbadhosts> flush global)"%0a%3c FlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-rate 50/10 overload %3cbadhosts> flush global)"%0a%3c %0a---%0a> FlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes%0a> 200, max-src-states 200)"%0a> Flush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 5%0a> 00/10 overload %3cbadhosts> flush global)"%0a> FlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-ra%0a> te 50/10 overload %3cbadhosts> flush global)"%0a> %0a37c40,41%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 pop3s} $Flush%0a---%0a> pass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 p%0a> op3s} $Flush%0a39,40c43,46%0a%3c pass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } #irc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16697 } $Flush #irc%0a---%0a> pass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000%0a> 9999 16667 16697 } #irc%0a> pass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16%0a> 697 } $Flush #irc%0a114,125c120,125%0a%3c [@%0a%3c FlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes 200, max-src-states 200)"%0a%3c Flush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 500/10 overload %3cbadhosts> flush global)"%0a%3c FlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-rate 50/10 overload %3cbadhosts> flush global)"%0a%3c @]%0a%3c %0a%3c This defines 3 macros.%0a%3c %0a%3c For FlushUDP, if the packet rate exceeds 10000 packets per 10 seconds, PF will refuse to process any further packets. It will keep track of state for ICMP and UDP packets; if there are more than 1000 state entries, it will stop accepting new packets. If there are more than 200 unique IPs in the state entry table, or if a single IP has more than 200 entries, it will stop accepting new connections.%0a%3c %0a%3c For Flush, if there are 1000 state entries, it will stop accepting new connections. If there are more than 200 unique IPs in the state entry table, or if a single IP makes more than 500 connections in 10 seconds, it will disconnect all connections from this user and add them to the table '''badhosts'''.%0a%3c %0a---%0a> FlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes%0a> 200, max-src-states 200)"%0a> Flush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 5%0a> 00/10 overload %3cbadhosts> flush global)"%0a> FlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-ra%0a> te 50/10 overload %3cbadhosts> flush global)"%0a host:1609327575=198.251.81.119 author:1609327314=jrmu diff:1609327314:1609327134:=108,174d107%0a%3c %0a%3c !! Comments%0a%3c %0a%3c [@%0a%3c ExtIf = "vio0"%0a%3c IP4 = "10.0.0.1"%0a%3c IntIP4 = "192.168.0.1"%0a%3c IP6 = "2001:db8::/80"%0a%3c @]%0a%3c %0a%3c ExtIf is the external interface (vio0 for [[openbsd/buyvm|BuyVM]] and [[openbsd/vmmusers|VMM]] users), IP4 is your DDoS-filtered IPv4 address, IntIP4 is your secret unfiltered IPv4 address, and IP6 is your IPv6 subnet range.%0a%3c %0a%3c FlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes%0a%3c 200, max-src-states 200)"%0a%3c Flush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 5%0a%3c 00/10 overload %3cbadhosts> flush global)"%0a%3c FlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-ra%0a%3c te 50/10 overload %3cbadhosts> flush global)"%0a%3c %0a%3c set skip on lo0%0a%3c set loginterface $ExtIf%0a%3c set ruleset-optimization profile%0a%3c set syncookies adaptive (start 25%25, end 12%25)%0a%3c %0a%3c table %3cilines> persist file "/etc/pf/ilines"%0a%3c table %3cbadhosts> persist file "/etc/pf/badhosts"%0a%3c %0a%3c # udp and icmp%0a%3c block in log quick from %3cbadhosts>%0a%3c pass in log quick proto udp to {$IP4 $IP6} port domain $FlushUDP%0a%3c pass in log quick proto udp to {$IntIP4 $IP6} port ntp $FlushUDP%0a%3c pass in log quick proto udp to {$IP4 $IP6} port {isakmp ipsec-nat-t} $FlushUDP%0a%3c block in log quick proto udp to {$IP4 $IP6}%0a%3c block in log quick from urpf-failed%0a%3c match in log all scrub (no-df random-id max-mss 1440)%0a%3c pass in log quick on $ExtIf inet proto icmp icmp-type 8 code 0 $FlushUDP # icmp packets%0a%3c pass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag%0a%3c (MTU)%0a%3c pass in log quick on $ExtIf proto ipv6-icmp $FlushUDP%0a%3c # tcp%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port domain $Flush%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port auth $Flush%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 p%0a%3c op3s} $Flush%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port {gopher http https} $Flush%0a%3c pass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000%0a%3c 9999 16667 16697 } #irc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16%0a%3c 697 } $Flush #irc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 1314 13140 1337 31337 } $Flush #bnc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port 29173 $Flush #wraith%0a%3c pass in log quick proto tcp to {$IP4 $IntIP4 $IP6} port ssh $FlushStrict%0a%3c %0a%3c # road warrior vpn%0a%3c pass in log inet proto udp to {$IP4 $IP6} port {isakmp, ipsec-nat-t} tag IKED%0a%3c pass in log inet proto esp to {$IP4 $IP6} tag IKED%0a%3c pass log on enc0 inet tagged ROADW%0a%3c match out log on $ExtIf inet tagged ROADW nat-to $IP4%0a%3c match in log quick on enc0 inet proto { tcp, udp } to port 53 rdr-to 127.0.0.1 port 53%0a%3c %0a%3c block in log all%0a%3c block out log on $IntIP4%0a%3c pass out quick from {$IP4 $IP6} # allow non-spoofed packets%0a%3c pass out quick proto tcp from $IntIP4 to port ssh%0a%3c pass out quick proto {udp tcp} from $IntIP4 to port {domain}%0a%3c pass out quick inet proto icmp from $IntIP4 # allow ICMP%0a%3c %0a host:1609327314=198.251.81.119 author:1609327134=jrmu diff:1609327134:1609326929:=47c47%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 1314 13140 1337 31337 } $Flush #bnc%0a---%0a> pass in log quick proto tcp to {$IP4 $IP6} port { 1314 21314 1337 31337 } $Flush #bnc%0a host:1609327134=198.251.81.119 author:1609326929=jrmu diff:1609326929:1609326272:= host:1609326929=198.251.81.119 author:1609326272=jrmu diff:1609326272:1609294740:=28c28%0a%3c pass in log quick proto udp to {$IntIP4 $IP6} port ntp $FlushUDP%0a---%0a> pass in log quick proto udp to {$IP4 $IP6} port ntp $FlushUDP%0a host:1609326272=198.251.81.119 author:1609294740=jrmu diff:1609294740:1609294740:=1,111d0%0a%3c (:title Sample PF for Stable:)%0a%3c %0a%3c Here's a sample /etc/pf.conf for stable servers (do '''NOT''' use this for shell servers):%0a%3c %0a%3c [@%0a%3c ExtIf = "vio0"%0a%3c IP4 = "10.0.0.1"%0a%3c IntIP4 = "192.168.0.1"%0a%3c IP6 = "2001:db8::/80"%0a%3c FlushUDP = "max-pkt-rate 10000/10 keep state (max 1000, source-track rule, max-src-nodes%0a%3c 200, max-src-states 200)"%0a%3c Flush = "keep state (max 1000, source-track rule, max-src-nodes 200, max-src-conn-rate 5%0a%3c 00/10 overload %3cbadhosts> flush global)"%0a%3c FlushStrict = "keep state (max 100, source-track rule, max-src-nodes 20, max-src-conn-ra%0a%3c te 50/10 overload %3cbadhosts> flush global)"%0a%3c %0a%3c set skip on lo0%0a%3c set loginterface $ExtIf%0a%3c set ruleset-optimization profile%0a%3c set syncookies adaptive (start 25%25, end 12%25)%0a%3c %0a%3c table %3cilines> persist file "/etc/pf/ilines"%0a%3c table %3cbadhosts> persist file "/etc/pf/badhosts"%0a%3c %0a%3c # udp and icmp%0a%3c block in log quick from %3cbadhosts>%0a%3c pass in log quick proto udp to {$IP4 $IP6} port domain $FlushUDP%0a%3c pass in log quick proto udp to {$IP4 $IP6} port ntp $FlushUDP%0a%3c pass in log quick proto udp to {$IP4 $IP6} port {isakmp ipsec-nat-t} $FlushUDP%0a%3c block in log quick proto udp to {$IP4 $IP6}%0a%3c block in log quick from urpf-failed%0a%3c match in log all scrub (no-df random-id max-mss 1440)%0a%3c pass in log quick on $ExtIf inet proto icmp icmp-type 8 code 0 $FlushUDP # icmp packets%0a%3c pass in log quick on $ExtIf inet proto icmp icmp-type 3 code 4 $FlushUDP # icmp needfrag%0a%3c (MTU)%0a%3c pass in log quick on $ExtIf proto ipv6-icmp $FlushUDP%0a%3c # tcp%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port domain $Flush%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port auth $Flush%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port {smtp submission smtps imap imaps pop3 p%0a%3c op3s} $Flush%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port {gopher http https} $Flush%0a%3c pass in log quick proto tcp from %3cilines> to {$IP4 $IP6} port { 6660:6669 6697 6997 7000%0a%3c 9999 16667 16697 } #irc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 6660:6669 6697 6997 7000 9999 16667 16%0a%3c 697 } $Flush #irc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port { 1314 21314 1337 31337 } $Flush #bnc%0a%3c pass in log quick proto tcp to {$IP4 $IP6} port 29173 $Flush #wraith%0a%3c pass in log quick proto tcp to {$IP4 $IntIP4 $IP6} port ssh $FlushStrict%0a%3c %0a%3c # road warrior vpn%0a%3c pass in log inet proto udp to {$IP4 $IP6} port {isakmp, ipsec-nat-t} tag IKED%0a%3c pass in log inet proto esp to {$IP4 $IP6} tag IKED%0a%3c pass log on enc0 inet tagged ROADW%0a%3c match out log on $ExtIf inet tagged ROADW nat-to $IP4%0a%3c match in log quick on enc0 inet proto { tcp, udp } to port 53 rdr-to 127.0.0.1 port 53%0a%3c %0a%3c block in log all%0a%3c block out log on $IntIP4%0a%3c pass out quick from {$IP4 $IP6} # allow non-spoofed packets%0a%3c pass out quick proto tcp from $IntIP4 to port ssh%0a%3c pass out quick proto {udp tcp} from $IntIP4 to port {domain}%0a%3c pass out quick inet proto icmp from $IntIP4 # allow ICMP%0a%3c @]%0a%3c %0a%3c You will then need to create a folder:%0a%3c %0a%3c [@%0a%3c $ doas mkdir /etc/pf/%0a%3c @]%0a%3c %0a%3c Then, add the list of [[openbsd/ilines|ilines]] to /etc/pf/ilines.%0a%3c %0a%3c [@%0a%3c 198.251.89.130%0a%3c 198.251.83.183%0a%3c 209.141.39.184%0a%3c 209.141.39.228%0a%3c 198.251.84.240%0a%3c 198.251.80.229%0a%3c 198.251.81.119%0a%3c 209.141.39.173%0a%3c 198.251.89.91%0a%3c 198.251.81.44%0a%3c 209.141.38.137%0a%3c 198.251.81.133%0a%3c 2605:6400:0030:f8de::/64%0a%3c 2605:6400:0010:071b::/64%0a%3c 2605:6400:0020:0434::/64%0a%3c 2605:6400:0020:00b4::/64%0a%3c 2605:6400:0010:05bf::/64%0a%3c 2605:6400:0030:fc15::/64%0a%3c 2605:6400:0020:1290::/64%0a%3c 2605:6400:0020:0bb8::/64%0a%3c 2605:6400:0030:faa1::/64%0a%3c 2605:6400:0010:069d::/64%0a%3c 2605:6400:0020:05cc::/64%0a%3c 2605:6400:0010:00fe::/64%0a%3c @]%0a%3c %0a%3c Afterwards, any badhosts can be added to /etc/pf/badhosts.%0a%3c %0a%3c To load the new configuration:%0a%3c %0a%3c [@%0a%3c $ doas pfctl -f /etc/pf.conf%0a%3c @]%0a%3c %0a%3c !! See Also%0a%3c %0a%3c || [[openbsd/pf|PF Guide]] || [[openbsd/ddos|DDoS Filtering Guide]] || [[openbsd/tcpdump|tcpdump]] ||%0a\ No newline at end of file%0a host:1609294740=198.251.81.119