FreeBSD PF 4.1 Inserts Flags S/SA Automatically to rules

Tom Uffner tom at uffner.com
Thu May 15 17:18:45 UTC 2008


Mark Pagulayan wrote:

> We are using PF from FreeBSD 7.0 and using the rules we used from
> openbsd 4.0 PF. With the help of Jeremy chadwick, I found out that
> modulate state is broken in FreeBSD PF so I replaced all rules that uses
> modulate state to use keep state.

FreeBSD 7.0 uses PF 4.1 so a number of your rules could be expressed
more compactly and a few of them were redundant even w/ pf 4.0.

> PF runs in bridge mode where one end connects to the Border
> Router(connected to the internet) and the other end to a Core
> Switch(connected to the University network). Basically with do a layer 2
> firewall with PF. 

i assume you didn't change the default sysctl "net.link.bridge.pfil_member: 1"

> Unfortunately I can't post all of my rules/attach, But I could for some.
> Would this be helpful? 

not asking you to give up any sensitive / proprietary information. but 
obviously we can't help w/ what you don't tell us...

> ========================================================================

i don't see any really obvious sources of state mismatches in the rules
you have posted. as i said though, many of them could be expressed more
concisely. PF will assume stuff like "to any", "from any", and now in
FreeBSD 7.0 (PF 4.1) "keep state [flags S/SA]" is implicit in any filter
rules that don't unset it.

> set limit states 150000
>  set timeout tcp.first 120
>  set timeout tcp.established 86400
>  set timeout { adaptive.start 90000, adaptive.end 250000}
# is there a "set skip on {lo0, bridge0}" in here somewhere
# or did you set net.link.bridge.pfil_bridge = 0

>  ext_if = "em1"
>  int_if = "em0"
>  
>  set loginterface $ext_if
>  wireless_allowed_tcp = "{515}"
>  blocked_udp = "{7, 67, 68, 69, 111, 134><140, 199, 445, 512, 513, 520,
> 1993, 2049, 1900, 5000}"
>  blocked_tcp_in = "{7, 11, 15, 67, 68, 87, 111,  134><140, 144,  199,
> 445, 511><516, 1025, 1993, 1900, 2049, 2766, 5000, 5999><6100}"
>  blocked_tcp_out = "{7, 11, 15, 67, 68, 87, 111,  134><140, 144,  199,
> 445, 511><516,  1993, 1900, 2049, 2766, 5000, 6000}"
>  
>  scrub in on $ext_if
>  
>  altq on $ext_if cbq bandwidth 200Mb queue { default, unlimited,
> sponsored, premium, proxy, standard }
>  altq on $int_if cbq bandwidth 800Mb queue { default, unlimited,
> sponsored, premium, proxy, standard }
>  queue default on $ext_if bandwidth 67% cbq(default)
>  queue default on $int_if bandwidth 67% cbq(default)
>  queue unlimited on $ext_if bandwidth 15% cbq(borrow ecn)
>  queue unlimited on $int_if bandwidth 15% cbq(borrow ecn)
>  queue sponsored on $ext_if bandwidth 9% cbq(borrow ecn)
>  queue sponsored on $int_if bandwidth 9% cbq(borrow ecn)
>  queue premium on $ext_if bandwidth 7% cbq(borrow ecn)
>  queue premium on $int_if bandwidth 7% cbq(borrow ecn)
>  queue standard on $ext_if bandwidth 2% priority 4 cbq(red)
>  queue standard on $int_if bandwidth 2% priority 4 cbq(red)

>  pass in log quick on $int_if
>  pass out log quick on $int_if
pass log quick on $int_if

>  block in log on $ext_if all
>  block return out log on $ext_if all
> 
>  pass quick on $ext_if proto ospf
>  pass quick on $ext_if proto igmp allow-opts
>  pass quick on $ext_if proto pim allow-opts

>  pass in quick on $ext_if proto udp from any to 224.0.0.0/4 allow-opts
> keep state
>  pass in quick on $ext_if from any to 224.0.0.0/4 allow-opts keep state
# redundant unless you want to tag, log, route or queue packets differently
pass in quick on $ext_if to 224.0.0.0/4 allow-opts

>  pass in quick log on $ext_if from <dmz_router> to any keep state
>  pass out quick log on $ext_if from any to <dmz_router> keep state
pass in quick log on $ext_if from <dmz_router>
pass out quick log on $ext_if to <dmz_router>

>  pass in quick on $ext_if from any to <wide_open>  flags S/SA keep state
>  pass out quick on $ext_if from <wide_open> to any keep state
pass in quick on $ext_if to <wide_open>
pass out quick on $ext_if from <wide_open>

>  pass out on $ext_if inet proto icmp all icmp-type echoreq keep state
>  pass in  on $ext_if inet proto icmp from any to <ping> icmp-type
> echoreq keep state
pass out on $ext_if inet proto icmp icmp-type echoreq
pass in  on $ext_if inet proto icmp to <ping> icmp-type echoreq

>  pass in quick on $ext_if proto tcp from <wireless_uoa> to any port
> $wireless_allowed_tcp
>  
>  block in quick log on $ext_if proto udp from any to any port
> $blocked_udp
>  block out  quick log on $ext_if proto udp from any to any port
> $blocked_udp
# redundant
block quick log on $ext_if proto udp to any port $blocked_udp

>  block in quick log on $ext_if proto tcp from any to any port
> $blocked_tcp_in
>  block out quick log on $ext_if proto tcp from any to any port
> $blocked_tcp_out
block in quick log on $ext_if proto tcp to any port $blocked_tcp_in
block out quick log on $ext_if proto tcp to any port $blocked_tcp_out

>  pass in  quick on $ext_if proto tcp from any to {<tcp-25-in>,
> <firewall>} port=25 flags S/SA keep state
>  pass out quick on $ext_if proto tcp from {<tcp-25-out>, <firewall>} to
> any port=25  keep state
pass in  quick on $ext_if proto tcp to {<tcp-25-in>, <firewall>} port=25
pass out quick on $ext_if proto tcp from {<tcp-25-out>, <firewall>} to any port=25

>  pass out  quick on $ext_if proto tcp from <tcp-53-out> to any port=53
> keep state
>  pass out  quick on $ext_if proto udp from <udp-53-out> to any port=53
> keep state
pass out  quick on $ext_if proto tcp from <tcp-53-out> to any port=53
pass out  quick on $ext_if proto udp from <udp-53-out> to any port=53

>  pass in  quick on $ext_if from any to <firewall> flags S/SA keep state
>  pass out quick on $ext_if from <firewall> to any keep state
pass in  quick on $ext_if to <firewall>
pass out quick on $ext_if from <firewall>

>  block out quick log on $ext_if proto tcp from any to any port=53
>  block out quick log on $ext_if proto udp from any to any port=53
# redundant
block quick log on $ext_if to any port=53

>  block in log quick on $ext_if proto tcp from any to any port=25
>  block out quick log on $ext_if proto tcp from any to any port=25
# redundant
block log quick on $ext_if proto tcp to any port=25

>  block out quick on $ext_if from  <no_netaccount> to any
>  pass out quick on $ext_if from  <external>  to any keep state
>  pass out quick on $ext_if from  <unlimited>  to any keep state queue
> unlimited
>  pass out quick on $ext_if from  <sponsored> to any keep state queue
> sponsored
>  pass out quick on $ext_if from <premium> to any keep state queue
> premium
>  pass out quick on $ext_if from <standard> to any keep state queue
> standard
>  pass in quick on $ext_if from any to <svr-out> flags S/SA keep state
block out quick on $ext_if from <no_netaccount>
pass out quick on $ext_if from <external>
pass out quick on $ext_if from <unlimited> queue unlimited
pass out quick on $ext_if from <sponsored> queue sponsored
pass out quick on $ext_if from <premium> queue premium
pass out quick on $ext_if from <standard> queue standard
pass in quick on $ext_if to <svr-out>

> ========================================================================

> And checking on the state-mismatch
> 
> [mpag016 at fw3 /home/mpag016]# sudo pfctl -si | grep state-mis
>   state-mismatch                     12179            3.9/s
> 
> Also, I want to understand the value that "pfctl -si" command outputs,
> can someone point me in the right direction?

they are counts of various filter/state related actions or events since
the firewall was started (or since they were last zeroed). i den't know of
anywhere it is documented in detail, but most of the items should make
sense after reading pf.conf and having an idea of all the things pf can do.

you can probably figure out which rules cause the state-mismatches by
setting misc debugging "pfctl -xm" and watching the syslog for messages
like:

kernel: pf: loose state match: ...

or

kernel: pf: BAD state: ...
kernel: pf: State failure on:         |


More information about the freebsd-pf mailing list