[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: synproxy to local

I have a hunch it is pf.c r1.437 (commited Apr 25, not part of
3.5-release), the comment reads
  don't add PF_GENERATED tag to synproxy generated packets for the
  second handshake, so they can match rules (and create state) on
  another interface.
The problem this addressed was that synproxy would add a tag to all
packets it generated for the second handshake (the one to the real
server, after the client handshake was completed) that prevented pf from
filtering those packets. The reasoning was that we obviously want to
pass them, but the problem is when you filter statefully on two
interfaces. The handshake packets would pass unfiltered (not creating
state), but subsequent data packets would be filtered (and, not matching
any state entry on the second interface, be blocked).
So, that change causes those packets to not get the tag, so they get
filtered (and, if passed with keep state) and create state on the second
interface, so subsequent packets match that state.
If you're using 'set state-policy if-bound' and filter on all interfaces
(like I'm doing mostly), things work fine. But I think this might create
a state conflict when sharing states across interfaces.
To confirm, can you try the patch below (which re-adds the tags for all
synproxy-generated packets) against -current? Also, in the faulty
snapshot, enable debug logging (pfctl -xm) and watch /var/log/messages
for pf related entries. You could also try switching to if-bound
state-policy (though that usually requires some ruleset changes, as
states no longer apply across multiple interfaces, so interfaces tend to
need more explicit pass keep state rules).
Index: pf.c
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.449
diff -u -r1.449 pf.c
--- pf.c	19 May 2004 17:50:51 -0000	1.449
+++ pf.c	24 May 2004 22:17:44 -0000
@@ -3814,7 +3814,7 @@
 			pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
 			    &dst->addr, src->port, dst->port,
 			    (*state)->dst.seqhi, 0, TH_SYN, 0,
-			    (*state)->src.mss, 0, 0, NULL, NULL);
+			    (*state)->src.mss, 0, 1, NULL, NULL);
 			return (PF_SYNPROXY_DROP);
 		} else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
 		    (TH_SYN|TH_ACK)) ||@@ -3831,7 +3831,7 @@
 			pf_send_tcp((*state)->rule.ptr, pd->af, &src->addr,
 			    &dst->addr, src->port, dst->port,
 			    (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
-			    TH_ACK, (*state)->dst.max_win, 0, 0, 0,
+			    TH_ACK, (*state)->dst.max_win, 0, 0, 1,
 			    NULL, NULL);
 			(*state)->src.seqdiff = (*state)->dst.seqhi -