State table and counters: pfctl -s info (or -si)
/etc/pf/base.pf
# $FreeBSD: src/etc/pf.conf,v 1.2.2.1 2006/04/04 20:31:20 mlaier Exp $ # $OpenBSD: pf.conf,v 1.21 2003/09/02 20:38:44 david Exp $ # # See pf.conf(5) and /usr/share/examples/pf for syntax and examples. # Required order: options, normalization, queueing, translation, filtering. # Macros and tables may be defined and used anywhere. # Note that translation rules are first match while filter rules are last match. # Macros: define common values, so they can be referenced and changed easily. ext_if="tun0" # replace with actual external interface name i.e., dc0 int_if="rl0" # replace with actual internal interface name i.e., dc1 int_net="{ 172.16.44.0/24, 172.16.45.0/24, 172.16.46.0/24, 192.168.1.0/24, 192.168.2.0/24, 10.0.0.0/8 }" # Options: tune the behavior of pf, default values are given. # Flush states? #set timeout { tcp.first 10, tcp.opening 10, tcp.established 10 } #set timeout { tcp.closing 10, tcp.finwait 10, tcp.closed 10 } #set timeout { interval 10, frag 30 } #set timeout { tcp.first 120, tcp.opening 30, tcp.established 86400 } #set timeout { tcp.closing 900, tcp.finwait 45, tcp.closed 90 } #set timeout { udp.first 60, udp.single 30, udp.multiple 60 } #set timeout { icmp.first 20, icmp.error 10 } #set timeout { other.first 60, other.single 30, other.multiple 60 } #set timeout { adaptive.start 0, adaptive.end 0 } #set limit { states 10000, frags 5000 } #set loginterface none #set optimization normal set block-policy return #set block-policy drop #set require-order yes set fingerprints "/etc/pf.os" # Normalization: reassemble fragments and resolve or reduce traffic ambiguities. scrub in all altq on $ext_if bandwidth 288Kb cbq queue { ack, ssh, dflt, bulk, down } queue ack bandwidth 32Kb priority 7 cbq(rio, borrow) queue ssh bandwidth 128Kb priority 5 cbq(rio, borrow) queue dflt bandwidth 8Kb priority 4 cbq(rio, borrow, default) queue bulk bandwidth 8Kb priority 2 cbq(rio, borrow) queue down bandwidth 8Kb priority 0 cbq(rio, borrow) # Translation: specify how addresses are to be mapped or redirected. # nat: packets going out through $ext_if with source address $int_net will # get translated as coming from the address of $ext_if, a state is created for # such packets, and incoming packets will be redirected to the internal address. nat-anchor "dynamic/*" binat-anchor "dynamic/*" nat on $ext_if from $int_net to any -> ($ext_if:0) # rdr outgoing FTP requests to the ftp-proxy rdr on $int_if proto tcp from any to !vitani port ftp -> 127.0.0.1 port 8021 rdr-anchor "dynamic/*" # Filtering: the implicit first two rules are pass in all pass out all # Default to block all on external interface block in on $ext_if all # Reject instead of drop for ident (irc servers hate that) block return-rst in on $ext_if proto tcp from any to ($ext_if) port ident # Keep state for all outgoing packets, and queue in default pass out on $ext_if proto { tcp, udp, icmp } all modulate state queue (dflt, ack) # Queue download-tagged packets pass out on $ext_if tagged DOWNLOAD modulate state queue (down, ack) # Queue all outgoing SSH connections in ssh queues pass out on $ext_if proto tcp from any to any port { 22, 13022 } modulate state queue (bulk, ssh) # FTP stuff pass on $ext_if inet proto tcp from any to any user proxy keep state queue (dflt, ack) # NTP stuff pass out on $ext_if proto udp from any to any port 123 keep state queue ack # RDP (MSTSC) stuff pass out on $ext_if proto tcp from any to any port 3389 keep state queue (ssh, ack) anchor "dynamic/*"