Skip to content

Instantly share code, notes, and snippets.

@johnko
Last active January 30, 2016 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnko/dd529cf872292ade24d2 to your computer and use it in GitHub Desktop.
Save johnko/dd529cf872292ade24d2 to your computer and use it in GitHub Desktop.
example web throttling with pf
# Edit your /etc/pf/pf.conf
# If you are connected via ssh, make sure you allow connection to your ssh port!
vi /etc/pf/pf.conf
# Enable pf on your system
sysrc pf_enable="YES"
sysrc pf_rules="/etc/pf/pf.conf"
# Start pf service/daemon
# If you are connected via SSH, you may be disconnected
service pf start
# Reload pf config if you make more changes to pf.conf
service pf reload
# To add an IP to the weblimit table
# This blocks one IP
# No need to reload pf if you add/remove from tables already defined in pf
pfctl -P -t weblimit -T add 192.168.0.253
# To add a subnet to the weblimit table
# This blocks all 192.168.0.* IPs
pfctl -P -t weblimit -T add 192.168.0.0/24
# To see what's in the table
pfctl -P -t weblimit -T show
# To save the table to disk (so it persists on reboot)
pfctl -P -t weblimit -T show >"/etc/pf/weblimit.table"
# To clear the table
pfctl -P -t weblimit -T expire 0
## variables
egress = "lagg0"
web_ports = "{ http, https, 8080 }"
ssh_ports = "{ ssh, 22222 }"
## tables of IP addresses
table <sshban> persist file "/etc/pf/sshban.table"
table <weblimit> persist file "/etc/pf/weblimit.table"
## quick rules: if there's a match, stop looking for other rules and block/pass as directed
# drop connections fomr ips in sshban table from connecting
block quick on $egress proto { tcp, udp } from <sshban> to (self) port $ssh_ports
# limit to 5 connections total, and 5 connections every 2 seconds
pass in quick on $egress proto { tcp, udp } from <weblimit> to (self) port $web_ports modulate state ( max-src-conn 5, max-src-conn-rate 5/2 )
## regular rules
# allow me to connect to other servers' sshd
pass out on $egress proto tcp from (self) to any port $ssh_ports modulate state
# allow my sshd to respond to clients
pass out on $egress proto tcp from (self) port $ssh_ports to any modulate state
# allow clients to connect to my sshd at a max of 15 connections per ip, and 15 connections per 2 seconds, and add them to sshban table if they exceed this limit
pass in on $egress proto tcp from any to (self) port $ssh_ports modulate state ( max-src-conn 15, max-src-conn-rate 15/2, overload <sshban> )
# allow me to talk to other servers' web ports
pass out on $egress proto tcp from (self) to any port $web_ports modulate state
# allow my web ports to reply to clients
pass out on $egress proto tcp from (self) port $web_ports to any modulate state
# allow clients to connect to my web ports at a max of 1000 connections per ip, and 1000 connections per 1 seconds, and add them to weblimit table if they exceed this limit
pass in on $egress proto tcp from any to (self) port $web_ports modulate state ( max-src-conn 1000, max-src-conn-rate 1000/1 , overload <weblimit> )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment