Saturday, January 12, 2008

pf miscellanea on FreeBSD

pf Status

Install and run /usr/ports/sysutils/pftop. Press "5" and "8" to see how your rules and queues are doing. "?" for help on what else you can do.

/usr/ports/net/trafshow is also very useful for seeing what going through your network cards.

pf Logging


To get l
ogging to work on FreeBSD, make a rule like:

(pf.conf) pass in log quick on $ext_inf

then enable the pf logging interface with:

$ kldload ~/test_pf/pflog.ko
$ ifconfig pflog0 up

then you can watch the logged stuff with:

$ tcpdump -n -e -ttt -i pflog0


queues of queues

If you try to have multilayer queues, with borrowing, things won't work as you expect, e.g.:

queue
bandwidth 20kb q1(a,b) bandwidth 20kb borrow
queue bandwidth 10kb a borrow
queue
bandwidth 10kb b borrow
queue
bandwidth 20kb q2(y,z) bandwidth 20kb borrow
queue bandwidth 10kb y borrow
queue
bandwidth 10kb z borrow

If queue a fills up, it seems to borrow from b, but then when a+b reaches 20kbit, it doesn't seem to borrow (at all / very well) from q2, even if q2 is idle.

FreeBSD pf traffic shaping rules

Handy link: http://www.openbsd.org/faq/pf/queueing.html

My pf.conf does this:

- My outgoing is 256kbit, this uses 240kbit to leave a bit of overhead so my cable modem doesn't end up doing shaping as well.

- Some redirection of traffic to internal clients

- All outgoing web (port 80) traffic is transparently sent to squid

- No security.. No inbound ports are actively blocked.

- Brute force poking and prodding of my ssh port will get you put in jail for the night.
- Install /usr/ports/security/expiretable, and put into rc.conf:
expiretable_enable="yes"
expiretable_flags="-d -t 1d bruteforce"

- Prioritisation:
- Priority is given to VoIP traffic (identified by port, and originating device on my LAN)
- SSH is next
- Then everything else
- Then Bittorrent (identified by setting my BT client to make all traffic come from a given port)

- Bittorrent is limited to about 15Kbytes/sec outgoing, as there is no borrowing enabled on the "bt" queue

"Ah-ha" moments:
- You create the queues on the outgoing (internet) interface
- You can (if you want) say which queue stuff is go to into as it comes in on the LAN side. Then, if it ends up going out to the internet, it'll end up in the designated queue.

The rules...

ext_if="sk0"
int_if="re0"
internal_net="192.168.60.0/24"
cablemodem="192.168.100.1"
voipbox="192.168.60.5"

# BT client set to have all outbound traffic as being from port 43123
# ports 43000:43999 forwarded to an internal machine

voipports="{5060,6000:6005}"

# Options: tune the behavior of pf, default values are given.
#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 drop
#set require-order yes
#set fingerprints "/etc/pf.os"

martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \
0.0.0.0/8, 240.0.0.0/4 }"

table persist

# Normalization: reassemble fragments and resolve or reduce traffic ambiguities.
scrub in all


altq on $ext_if cbq bandwidth 240Kb queue { voip, tcpack, ssh_int, ssh_bulk, def, bt,btack }
queue bt bandwidth 128Kb priority 1 cbq( red ecn)
queue btack bandwidth 6Kb priority 2 cbq(borrow red)

queue def bandwidth 6Kb priority 3 cbq(borrow red default)
queue ssh_bulk bandwidth 6Kb priority 3 cbq(borrow red)
queue ssh_int bandwidth 6Kb priority 4 cbq(borrow red)

queue voip bandwidth 80Kb priority 6 cbq(borrow red)
queue tcpack bandwidth 8Kb priority 7 cbq(borrow red)



nat on $ext_if from $internal_net to any -> ($ext_if)


rdr on $ext_if proto {tcp,udp} from any to any port 43000:43999 -> 192.168.60.42
rdr on $ext_if proto {tcp,udp} from any to any port 25777 -> 192.168.60.42
# rdp = 3389
rdr on $ext_if proto {tcp,udp} from any to any port 3389 -> 192.168.60.42
rdr on $ext_if proto tcp from any to any port 5900 -> 192.168.60.42

#SIP/VoIP
rdr on $ext_if proto {tcp,udp} from any to any port $voipports -> $voipbox

# squid
rdr on $int_if proto tcp from any to any port http -> 127.0.0.1 port 3128

antispoof for $ext_if
antispoof for $int_if

block quick from

pass in quick on $ext_if from $cablemodem to any
pass out quick on $ext_if from any to $cablemodem

block drop in quick on $ext_if from $martians to any
block drop out quick on $ext_if from any to $martians


pass in on $ext_if inet proto tcp from any to any port 22 \
flags S/SA keep state \
(max-src-conn 15, max-src-conn-rate 5/3, \
overload flush global)


################################################################
##
## VOIP

pass in quick on $int_if inet proto {tcp,udp} from any to any port $voipports keep state queue (voip,tcpack)
pass in quick on $int_if inet proto {tcp,udp} from any port $voipports to any keep state queue (voip,tcpack)

pass out quick on $ext_if inet proto {tcp,udp} from any port $voipports to any keep state queue (voip,tcpack)
pass out quick on $ext_if inet proto {tcp,udp} from any to any port $voipports keep state queue (voip,tcpack)
pass in quick on $int_if from $voipbox to any keep state queue (voip,tcpack)

################################################################
##
## BT

pass in quick on $int_if inet proto {tcp,udp} from any port 43123 to any keep state queue (bt,btack)
pass in quick on $int_if inet proto {tcp,udp} from any to any port 43123 keep state queue (bt,btack)
pass in quick on $int_if inet proto {tcp,udp} from any port 43123 to any keep state queue (bt,btack)
pass in quick on $int_if inet proto {tcp,udp} from any to any port 6881:6889 keep state queue (bt,btack)

################################################################
##
## SSH

pass in quick on $int_if inet proto tcp from any to any port 22 \
keep state flags S/SA queue(ssh_int, ssh_bulk)

################################################################

pass in quick on $int_if inet proto tcp all modulate state flags S/SA queue(def, tcpack)
pass in quick on $int_if inet proto { udp, icmp, gre } all keep state

# security schmecurity
pass in all
pass out all