On Fri, Jan 07, 2005 at 11:06:18AM -0500, Dave Anderson wrote: > I hadn't realized it until I started thinking this through, but it > appears that, if floating state is enabled, there's no way to prevent > PF from passing *some* spoofed packets -- though this probably isn't a > significant issue in practice. Perhaps the "right" way to deal with > all of these issues is to provide more explicit control over floating > state -- e.g., eliminate the current general floating state and add to > each rule specifying "keep state" (or its relatives) an optional list > of interfaces to which those states may float with a direction for each > such interface.
Adding to the previous explanation, if you know that one side of the connection should pass only through one specific interface (like a single uplink interface), you should use an if-bound state for that side. There's no reason to use a floating state in that case. If you're using a floating state (maybe just because it's the default, and you didn't realize the difference), there is one form of spoofing that becomes possible: The state entry says: on any interface, pass incoming from A to B, outgoing from B to A Such packets should only occur on interface I, but you made the state floating (instead of if-bound to I), so theoretically, someone might inject a packet on another interface (not I), like incoming from A to B on J outgoing from B to A on K but NOT incoming from B to A on L outgoing from A to B on K because the state will only match the former two, but not the latter two. Now, to successfully match a state entry, an attacker needs to know (or guess) more than just the source and destination addresses. For TCP, he needs to know both ports and, more importantly, the current sequence numbers. We rely on the unguessability of sequence numbers, only the endpoints of a connection (and the few legitimate hops along the path between them) know these secrets. Obviously, if an attack were able to guess the secrets, he could attack your connections in a number of ways, anyway. So, try to think of a case where an attacker gains any advantage by being able to pass a packet incoming from A to B on J outgoing from B to A on K where he knows the connection secrets and couldn't just as well pass the packet on I (where it would pass, anyway). I guess it would have to be some very specific case where, for some reason, the attacker can only inject packets on interfaces other than I. I haven't seen a single example where this would matter in practice. But, yes, if worry about this, make your state if-bound to I, and this becomes a non-issue. My guess is that we might eventually switch to if-bound as default. I'm in favor of changing all examples in documentation to use it explicitely until then. But if anyone is claiming that the default of floating states leads to holes in rulesets of people unaware of the issue, I'd like to see an practical example attack. Daniel