On Fri, Apr 05, 2013 at 07:03:52PM +1100, Cameron Simpson wrote: > I was imagining NATing on an internal virtual interface to a private > address on some kind of internal virtual interface; this might keep > the necessary state without being the outmost layer. > > And then to do stateless filtering of RSTs on the real physical > external interface (because the NAT states are not present there, > or even if floating, will not match), and then have some kind of > stateless binat or other rewrite of the remaining non-RST packets > from the real external address to the private address used for the > NAT.
I guess you have already considered the obvious solution of adding a second device (stateless filtering bridge) justs to drop the RSTs. While it may seem a waste of parts and electricity, it's much simpler than trying to route a connection through the same device multiple times. Is it a router or a bridge now? If a router, you'd probably have to use rtables to trick the stack, see http://www.packetmischief.ca/2011/09/20/virtualizing-the-openbsd-routing-table/ If you have two spare physical interfaces, a patch cable between them would be simple and produces non-surprising interaction with pf. I don't know which (if any) virtual interface would help. > | However, you can filter statelessly on the internal interface (the > | states won't match there (wrong direction, if-bound), dropping outgoing > | TCP RST, passing everything else. > > Won't the RST packets shut down the TCP states as they traverse to > external interface? The RST packets will cause the state entries to show up in pfctl -ss as TIME_WAIT:TIME_WAIT, but that doesn't make them not match further packets. The only effect is that the entries will time out (when idle!) with tcp.closed (90s by default) instead of tcp.established (24 hours). You can increase tcp.closed, the downside is that the entries will stay around longer, even you'd want them to be purged. Daniel