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: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4D14E7C8-DFFD-4580-8CD0-99BB3C4EB051>