On Fri, Aug 30, 2002 at 02:08:41PM +0200, Clemens Dumat wrote:
> I tried to apply a route-to on tun0 to get this packet to de0, but i can't get
> it to work. Are 'route-to' pf-rules really treated differently than 'normal'
> rules (as show in http://mniam.net/pf/pf.png), or are they treated just like any
> other filter-rule and skipped when a state is applicable?
Ok, this is a little tricky, so let me first explain how rules, states
and route-to works in pf, then let's see how this affects your specific
situation.
When a packet goes through pf, pf first does a state table lookup. If
the packet matches a state, it's passed. Otherwise, the rule set is
evaluated, and the last matching rule either blocks or passes the
packet, and in the latter case optionally creates state.
The first packet of a connection never matches a state. If the last
matching rule contains a 'route-to' option, the packet is routed to that
interface. If the rule also creates state, the rule that creates it is
stored in the state entry. Further packets of this connection in the
same direction will also honor the route-to interface, if that
information is still available through the state -> rule that created
the state -> route-to option chain (which is broken, for instance, when
you reload the rule set, which clears all rule pointers in all active
states). So, in general, all (outgoing) packets of that connection will
be routed through the specified interface.
Another point is that translated packets (rdr, nat, binat) will
automatically create state when they're passed, even if the last
matching rule does not have the 'keep state' option.
So, let's look at your case.
The initial packet comes in on de0 and gets its destination address
translated to 192.168.0.100. A state lookup happens, but there is no
matching state. So the rule set is evaluated. The last matching rule is
> pass in quick on de0 inet proto tcp from any to any port { http }
So the packet gets passed, and since it was translated, implicitely
creates state. A pointer to the last matching rule is stored in the
state entry.
Now the web server 192.168.0.100 replies with a SYN+ACK to the external
browser. The firewall will try to route this packet out to its default
gateway, so pf gets to filter it on tun0. The state lookup finds the
existing state, so the packet gets passed. The rule that created the
state does not have a route-to option, so the packet is not routed to
another interface, and goes out through tun0. There's no rule set
evaluation at all, and the rule
> pass out quick on tun0 route-to de0:$WLANGate inet proto tcp \
> from any port { http } to any
never matches.
That explains what you see.
So, basically, route-to was made to route _outgoing_ connections through
different interfaces. What you want is a kind of 'route-from', that
affects where replies to _incoming_ connections are routed through. That
doesn't exist yet, I'm afraid. Maybe someone else has an idea how to
achieve the same with the existing options, I can't think of an simple
solution yet.
> A point that could confirm, that packets are treated the same, whether or not
> they have a routing section like 'route-to' in them, is that incoming
> connections aimed for the router (e.g. ssh) work with these rules (that is, when
> there is no state), but only as long as i don't keep state on these incoming
> connections!
Yes, that's because there is no translation creating state implicitely
in this case.
Daniel