route-to rule.

Stephane Raimbault segr at
Wed Jan 26 08:42:08 PST 2005

Well this made a lot of sense.. thanks for the info, and now I've resolved 
that problem... so to recap my situation.

I have a FreeBSD-pf box with the following interfaces:

rl0 - Internal lan (
rl1 - ISP #1
rl2 - ISP #2
tun0 - OpenVPN Tunnel to remote office (

Right now, my pf.conf allows me to do a few things,

1. nat lan traffic out ISP #1 (this is my default ISP, however I'd like the 
non servers go out ISP #2)
2. binat server traffic out ISP #1 (this is good as we want our servers only 
to respond out specific IP's on ISP #1)
3. we have rl2 responding to pings, however can't seem to get nat traffic 
over to rl2 without causing problems with our tunnel to our remote office
4. we have our traffic destined for our remote office working with static 
routes initialized when the vpn creates the tunnel.

What I'm trying to get working is to have our lan traffic go over the nat on 
rl2 (ISP #2) rather then rl1 (ISP#1) at the same time having our binat 
traffic still go over ISP #1 and our vpn traffic go over the tun0 interface. 
  This is quickly becoming no small feat.

Here is my current pf.conf file as it stands:

ext_gw1="<ISP#1 Gateway IP>"
ext_gw2="<ISP#2 Gateway IP>"

server1_out="ISP #1 External IP #2"
server2_out="ISP #1 External IP #3"
server3_out="ISP #1 External IP #4"
server4_out="ISP #1 External IP #5"

nat on $ext_if1 from $int_net to any -> ($ext_if1:0)
nat on $ext_if2 from $int_net to any -> ($ext_if2:0)
binat on $ext_if1 from $server1_int to any -> $server1_out
binat on $ext_if1 from $server2_int to any -> $server2_out
binat on $ext_if1 from $server3_int to any -> $server3_out
binat on $ext_if1 from $server4_int to any -> $server4_out

pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any

Any input would be much apreciated as always.

>From: Daniel Hartmeier <daniel at>
>To: Stephane Raimbault <segr at>
>CC: dionch at, freebsd-pf at
>Subject: Re: route-to rule.
>Date: Wed, 26 Jan 2005 00:45:13 +0100
>On Tue, Jan 25, 2005 at 04:22:45PM -0700, Stephane Raimbault wrote:
> > Looking into audities... it seems that the nat that goes across this 
> > right now:
> >
> > nat on $ext_if1 from $internal_net to any -> ($ext_if1)
> >
> > seems to round robin the external IP as I have several IP's aliased on
> > $ext_if1 if I replace the above line with this:
> >
> > nat on $ext_if1 from $internal_net to any -> ($ext_ip1)
> >
> > where $ext_ip1 is the external IP I want the nat to go out, however when 
> > do this... the lan can no longer establish new connections... any 
> > on this?
>You can put () around an interface name, meaning 'dynamic interface name
>to address translation'. In the first example, as you noted, this means
>pf will round-robin through all addresses of the interface to pick a
>source address for NATed connections.
>The second example makes no sense. If what you want is to use a constant
>source address for NAT, just use
>   -> $ext_ip1
>without the parentheses. If you expect $ext_if1 to change its address
>dynamically, and you want to use its 'main' address as replacement (but
>not round-robin through aliases, if it has any), use
>   -> ($ext_if1:0)
>If you want still something else, please explain.
>What you actually have in your second example is (surprisingly) not a
>syntax error, but
>   -> (
>Which means the interface with name "". There is no such
>interface, of course, but since pf accepts non-existant interfaces
>(which could exist later on, think USB or PCMCIA nics), it accepts this.
>It's still non-sensical, don't use () around IP addresses. :)

Take advantage of powerful junk e-mail filters built on patented Microsoft® 
SmartScreen Technology. 
  Start enjoying all the benefits of MSN® Premium right now and get the 
first two months FREE*.

More information about the freebsd-pf mailing list