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/*"
