Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Jan 2007 16:39:52 -0800
From:      Drew Tomlinson <>
To:        FreeBSD Questions <>
Subject:   pf and ALTQ Help
Message-ID:  <>

Next in thread | Raw E-Mail | Index | Archive | Help
I recently began using a VoIP phone service (SunRocket) and need to 
ensure that the SunRocket hardware has priority over any other traffic 
on my slow DSL connection.  For years I've used ipfw for my firewall so 
I tried shaping traffic with dummynet but it seems unreliable.  Because 
the man page says dummynet isn't a true QoS, I decided to move from ipfw 
to pf.  From what I've read, seems pf is a much better firewall anyway 
and now I have the need.  :)

I've worked up a pf.conf file following the tutorial at but there are a few items that I can't 
seem to get right.  Blacklamb sits behind my router and I have some 
ports redirected to it. This rule doesn't seem to match packets and 
create a state rule:

pass log proto { tcp, udp } to blacklamb port $blacklamb_ip_services \
      flags S/SA synproxy state

But when I use this one, things are OK.
pass log proto { tcp, udp } to blacklamb port $blacklamb_ip_services 
keep state

Is synproxy state supposed to work with redirection?

Also, when trying to put VoIP traffic in a priority queue, this rule is 
not matching and I don't understand why:

pass out log on $ext_if from gizmo to any keep state queue voip_out

I'd really appreciate any help and comments on my rule set in general.



Here is my complete ruleset:

blacksheep# cat /etc/pf.conf
#       $FreeBSD: src/etc/pf.conf,v 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 
ext_if="dc1"    # replace with actual external interface name i.e., dc0

int_if="dc0"    # replace with actual internal interface name i.e., dc1

vpn_if="tun0"   # OpenVPN interface


localnet="{ $internal_net, $vpn_net }"

blacksheep_ip_services="{ 22, 25, 1194, 1195, 10000 }"
blacklamb_ip_services="{ 22, 25, 80, 993, 10001 }"

# Tables: similar to macros, but more flexible for many addresses.
table <banned> file "/etc/pf/banned"
table <rfc1918> const {,, }
table <draft_manning> const {,,, \, }
table <login> file "/etc/pf/login"
table <spyware> file "/etc/pf/spyware"

set skip on lo0

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

# Queueing: rule-based bandwidth control.
altq on $ext_if priq queue { std_out, voip_out, ack_out, high_out, low_out }
queue std_out priority 4 priq (default)
queue voip_out priority 9
queue ack_out priority 10
queue high_out priority 5
queue low_out priority 3

# Translation: specify how addresses are to be mapped or redirected.
# nat: packets going out through $ext_if with source address 
$internal_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 
nat on $ext_if from $internal_net to any -> ($ext_if)

rdr on $ext_if proto { tcp, udp } from any to $ext_if \
        port $blacklamb_ip_services -> blacklamb

rdr on $ext_if proto { tcp, udp } from any to $ext_if \
        port $bigdaddy_ip_services -> bigdaddy

# Redirect FTP traffic to ftp-proxy
#rdr on $int_if proto tcp from any to any port ftp -> port 8021

# Stop spoofing for our interfaces
antispoof for $ext_if
antispoof for $int_if

# Set up default behavior.  Allow outbound packets and deny inbound.
# Unlike ipfw (first match wins), in pf, last match wins unless using
# the 'quick' modifier.  Thus default rules are set at the top
block log all
pass from { $internal_net, $vpn_net } keep state
pass out from dc1 keep state

# Block non-routable IP addresses with 'quick' so they won't be passed by
# subsequent rule.
block in log quick on $ext_if from { <rfc1918>, <draft_manning> } to any
block out log quick on $ext_if from any to { <rfc1918>, <draft_manning> }

# Ensure IP listed in 'banned' table are not passed by some subsequent rule
block in log quick on $ext_if from <banned> to any

# Block interactive access to sites listed in 'login' table.  Use quick to
# ensure not passed by subsequent rule.
login_ports="{ 21, 22, 23, 143, 901, 993, 1194, 1195, 3389, 8080, 8081, \
        8888, 5405, 5406, 10000, 10001, 10865 }"
block in log quick on $ext_if  proto { tcp, udp } from <login> port 

# Politely reject auth traffic
# (
block return in on $ext_if proto tcp from any port auth

# Allow icmp
icmp_types="{ echoreq, unreach }"
pass inet proto icmp all icmp-type $icmp_types keep state

# Allow traceroute the default range for traceroute(8):
# "base+nhops*nqueries-1" (33434+64*3-1)
pass out on $ext_if inet proto udp from any to any \
        port 33433 >< 33626 keep state

# Allow services hosted by Blacksheep
pass in on $ext_if proto { tcp, udp } to $ext_if \
        port $blacksheep_ip_services flags S/SA synproxy state

# Allow services to work on Blacklamb. (NOTE: Research ftp-proxy to get
# FTP working)
# This rule doesn't work even though it works for Blacksheep above.  Maybe
# has to do with NAT?
##pass log proto { tcp, udp } to blacklamb port $blacklamb_ip_services \
##      flags S/SA synproxy state

# This one works
pass log proto { tcp, udp } to blacklamb port $blacklamb_ip_services 
keep state

# assign packets to a queue.
pass out log on $ext_if from gizmo to any keep state queue voip_out

Want to link to this message? Use this URL: <>