Subject: Re: stopping PF NAT state from "floating" ?
To: None <tech-net@NetBSD.org>
From: David Young <dyoung@pobox.com>
List: tech-net
Date: 05/07/2007 02:50:55
On Mon, May 07, 2007 at 04:40:40PM +1000, Daniel Carosone wrote:
> On Mon, May 07, 2007 at 01:01:47AM -0500, David Young wrote:
> > I am using PF for NAT.  I would like to stop NAT states from floating
> > between interfaces.  I have searched all day for a solution, but I have
> > not found one.  Does anyone know how?
> 
> First question, if this is a "flow" where changing the IP addressing
> within the "flow" when the routing changes doesn't break the
> application, is whether you need a persistent NAT state at all.

For the application to work, the state does have to persist.  What is
more important is the network, I think:

                                 Router A                Router B
                             |  +---------+             +---------+
   __     ___                |  |         |             |         |  a.b.c.d
  /  \___/   \               |--|admsw0   |             |     sip0|--+
  \ the (ugly)| +----------+ |  |         |             |    (NAT)|  |
  /  Internet |-|NAT router|-|  |     ath0|-- 10.0/16 --|ath0     |  |
  |     _    /  +----------+ |  |_________|             |_________|  |
   \___/ \__/                |                                       |
           |                 |                                       |
           |           192.168.1/24                                  |
           |                                                         |
           +---------------------------------------------------------+

a.b.c.d is a globally routable IP address.  Router B NATs 10/8 to a.b.c.d.
Router B neither knows a route to 192.168.1/24, nor should it.  So there
is no sense in translating an address in 10.0/16 to 192.168.1.4 before
sending it out ath0 on Router A.  Nevertheless, that is what is happening.

> Alternately, could you try tagging these flows, and when the route
> changes, flush all states with the tag.  I don't know pf enough to say
> whether there's a way to do that.

Letting the states time-out in the usual way is more desirable than
flushing them when the route changes.  The route may change from sip0
to admsw0, and change back to sip0 a moment later; if that happens,
it is nice to have state on sip0.

> > I thought that 'set state-policy if-bound' would help, but I have found
> > out in other experiments that it will not.  I believe I understand why not
> > after reading the PF sources, especially sys/dist/pf/sbin/pfctl/parse.y
> > and sys/dist/pf/net/pf.c.
> 
> Hm, I'd have expected the same. Does it make any difference if you
> specify it on the rule rather than as a global pref?

You cannot specify the state policy of a NAT rule.  At least, not as
far as I can tell by reading pf.conf(5) and the source code.

Dave

-- 
David Young             OJC Technologies
dyoung@ojctech.com      Urbana, IL * (217) 278-3933