by Lucian Gheorghe

Double NAT with Linux

News
Feb 23, 20076 mins

When you need to make a VPN connection between two networks using the same private address space, it’s time for a combination of source and destination NAT.

Our company opened a remote office in a Third-World country that didn’t have an Internet connection. The administrator hired in that location configured the local network with IP addresses in the private class C network 192.168.1.0/24.

After a while, they were able to install a permanent Internet connection with a static assigned IP address 1.2.8.1. The database server on their location has the same IP address as the database server in our location—192.168.1.60.

The configuration is the same as in the following figure:

In the headquarters location, we have:

• HQ local network: 192.168.1.0/24

• HQ database server: 192.168.1.60

• Linux Router 1 with two Ethernet interfaces: eth0, which connects to the local network and has the IP address 192.168.1.1, and eth1, which connects to the Internet with the IP address 1.2.7.1

In the remote location, we have:

• Remote local network: 192.168.1.0/24

• Remote database server in the remote location: 192.168.1.60

• Linux Router 2 with two Ethernet interfaces: eth0, which connects to the local network and has the IP address 192.168.1.1, and eth1, which connects to the Internet with the IP address 1.2.8.1

The next step is to create a VPN between these locations. On Linux Router 1 at the headquarters, we perform the following:

iptunnel add vpn1 mode gre remote 1.2.8.1 local 1.2.7.1 key 8132912

ifconfig vpn1 10.10.10.1 pointopoint 10.10.10.2 netmask 255.255.255.252

On Linux Router 2 at the remote location, what we do is:

iptunnel add vpn1 mode gre remote 1.2.7.1 local 1.2.8.1 key 8132912

ifconfig vpn1 10.10.10.2 pointopoint 10.10.10.1 netmask 255.255.255.252

In a normal situation, we would have a network at the headquarters and another network at the remote location, and we would route them on the vpn1 interface and not perform source network address translation (SNAT). As the heading says, this is not a normal situation. We can route on the Linux Router 1 network 192.168.1.0/24 through 10.10.10.2 (Linux Router 2), but it would have absolutely no effect, because the Linux kernel prefers directly connected routes (and it is normal to be this way).

In order for a computer from headquarters to communicate with a computer from the remote location, we have to “fake” the fact that we have different networks on each side. So, we will tell the headquarters’ computers that the computers in the remote location are in the network 192.168.20.0/24. We will also tell the remote computers that the computers in the headquarters location are in the network 192.168.10.0/24.

In the following example, we will show how the database servers can communicate, for example, for data replication. So, we will teach you how to map one IP, and you can do the same for the other 252 IP addresses (such as from 254, excluding the database server and the gateway).

From their point of view, the database server in headquarters is communicating with the database server in the remote location that has the IP address 192.168.20.60, and the database server in the remote location is communicating with the database server in the headquarters location that has the IP address 192.168.10.60. In fact, they both have the IP address 192.168.1.60.

Let’s configure Linux Router 1 (at the headquarters).

Step 1

ifconfig eth1:0 192.168.10.1 netmask 255.255.255.0

This is an optional step. IP packets with destination IP addresses in 192.168.10.0/24 will arrive at this router, and if we have no rules in the PREROUTING chain, we don’t want to forward them on the default route.

Step 2

route add –net 192.168.20.0 netmask 255.255.255.0 gw 10.10.10.2

This will add a route to network 192.168.20.0/24 via 10.10.10.2 on the vpn1 interface.

Step 3

iptables –t nat –A POSTROUTING –s 192.168.1.60 –d 192.168.20.60 –j SNAT –-to 192.168.10.60

This will create a SNAT rule on Linux Router 1 that will map the IP address 192.168.1.60 to 192.168.10.60 if the destination IP address is 192.168.20.60.

Step 4

iptables –t nat –A PREROUTING –d 192.168.10.60 –j DNAT –-to 192.168.1.60

This will create a destination network address translation (DNAT) rule for all packets arriving at Linux Router 1 having the destination IP address 192.168.10.60 to send the packets to 192.168.1.60.

This is all we need on Linux Router 1.

On Linux router 2, we do basically the same thing.

Step 1

ifconfig eth1:0 192.168.20.1 netmask 255.255.255.0

Step 2

route add –net 192.168.10.0 netmask 255.255.255.0 gw 10.10.10.1

This will add a route to network 192.168.10.0/24 via 10.10.10.1 on the vpn1 interface.

Step 3

iptables –t nat –A POSTROUTING –s 192.168.1.60 –d 192.168.10.60 –j SNAT –-to 192.168.20.60

This will create a SNAT rule on Linux Router 2 that will map the IP address 192.168.1.60 to 192.168.20.60 if the destination IP address is 192.168.10.60.

Step 4

iptables –t nat –A PREROUTING –d 192.168.20.60 –j DNAT –-to 192.168.1.60

This will create a DNAT rule for all packets arriving at Linux Router 2 having the destination IP address 192.168.20.60 to send the packets to 192.168.1.60.

This is the end of the configuration we need to make. Let’s see if it works both ways:

The database server at headquarters sends a packet to the database server in the remote location, which it thinks is 192.168.20.60. Since 192.168.20.60 is not directly connected to 192.168.1.60, it will forward the packet to the default gateway, Linux Router 1. Linux Router 1 checks out the PREROUTING chain and finds no rule to match this packet, and so it looks up the routing table for 192.168.20.60 and finds the best route through 10.10.10.2 on interface vpn1. Now, Linux Router 1 checks out the POSTROUTING chain and matches the rule that states that for every packet from 192.168.1.60 to 192.168.20.60, it should change the source IP address to 192.168.10.60. Linux Router 1 does that, and because of ip_conntrack it keeps a record of this connection. The packet with the changed source IP address is forwarded according to the routing table to 10.10.10.2 on interface vpn1.

Now, the packet arrives at Linux Router 2 at the remote location having the source IP address 192.168.10.60 and destination 192.168.20.60. Linux Router 2 looks in its PREROUTING chain and matches the rule that says to change the destination IP address to 192.168.1.60 if the packet is destined for 192.168.20.60. Linux Router 2 does this and then looks up 192.168.1.60 in its routing table and sees that 192.168.1.60 is directly connected with itself on Eth0. After analyzing the POSTROUTING chain and seeing that no rule matches this packet, Linux Router 2 forwards the packet to 192.168.1.60 as being from 192.168.10.60.

Packets traveling the other way around follow the exact same steps; so we can say “Mission Accomplished!”

This article has been adapted from the book, Designing and Implementing Linux Firewalls and QoS using netfilter, iproute2, NAT and l7-filter by Lucian Gheorghe. For further details, please visit https://www.packtpub.com/linux-firewalls/book.