# PF + 2 Nat



## jailed (Feb 6, 2011)

Hello,

First of all, I'm not sure that 2 Nat on same server is possible. I have 2 different internet service. DSL and Cable. I've two gateway server but I wanted to connect both 2 internet onto one server for power consumption.

Here's my pf.conf (ip addresses are sample, they are different in production)


```
interface_1="rl0" # STATIC IP
interface_2="rl1" # DHCP

nat_1="{ 192.168.0.2, 192.168.0.3 }"
nat_2="{ 10.0.0.2, 10.0.0.3 }"

nat on $interface_1 from $nat_1 to any -> 192.168.0.1
nat on $interface_2 from $nat_2 to any -> 12.34.56.78 # ip leased from dhcp

pass all
```

Now, nat 1 is working without any problem. The machines using the ($nat_1) ip addresses are connecting to internet over interface_1

The problem is, nat 2 is not working. The machines in the network see each other but can't connect to internet via interface_2

Waiting for your helpful posts. I hope that 2 nat on same machine is possible.

Thanks.


----------



## lbl (Feb 7, 2011)

Hi

Im not sure you can do that on a FreeBSD box, it's the routing table that decides wich interface/default gateway the packet has to follow out ...

And in the FreeBSD's man page for pf.conf it states under bugs:


```
Route labels are not supported by the FreeBSD route(4) system.
Rules with a route label do not match any traffic.
```

If you figure it out please post the solution 

/lbl


----------



## dbi (Feb 7, 2011)

Perhaps:


```
interface_1="rl0" # STATIC IP
interface_2="rl1" # DHCP

nat_1="{ 192.168.0.2, 192.168.0.3 }"
nat_2="{ 10.0.0.2, 10.0.0.3 }"

nat on $interface_1 from $nat_1 to any -> 192.168.0.1
nat on $interface_2 from $nat_2 to any -> 12.34.56.78 # ip leased from dhcp

pass all

pass from $nat_1 route-to ( 192.168.0.1, $ISP1_GW )
pass from $nat_2 route-to ( 12.34.56.78, $ISP2_GW )
```


----------



## jailed (Feb 7, 2011)

Thanks for your replies.


```
pass from $nat_1 route-to ( 192.168.0.1, $ISP1_GW )
```

This doesn't works. I replaced the $ISP1_GW with the real IP.

pfctl points syntax error.

I see this example of route-to on several pages. However, even if I tried all combinations, always I get syntax error.

I run the conf with pfctl -f pf.conf


```
No ALTQ support in kernel
ALTQ related functions disabled
/etc/pf.conf:27: syntax error
```


----------



## dbi (Feb 7, 2011)

Sorry, I guess I've made a syntax error. Unfortunately I have no way to test the syntax.
I believe "route-to" should solve your problem though.

Added:

I guess the error is generated because there is no direction given in the rules. Please, try modifying the last two rules like this


```
pass out route-to ( 192.168.0.1, $ISP1_GW ) from $nat_1
pass out route-to ( 12.34.56.78, $ISP2_GW ) from $nat_2
```


----------



## jailed (Feb 7, 2011)

@dbi

I've already tried your modified version. Tried both "pass" and "pass out".


----------



## dbi (Feb 7, 2011)

jailed said:
			
		

> @dbi
> 
> I've already tried your modified version. Tried both "pass" and "pass out".



Did it work? (btw, I've swapped the places of "from" and "route-to" in my previous post)


----------



## jailed (Feb 7, 2011)

Sorry, I didn't realized swapped places. I've just tried and there's no syntax error. Configuration is worked.


```
pass out route-to ( 192.168.0.1 $ISP1_GW ) from $nat_1
pass out route-to ( 12.34.56.78 $ISP2_GW ) from $nat_2
```

There shouldn't be commas before gateways for true syntax.

But, still not working for me. The second lan can't connect to internet over second internet.

I can ping the local machines but can't ping WAN.


----------



## jailed (Feb 7, 2011)

Update:
when 2 "nat on" line is active, if I restart the server, both 2 lan can't connect to internet over both DSL and Cable.

If I remove the ethernet cable of second internet and restart the server; the primary internet works again.


----------



## jailed (Feb 7, 2011)

All servers on LAN use 8.8.8.8 (google's dns) as name server.

I can't ping even ip addresses on WAN, not only domain names. I can ping all the servers in LAN, and routers but can't ping WAN ip addresses.


----------



## kpa (Feb 7, 2011)

How do these addresses 192.168.0.2, 192.168.0.3 and 10.0.0.2, 10.0.0.3 relate to this "server"? Are they the other machines on the same LAN or just ip addresses/aliases on its interfaces? Post the output of `$ ifconfig -a`.


----------



## jailed (Feb 7, 2011)

There is 5 ethernet card on this server.

2 of them is for internet connections.
3 of them is for internal LANs for other servers to connect to internet.
This 3 ethernet nic has their own ip and they are routers of the 3 LAN.

For example
192.168.0.0/24 belongs to rl2 (LAN 1)
10.0.0.0/24 belongs to rl3 (LAN 2)
172.16.0.0/24 belongs to rl4 (LAN 3)

They aren't on the same nic.

For example, I want to connect the servers connected to LAN 1 to internet over rl0 (internet 1)
Or LAN 2 servers to connect to internet over rl1 (internet 2)

I've had 2 separate gateway servers for each internet but I want to migrate them. And have only one gateway for both 2 internet and 3 LAN.

Servers has 5 ethernet cards at all. And all networks/subnets has their own card.


----------



## kpa (Feb 7, 2011)

That starts to make more sense now... I think what you need is "pass in" rules with route-to instead of "pass out". The reason is that policy based routing should be applied to incoming traffic on an interface, not outgoing (routing decision already made, no way to do routing again). So something like this:


```
pass in on $interface_n route-to (12.34.56.78 $ISP2_GW) from $nat_2
```

Where interface_n is the matching "LAN" interface for nat_2.

Edit: You can probably write the route-to with the name of the interface instead of the ip address assigned to it, so the above becomes:


```
pass in on $interface_n route-to ($interface_2 $ISP2_GW) from $nat_2
```


----------



## jailed (Feb 7, 2011)

I tried both of them but not working. The servers on LAN 2 can ping the router of internet 2, but can't ping e.g 8.8.8.8 (google).

---
To clear some other thing about pf,
`# pfctl -f pf.conf` reload the rules, right? Is there need to `# /etc/rc.d/pf restart`

If I reload the configuration, anything changes on internet 2. When I restart pf, internet 1 goes down too. And I have to remove the link of internet 2 and restart the server.
---


----------



## kpa (Feb 7, 2011)

`# /etc/rc.d/pf reload` is enough to reload the rules. Try changing the nat rules to:


```
nat on $interface_1 from $nat_1 to any -> ($interface_1)
nat on $interface_2 from $nat_2 to any -> ($interface_2)
```

This way you don't have to keep track of the ip addresses assigned to interface_1 and interface_2.


----------



## jailed (Feb 7, 2011)

@kpa, thanks for your last post.

I don't know if I'm right but I've thoughts about our rule,


```
pass in on $interface_2 route-to ($interface_2 $ISP2_GW) from $nat_2
```

This is for incoming packages (pass in). But we say "from $nat_2" on the end of the line. $nat_2 is the IP addresses who will use this nat to connect to internet. Is it reasonable? Pass in the packages from local lan and route?


----------



## kpa (Feb 7, 2011)

It says "allow incoming traffic on $interface_2 from $nat_2 (to any) and route packets matching this rule directly to $ISP2_GW via $interface_2, bypassing the default routing table". The nat rule rewrites the source addresses on those packets to the ip address assigned on $interface_2 since they are routed to go out via $interface_2.


----------



## jailed (Feb 7, 2011)

Wow 

I read your these words for about 10 times:

```
"allow incoming traffic on $interface_2 from $nat_2 (to any) and
route packets matching this rule directly to $ISP2_GW via
$interface_2, bypassing the default routing table"
```

After reading them over 10 times I found the problem 

Our $interface_2 is the NIC that connected to internet modem. There is no incoming package to it. The packages come to LAN NIC.

The rule must be like that:

```
interface_2="rl1"
lan_2="rl4"
router_2="12.34.56.78"

pass in on $lan_2 route-to ( $interface_2 $router_2 ) from $nat_2
```

$lan_2 and $interface_2 is different NICs.

And now it works perfect 

Thanks again.


----------

