Max wrote: > You should explicitly pass initial packet(s) through both interfaces.
Max, is this requirement documented somewhere? This is becoming very interesting and educational. Thank you for the great analysis, but may I ask you some more questions? > > We have following rules: > @0 pass in on $dmz > @1 block in on $dmz from any to 192.168.0.0/16 > @2 pass in on $inside > > 1. first packet arriving on $inside from 192.168.10.3 to 172.16.1.10 > 2. pf searching a state using a hash based on src and dst > 192.168.10.3-172.16.1.10 > 3. there is no such state > 4. maching against ruleset > 5. using rule @2 > 6. creating a state with key 192.168.10.3-172.16.1.10 And this state does not allow traffic in the reverse direction (172.16.1.10 -> 192.168.10.3)? That is probably the cause of my confusion. As a person with some ipfw background, I'm used to the fact that ipfw's dynamic rules are bidirectional. It is documented, and "ipfw -d list" shows them as such, e.g. 65500 STATE udp 192.168.3.76 61152 <-> 192.168.1.1 53 :default But why would pf need such unidirectional states at all? Is their purpose different from ipfw's keep-state/dynamic rules? > 7. making routing decision > 8. sending a packet through $dmz from 192.168.10.3 to 172.16.1.10 > 9. pf recieving outgoing packet, in this case reversing src and dst > 10. searching a state using a key 172.16.1.10-192.168.10.3 > 11. there is no such state > 12. using default pass, no state created > 13. recieving reply on $dmz from 172.16.1.10 to 192.168.10.3 > 14. searching a state using a (straight) key 172.16.1.10-192.168.10.3 > 15. there is no such state > 16. matching against ruleset > 17. using rule @1 > > Hope I am correct. :) Yes, I think this explains perfectly what's happening. I somehow was thinking that the state created at Step 6 would be found and used at Step 14-15. > > So, you can modify first rule: > @0 pass on $dmz (no direction keyword) > Now pf can create a state when sending initial packet from 192.168.10.3 > to 172.16.1.10. Outgoing packet will generate a state with reversed key > 172.16.1.10-192.168.10.3. Then reply packet(s) will match this state > (traffic from 172.16.1.10 to 192.168.10.3). I prefer rules bound to interfaces, Cisco-style. > > Or you can create "pass out on $dmz..." rule. Yeah, that sounds great. The ping responses begin to arrive at 192.168.10.3! Victory! Let's see what happens to the rules and states (the added rule becomes @2): oot@fw:~ # pfctl -vvs rules No ALTQ support in kernel ALTQ related functions disabled @0 pass in on vtnet1 all flags S/SA keep state [ Evaluations: 3074 Packets: 0 Bytes: 0 States: 0 ] [ Inserted: uid 0 pid 1482 State Creations: 0 ] @1 block drop in on vtnet1 inet from any to 192.168.0.0/16 [ Evaluations: 0 Packets: 0 Bytes: 0 States: 0 ] [ Inserted: uid 0 pid 1482 State Creations: 0 ] @2 pass out on vtnet1 all flags S/SA keep state [ Evaluations: 1 Packets: 4630 Bytes: 388920 States: 1 ] [ Inserted: uid 0 pid 1482 State Creations: 1 ] @3 pass in on vtnet2 all flags S/SA keep state [ Evaluations: 3074 Packets: 4630 Bytes: 388920 States: 1 ] [ Inserted: uid 0 pid 1482 State Creations: 1 ] root@fw:~ # root@fw:~ # pfctl -vvs states No ALTQ support in kernel ALTQ related functions disabled all icmp 172.16.1.10:33794 <- 192.168.10.3:33794 0:0 age 00:43:38, expires in 00:00:10, 2498:2498 pkts, 209832:209832 bytes, rule 3 id: 000000005de764a4 creatorid: 4e14336a all icmp 192.168.10.3:33794 -> 172.16.1.10:33794 0:0 age 00:43:38, expires in 00:00:10, 2498:2498 pkts, 209832:209832 bytes, rule 2 id: 000000005de764a5 creatorid: 4e14336a root@fw:~ # I begin to see two identical (?) floating states. I call them identical because both denote the direction of traffic "192.168.10.3 -> 172.16.1.10". There is not a state with (reversed) key "172.16.1.10 -> 192.168.10.3", but the return traffic is now somehow magically passed. I'm mystified again. -- Victor Sudakov, VAS4-RIPE, VAS47-RIPN 2:5005/49@fidonet http://vas.tomsk.ru/
signature.asc
Description: PGP signature