Simple HFSC packet filter for FreeBSD/OpenBSD

by FJ  

Abstract: HFSC is a packet queuing discipline developed at Carnegie Melon University.
Details here. Its aim is to distribite fairly pieces of the big pie of bandwith to the N entities that eat it.
When I came home in Bulgaria, I decided that it's high-time to implement something with HFSC on my broadband connection.
Goals of this setup: creating an ultimate sharing of connection so that all queues run at almost top speed with minimal interference between each other.
I had some headbang until I realized that my ISP is filtering me by TTL and is chaining DNS queries, so I made some tricks in the scrub section and left it a little wider than than I do normally. Please see below.
Raised the packets in the queue to 1000, so that it can be manipulated easier and in larger numbers. Your mileage may vary depending on your hardware and the bandwidth you want to split. I'm a home user in this situation. But you know it already.
Note: table misfits contains all private and corporate assigned IPs like 16/8,9/8 and so on, which should not appear on your external interface.bgpeer2 is remnant from the time when we didn't have symmetric internet. I don't use it anymore.
They're without brackets, because my blogging software accepts them as HTML tags.

Here is the config file:
#PF.conf reloaded - 16.12.2006
#
tg="block log quick"
tg_in="block in log quick"
tg_out="block out log quick"
#
bw="bandwidth"

ext_if="put your ext if"
int_if="put your int if"
l="lo0"
int_net="ip range of internal net"
#
#
DNS="{IP, IP}"
#
dhcp1="255.255.255.255/32"
dhcp2="172.20.0.9/32"
#
bootstrap_server="67"
#
bootstrap_client="68"
#
q="qlimit"
#
services="22,5190,6666,6667,5190,80,443"
#
#
# Tables: similar to macros, but more flexible for many addresses.
#
table nogo persist file "/etc/pf/misfits"
#
#
table bgpeer persist file "/etc/pf/bgpeer2"
#
#
# Options: tune the behavior of pf, default values are given.
set timeout { interval 5, frag 20, src.track 20 }
set timeout { tcp.first 30, tcp.opening 30, tcp.established 86400 }
set timeout { tcp.closing 90, tcp.finwait 20, 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 6000, adaptive.end 12000 }
#
set limit { states 20000, frags 20000, src-nodes 2000 }
set loginterface $ext_if
set optimization normal
set block-policy drop
set state-policy if-bound
set require-order yes
set fingerprints "/etc/pf.os"
#
# Normalization: reassemble fragments and resolve or reduce traffic ambiguities.
scrub in all min-ttl 2 max-mss 1440 fragment reassemble
scrub out all min-ttl 1 no-df max-mss 1440 fragment reassemble random-id
#
# Queueing: rule-based bandwidth control.
#
altq on $ext_if bandwidth 1000Mb hfsc queue { tcp_ack_out, www, ftp, ssh tcp_ack_in}
queue tcp_ack_out $bw 10Mb priority 6 hfsc (ecn realtime 6Mb linkshare 10% upperlimit 9Mb) $q 1000
queue tcp_ack_in $bw 10Mb priority 7 hfsc (ecn default realtime 6Mb linkshare 10% upperlimit 9Mb) $q 1000
#
#
#start intl www
#
queue www $bw 30Mb priority 5 hfsc (ecn realtime 30Mb linkshare 20% upperlimit 35Mb) $q 1000 { www_in, www_out }
queue www_in $bw 15Mb priority 5 hfsc (ecn realtime 10Mb linkshare 5% upperlimit 10Mb) $q 1000
queue www_out $bw 15Mb priority 6 hfsc (ecn realtime 10Mb linkshare 5% upperlimit 10Mb) $q 1000
#
#
# ftp
#
queue ftp $bw 50Mb priority 5 hfsc (ecn realtime 30Mb linkshare 20% upperlimit 35Mb) $q 1000 { ftp_login, ftp_bulk }
queue ftp_bulk $bw 70% priority 5 hfsc (ecn realtime 30Mb linkshare 20% upperlimit 35Mb) $q 1000
queue ftp_login $bw 30% priority 7 hfsc (ecn realtime 20Mb linkshare 20% upperlimit 25Mb) $q 1000

#ssh
#
queue ssh $bw 120Mb priority 7 hfsc (ecn realtime 50Mb linkshare 30% upperlimit 150Mb) $q 1000 { ssh_login, ssh_bulk }
queue ssh_login $bw 50Mb priority 7 hfsc (ecn realtime 30Mb linkshare 10% upperlimit 35Mb) $q 1000
queue ssh_bulk $bw 50Mb priority 5 hfsc (ecn realtime 30Mb linkshare 10% upperlimit 40Mb) $q 1000
#
# NAT
#
#
nat on $ext_if from !($ext_if) to any -> ($ext_if)
#
# FTP proxying
#
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on $int_if proto tcp from $int_net to any port ftp -> 127.0.0.1 port 8021
#
#
# spamd-setup puts addresses to be redirected into table spamd.
#table spamd persist
#no rdr on { lo0, lo1 } from any to any
#rdr inet proto tcp from spamd to any port smtp -> 127.0.0.1 port 8025
#
# Filtering: the implicit first two rules are
#
antispoof quick for {$ext_if, $int_if,$l }
#
#
pass quick on {$l} all keep state
#
#
block log on $ext_if all
$tg_in on $ext_if inet proto udp from any to any port=syslog
$tg_in on $ext_if from any to any flags P/FSRPAUEW
$tg_in on $ext_if from any to any flags FPU/FSRPAUEW
$tg_in on $ext_if from any to any flags FPU/FPU
$tg_in on $ext_if from any to any flags /FSRA
$tg_in on $ext_if from any to any flags FS/FSRA
$tg_in on $ext_if from any to any flags FSPU/FSPRAU
$tg_in on $ext_if from any to any flags FPU/FSRPAU
$tg_in on $ext_if from any to any flags /FSRPAU
$tg_in on $ext_if from any to any flags F/FSRA
$tg_in on $ext_if from any to any flags U/FSRAU
$tg_in on $ext_if from any to any flags S/FSRPAU
$tg_in on $ext_if from any to any flags P/FSRPAU
$tg_in on $ext_if from any to any flags A/A
$tg_in on $ext_if from any to any flags P/P
#
anchor "ftp-proxy/*"
pass out on $ext_if keep state
#
pass in quick on $ext_if inet proto tcp from any port 21 to $ext_if user proxy keep state queue ftp_bulk
pass out quick on $ext_if inet proto tcp from any to any port 21 user proxy keep state queue ftp_login
#
pass out quick on $ext_if inet proto tcp from any to any port { 22, 5190, 6666,6667, 5190 } keep state queue ssh_login
pass in quick on $ext_if inet proto tcp from any port { 22, 5190, 6666,6667, 5190 } to any keep state queue ssh_bulk
#
pass out quick on $ext_if inet proto tcp from any to any port { 80, 443 } keep state queue www_out
pass in quick on $ext_if inet proto tcp from any port { 80, 443 } keep state queue www_in

Could do more, but I didn't have the time - a vacation is too short to waste with digging too much in geeky things. If you find this useful and would like to contribute: I'm one of the mirror admins of bg.freebsd.org and would enjoy a small contribution for the machine. We have upgraded the SCSI disk subsystem, however we miss a controller for U160 interface with decent performance.
Contact me via $1=`whois oldbonez.net | grep "@" | sort | head -1` && mail -s contribution $1
Thank you and Happy Holidays.

1 ... 81 82 83 ...84 ... 86 ...88 ...89 90 91 ... 96