Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Nov 2012 10:21:21 -0500
From:      Kevin Wilcox <kevin.wilcox@gmail.com>
To:        Peter McAlpine <peter@aoeu.ca>
Cc:        freebsd-pf@freebsd.org
Subject:   Re: Routing return NAT traffic based on interface
Message-ID:  <CAFpgnrO3o1==XtxDK__KmEhX1C947DHhj5N_NptKomFBba3fzQ@mail.gmail.com>
In-Reply-To: <CAEDV4ypAo21-4KYws0LTxC%2BXSNNtSmWvMpvFGro6BqNH2z==Wg@mail.gmail.com>
References:  <CAEDV4ypAo21-4KYws0LTxC%2BXSNNtSmWvMpvFGro6BqNH2z==Wg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 16 November 2012 09:40, Peter McAlpine <peter@aoeu.ca> wrote:

> data_if = "tap3"
> ext_if = "em0"
> set skip on lo0
> nat on $ext_if from !$ext_if:network to any -> ($ext_if)
> pass in on $ext_if route-to $data_if from any to !$ext_if:network

> The issue I'm having is that the 'pass' rule is not being matched (or
> even evaluated?). My default gateway on the router is the ext_if and
> return traffic is being reverse-translated and then the routing table
> is sending it back out ext_if instead of down data_if where I want it
> to go.

That's because that's what your NAT rule is telling it to do.

Your rule says "if I see traffic on the external interface that isn't
on the same network as the external interface, NAT it back out the
external interface"

Your pass rule should never be used. Your external interface should
never see traffic coming into it that isn't destined for it.

pf is smart enough to handle the return NAT traffic.

I think you may have a misunderstanding of how NAT works.

For simplicity sake, I'll use a fake internal network of 10.10.10.0/24
and an outside Internet IP address of 4.4.4.4. Let's pretend the
internal interface has an IP of 10.10.10.254 and is the gateway for
the 10.10.10.0/24 network and that we will NAT their outbound traffic.
Now let's pretend there is a web-server at 25.25.25.25.

When a computer inside my internal network, let's say 10.10.10.10,
wants to get to 25.25.25.25, it hits the gateway of 10.10.10.254. That
router then NATs the traffic. 25.25.25.25 sees a connection request
from 4.4.4.4. It sends back a reply. The router at 4.4.4.4 sees the
return traffic and pf checks its state table. It then changes the
destination for that traffic to be 10.10.10.10 and passes it out the
10.10.10.254 interface. The whole point of RFC-1918 is that anyone can
re-use those IPs internally without conflicting with anyone else
because the IP seen by everyone else on the Internet is the *outside*
IP.

A pf configuration to do that would look something like:

==================

int_if=tun0
ext_if=em0
set skip on lo

nat on $ext_if from $int_if:network to any -> $ext_if
pass in on $int_if from $int_if:network to any keep state
pass out on $ext_if from any to any keep state

==================

Yes, that is being overly verbose and uses a little older syntax (keep
state, from any to any ) but it works on both OpenBSD and FreeBSD, and
it works on every release within the last few years (I still have
early 4.x OpenBSD routers and 7.x FreeBSD routers).

Keep in mind that that configuration is *wide open*.

kmw



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAFpgnrO3o1==XtxDK__KmEhX1C947DHhj5N_NptKomFBba3fzQ>