On 18/12/13 22:32, Camiel Dobbelaar wrote:
On 18/12/13 14:50, Maxim Khitrov wrote:
On Wed, Dec 18, 2013 at 8:42 AM, Camiel Dobbelaar <c...@sentia.nl> wrote:
On 18/12/13 13:53, Maxim Khitrov wrote:
When writing outbound rules in pf, is there an accepted best practice
for only matching packets that are either forwarded or
firewall-generated?
The best that I could come up with is 'received-on all' as a way of
identifying forwarded packets, but that option can't be negated to
match packets that were not received on any inbound interface (i.e.
those generated by the firewall itself).
Another option is 'from (self)', but then you have to be careful with
any preceding nat rules. Ideally, I want a solution that doesn't
depend on the context. I also tried to use tags in combination with
'received-on', but it became rather messy and created conflicts with
other tag usage.
What is everyone else using to solve this problem?
Check the "user" option in pf.conf(5):
user <user>
This rule only applies to packets of sockets owned by the
specified user. For outgoing connections initiated
from the
firewall, this is the user that opened the connection.
For
incoming connections to the firewall itself, this is
the user
that listens on the destination port. For forwarded
connections,
where the firewall is not a connection endpoint, the
user and
group are unknown.
I tried that a while ago and it doesn't work as documented:
http://marc.info/?l=openbsd-bugs&m=137650531124231&w=2
http://marc.info/?l=openbsd-bugs&m=137658379014570&w=2
Nice of you to lure me in like this, and spent a few hours looking at
the code. :-)
I'd say the feature is indeed broken, and probably has been for more
then 10 years.
in_pcblookup_listen() in pf.c is the culprit. The destination IP does
not seem to matter for the socket lookup and will match anything. As
you noticed, this makes forwarded traffic match too.
So I guess the only way to make this work at all is to match the source
and destination IP's yourself first in pf.conf like this:
pass in from any to self port 22 user root
pass out from self to any user camield
I think a documentation fix for pf.conf(5) is all that can be done.
The diff adds the following paragraph:
When listening sockets are bound to the wildcard address,
pf(4)
cannot determine if a connection is destined for the firewall
itself. To avoid false matches on just the destination port,
combine a user rule with source or destination address self.
Also, it deletes all mentions of the "unknown" user since it's useless.
And the example is updated.
Better?
camield@xmts $ cvs diff -u
cvs server: Diffing .
Index: pf.conf.5
===================================================================
RCS file: /cvs/src/share/man/man5/pf.conf.5,v
retrieving revision 1.531
diff -u -p -u -r1.531 pf.conf.5
--- pf.conf.5 27 Nov 2013 15:16:29 -0000 1.531
+++ pf.conf.5 19 Dec 2013 13:32:17 -0000
@@ -760,9 +760,14 @@ For outgoing connections initiated from
that opened the connection.
For incoming connections to the firewall itself, this is the user that
listens on the destination port.
-For forwarded connections, where the firewall is not a connection endpoint,
-the user and group are
-.Em unknown .
+.Pp
+When listening sockets are bound to the wildcard address,
+.Xr pf 4
+cannot determine if a connection is destined for the firewall itself.
+To avoid false matches on just the destination port, combine a
+.Ar user
+rule with source or destination address
+.Ar self .
.Pp
All packets, both outgoing and incoming, of one connection are associated
with the same user and group.
@@ -777,32 +782,11 @@ user ID (to drop privileges), the creden
.Pp
User and group IDs can be specified as either numbers or names.
The syntax is similar to the one for ports.
-The value
-.Ar unknown
-matches packets of forwarded connections.
-.Ar unknown
-can only be used with the operators
-.Cm =
-and
-.Cm != .
-Other constructs like
-.Cm user \*(Ge unknown
-are invalid.
-Forwarded packets with unknown user and group ID match only rules
-that explicitly compare
-.Ar unknown
-with the operators
-.Cm =
-or
-.Cm != .
-For instance
-.Cm user \*(Ge 0
-does not match forwarded packets.
The following example allows only selected users to open outgoing
connections:
.Bd -literal -offset indent
-block out proto { tcp, udp } all
-pass out proto { tcp, udp } all user { \*(Lt 1000, dhartmei }
+block out proto tcp all
+pass out proto tcp from self user { \*(Lt 1000, dhartmei }
.Ed
.El
.Ss Translation