pf configuration subleties

Daniel Malament <[email protected]>
Newsgroups gmane.os.openbsd.pf
Message-ID <[email protected]>
I recently spent a couple of days reading various pf documentation, 
including the man pages, the faq, and some guides (including Peter 
Hansteen's), and fiddling with my firewall configuration, and there are 
a few subtleties that I haven't found addressed anywhere.

1) The big one is what I would call the 'double state problem'.  It 
seems to me that the big disadvantage of a default-deny ruleset is that 
because explicit pass rules are required on all interfaces, traffic 
passing through the firewall machine needs state on all interfaces. 
This isn't a problem for most applications, but it seems like it would 
be a memory issue for large routers.

Supposing you have the following in your pf.conf [note: all rules in my 
(simplified) examples will omit the implicit 'keep state']:

---
block    all
pass     on $int_if
pass out on $ext_if
pass in  on $ext_if from any to $ext_if port 22
---

If you now initiate a web connection from a machine on the internal 
network to one on the internet, two states are created, one on each 
interface, to allow return packets through.

The same problem, less obviously, occurs with a default-deny-in ruleset 
like:
---
block in  all
pass  out all
pass  in  on $int_if
pass  in  on $ext_if from any to $ext_if port 22
---
or even with rules like
pass from $int_if:network to $ext_if:network

If you have
---
block    all
pass     on $int_if no state
pass out on $ext_if
pass in  on $ext_if from any to $ext_if port 22
---
then the ruleset is effectively the same, and there is only one state 
per connection, but traffic is (slightly) slower because return traffic 
through $int_if needs to be checked against the ruleset instead of the 
state table.

But if you create a default-permit ruleset with wide-ranging block 
rules, like:

---
block in on $ext_if
pass  in on $ext_if from any to $ext_if port 22
---

you get the same filtering results with fewer rules, one state per 
connection, and no need for ruleset lookups on established streams.

The most obvious benefit of a default-deny ruleset is that it saves you 
if you make a block rule too narrow, or comment it out by accident or 
something.  But is there a way to have only one state per connection 
with a default-deny ruleset?  And if not, does it ever actually matter, 
or am I just being pedantic?

2) The other (shorter) question:
If I want one of my internal networks to be able to access the internet, 
but not be able to access my other internal networks, is

---
table <non_local> { 0.0.0.0/0 !$int_net1 !$int_net2 }
block   all
pass in on $int_net3 from any to <non_local>
[etc]
---

better or worse in speed and resources than

---
block all
pass  in on $int_net3
block in on $int_net3 from any to $int_net1:network
block in on $int_net3 from any to $int_net2:network
[etc]
---

?

Any enlightenment from the pf gurus?
Thanks.

PS: please cc me on replies; I can't seem to get the list server to 
accept my subscribe requests.  It bounces them as spam. (!?)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.