Hi, Ok, I think I get it, thank you for the thorough explanation! According my man page, "floating" is the default which confuses me a bit, since I'm not specifying if-bound, and would expect the returning SA to match the "floating" state created on the first S outbound, but I guess this is wrong. I've added states on inbound and the return state is indeed created with correct wscales now. Now I just have to add states to all the inbound definitions, which is going to take me a while.
This may be a redundant feature to ask for, but if a pass without a state always is suspicious, a "set states on <ifspec>" rule, or something, to always create states on pass rules, would help clean up my rule files and improve readability a bit. Something I've been wondering about for a long time is S/SA. If we live in the age of "default deny", why create states on SFR or something else bizarre? Why even allow it to pass? Also a huge thank you for the brilliant contribution to the security community! Kind regards, Fredrik Widlund Daniel Hartmeier wrote: > On Thu, Mar 30, 2006 at 02:29:19PM +0200, Fredrik Widlund wrote: > > >> So, there are indeed 2 states, one without wscaling. I don't understand >> why the returning state (S->C) is created, and not matched to the >> initial NAT state? Is it because I create the state on "out" and is this >> then invalid?! I use this normally without problems on many routers. >> > > A state entry is always bound to the direction of the packet that > creates it. For instance, if you have a pf box with two interfaces and a > connection flowing through it, you'll get two separate state entries, > one on each interface. The entry on the first interface won't match > packets on the second interface, because, there, packets flow in the > opposite direction. In short, a state entry does not allow packets of > one connection _through_ the firewall as a whole, but generally only > through one interface. > > There are of course special cases, like when you simply don't filter on > one of the interfces, but in general, requiring multiple states per > connection is intentional. It allows more fine-grained control of what > interfaces a connection may flow through (compared to a blanket 'allowed > to pass through anywhere'). See the pf.conf(5) parts about if-bound vs. > floating, for more details. > > The difference between if-bound and floating is NOT that floating is > that blanket check 'through the firewall'. It's a more subtle difference > for the case where you have more than two interfaces, like > > ---- $out1 > $in ---- pf < > ---- $out2 > > With static routing, one connection will only pass through either $out1 > or $out2 exclusively, so if-bound states are fine. But when you have > dynamic routing (or load balancing), you might want to allow packets of > one connection to pass through both $out1 and $out2. THEN you'd use > floating states instead of if-bound. But no matter whether you use > if-bound or floating states on the $out interfaces, those states will > never match packets on $in, because there the direction is reversed. > > Now, given that there are two states, one per interface involved, check > again that each state gets created on the initial SYN of the connection. > > >> I have a very large ruleset, with 10+ segments and many hosts, but I >> have only one state rule: "pass out keep state". I have default deny on >> everything. In essence the stripped ruleset relevant for the case is: >> > > >> block log all >> pass out keep state >> nat on vlan_external from vlan_x:network to $internet -> $gateway >> pass in on vlan_x from vlan_x:network to $internet >> > > The last rule is suspicious, it could allow an initial SYN in (on > vlan_x) without creating state. That SYN then passes out (on another > interface), creating the state there correctly. The SYN+ACK will pass in > on the other interface (based on the state created there), and then gets > routed out through vlan_x. There, it doesn't match any state, and passes > based on the generic 'pass out keep state' rule. Hence, you crate state > on vlan_x on the SYN+ACK instead of the initial SYN. Breaking wscale > support. > > In short, ANY 'pass' rule without 'keep state' is always suspicious. > Also, adding 'flags S/SA' to all 'pass' rules helps spot these problems > early, as they are not (unintentionally) matching SYN+ACKs. > > Daniel >