Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Jan 2010 15:34:48 -0800
From:      Doug Hardie <bc979@lafn.org>
To:        Erik Norgaard <norgaard@locolomo.org>
Cc:        freebsd-questions - <freebsd-questions@freebsd.org>
Subject:   Re: pf rules
Message-ID:  <4D14E7C8-DFFD-4580-8CD0-99BB3C4EB051@lafn.org>
In-Reply-To: <4B59887E.30301@locolomo.org>
References:  <4B594FC0.3010200@el.net> <4B5973AD.8070603@locolomo.org> <772FAD6A-C534-4217-9AA7-274561879E86@lafn.org> <4B59887E.30301@locolomo.org>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help

On 22 January 2010, at 03:14, Erik Norgaard wrote:

> Doug Hardie wrote:
>> On 22 January 2010, at 01:45, Erik Norgaard wrote:
>>> To debug pf rules:
>>>=20
>>> - always add direction to the rule, pass or block, add interface to =
all
>>> rules except default policy, keep state on all pass rules
>>> - group your rules per direction, then per interface
>>> - add log to all rules and watch pflog to see which rule blocks or
>>> passes traffic.
>>> - use keyword quick for any decisive rule
>>> - check the parsing of your ruleset, pfctl -sr
>>>=20
>>> then come back and ask for help.
>> Where do you find the rule information in the pflog output from =
tcpdump? =20
>=20
> a snip:
>=20
> alpha# tcpdump -n -e -i pflog0
> tcpdump: WARNING: pflog0: no IPv4 address assigned
> tcpdump: verbose output suppressed, use -v or -vv for full protocol =
decode
> listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture =
size 96 bytes
> 11:55:20.910140 rule 81/0(match): block in on vr1: 172.16.1.127.52444 =
> 172.16.0.1.23:  tcp 44 [bad hdr length 0 - too short, < 20]
>=20
> rule 81 blocks. Now, problem is that your rules may be more compact, =
you'll find the rule with pfctl -sr. Now admittedly, I got:
>=20
> pass in quick on vr1 inet proto udp from 172.16.0.0/23 to <local_ip> =
port =3D secret_service keep state
>=20
> ofcourse, that rule didn't block. But two lines down I found:
>=20
> block return in log quick on vr1 inet from 172.16.0.0/23 to <local_ip>
>=20
> This makes sence, so why the offset 2? The first line of the output =
from pfctl -sr is
>=20
> scrub all fragment reassemble
>=20
> that shouldn't count as a rule. And then, if pflog starts counting =
with 0 while vi counts from 1 that explains it.
>=20
> Yet another reason to check the rules as parsed using pfctl -sr.
>=20
> Anyway, not trying to cut corners is the first step, then add log so =
you can see whats going on, use quick to avoid some packet fall through =
and being matched by a different rule than intended, organizes your =
rules so you can easily separate things out.
>=20
> My rules are grouped together like this:
>=20
> # default policy
> block all
>=20
> block in log <general condition>
> pass  in quick some packets keep state
> block in log quick <general condition>
>=20
> block out log <general condition>
> pass  out quick some packets keep state
> block out log quick <general condition>
>=20
> # Default policy catch all should never apply
> block log all
>=20
> the conditions for the pass rules should match those of the first =
block and then be more specific, say, only apply to one port. Doing so, =
the pf rule parser will optimize the ruleset.
>=20
> Even if I know that a given rule can only match packets on the vr0 =
interface, I explicitly state the interface. It makes it clear what's =
going on.
>=20
> Once the ruleset is debugged and working you can remove the log =
statements.
>=20
> BR, Erik
> --=20

This is quite interesting.  I can't figure out the rules on my system.  =
Here is the pf.conf file with all comments removed:

table <blackhole> persist file "/etc/blackhole"
table <spamd> persist
table <spamd-white> persist
table <spamd-white-local> persist file "/etc/mail/whitelist"
MAILHOSTS =3D "{zool.lafn.org}"

no rdr on { lo0, lo1 } from any to any
no rdr inet proto tcp from <spamd-white-local> to any port smtp
no rdr inet proto tcp from <spamd-white> to any port smtp
rdr pass log inet proto tcp from any to any port smtp -> 127.0.0.1 port =
spamd
pass in log inet proto tcp to $MAILHOSTS port smtp keep state
pass in log on sis0 reply-to (sis0 192.168.25.1) proto tcp from any to =
any port 75 keep state
block in quick log on $ext_if from <blackhole> to any

Note:  the blackhole file is empty as is the whitelist file.  There is =
an entry for 216.54.240.150 in spamd database.  This is a test system.

Here is the output of tcpdump where I have only taken one entry for each =
rule.  I have listed the rule number at the front of each line:

Rule 0:  14:01:27.133320 rule 0/0(match): pass in on dc0: =
216.54.240.150.55782 > 206.117.18.7.25: S 2501333595:2501333595(0) win =
65535 <mss 1460,nop,nop,sackOK>
Rule 1:  02:26:44.755650 rule 1/0(match): pass in on sis0: =
71.109.144.133.40864 > 192.168.25.7.75: S 3941268770:3941268770(0) win =
65535 <mss 1460,nop,wscale 3,nop,nop,timestamp[|tcp]>
Rule 2:  10:44:45.037918 rule 2/0(match): block in on dc0: =
71.109.162.173.39529 > 206.117.18.7.75: . ack 145 win 65535 =
<nop,nop,timestamp 705571170 1951648775>
Rule 4:  13:51:16.022700 rule 4/0(match): rdr in on dc0: =
216.54.240.150.49821 > 127.0.0.1.8025: S 2371633783:2371633783(0) win =
65535 <mss 1460,nop,nop,sackOK>

I found no entries for rule 3.  There is virtually no traffic on this =
system other than from me.


As I look at pf.conf and tie the rules to the entries I get (rule number =
at beginning of line):

no rdr on { lo0, lo1 } from any to any
no rdr inet proto tcp from <spamd-white-local> to any port smtp
0 - no rdr inet proto tcp from <spamd-white> to any port smtp
4 - rdr pass log inet proto tcp from any to any port smtp -> 127.0.0.1 =
port spamd
pass in log inet proto tcp to $MAILHOSTS port smtp keep state
1 - pass in log on sis0 reply-to (sis0 192.168.25.1) proto tcp from any =
to any port 75 keep state
block in quick log on $ext_if from <blackhole> to any


I have no clue which one is rule 2.  The only block is the last entry =
but that should never be used because the blackhole file is empty.  =
pfctl shows the table is empty also.

The ordering seems to make no sense either.  I also note that the man =
page for pf.conf indicates in the BNF grammar for pf.conf that log is a =
valid entry for no rdr.  However, that always generates a syntax error.  =
Apparently there is no way to log the use of no rdr rules.=



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?4D14E7C8-DFFD-4580-8CD0-99BB3C4EB051>