Linux – 1:1 NAT with several identical LANs

linuxopenvpnrouting

I want to connect several LANs located on remote buildings.
The "central" site have a Linux computer running OpenVPN. Each remote site also run OpenVPN.

  1. the central site has a LAN numbered 192.168.0.0/24
  2. several remote sites are also numbered 192.168.0.0/24
  3. I can't/won't/don't want to/whatever modify LAN numbering
  4. I don't have control on most remote OpenVPNs

I then need to :
1. define virtual LANs
2. configure a 1:1 NAT for each site
3. the 1:1 NAT has to be configured on the central router

LAN map
.
So each site is seen to have a 10.10.x.0/24 LAN.
When a computer want to reach, say, 192.168.0.44 on site 12, it just have to send a paquet to 10.10.12.44

Operating a VPN is not a problem for me. I currently connect 60+ sites. But I don't find a simple way to do this 1:1 NAT.

Here is an example of a packet sent from the central site to a remote site, and its response packet :

enter image description here

I did some tests with iptables NETMAP but I can't manage to make it work because I don't find a way to modify source+destination after routing decision.
I prefer to avoid the new --client-nat OpenVPN's feature.
Maybe I have to force routing with ip route ? Or to loop twice into the network stack with veth ?

Note : I don't want to use masquerade. Only 1/1 NAT.

EDIT :
It's not possible with a regular openVPN setup. Because a packet from a remote site is indistinguishable from a packet from another site : both have similar source and destination addresses, and both come from the same tun (or tap) interface. So it's not possible to source-NAT it.

Solution 1 : do the NAT on the remote sites. Not possible in my case. I have to do it only on the central site.

Solution 2 : setup one VPN for each remote site. So I'll have one tun for each. I think this can be ok. Not very memory efficient but ok.

Solution 3 : setup a (unencrypted) tunnel inside the VPN for each site. This will give one interface for each. Simple tunnels are are not cross-platform (to my knoledge). For example GRE or ipip or sit are ok for Linux, but some distant sites are running only one Windows computer, so openVPN is installed on it. So impossible to setup a simple tunnel.
Other option is to use a more complicated tunnel (wich ?) but the overhead on the system and on the sysadmin may be bigger than having multiple VPNs

Solution 4 : compile the latest openVPN, because its include a 1:1 NAT feature.
I test this this week.

Best Answer

A very basic solution is :
1. use OpenVPN 2.3 or more (currently, the latest is 2.3-alpha) for server + clients
2. use the OpenVPN configuration option below
3. don't use anything else (no ipfilter, no tricks)

On the server side, you need to manually distribute VPN addresses (so no server option, you have to use ifconfig or ifconfig-push) :

# /etc/openvpn/server.conf
ifconfig 10.99.99.1 10.99.99.2
route 10.99.99.0 255.255.255.0
push "route 10.99.99.0 255.255.255.0"
push "client-nat dnat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat dnat 10.99.99.12 255.255.255.255 10.10.112.12"
push "client-nat dnat 10.99.99.13 255.255.255.255 10.10.113.13"

The route and push route and client-nat lines are required if you want to communicate directly between routers (ping 10.99.99.1 from a distant site throught the VPN). Else you can discard them.

.

.

Now you have to choose a virtual network address. I kept the same you used in your example : 10.10.0.0/16
You allow routing for this :

# /etc/openvpn/server.conf
route 10.10.0.0 255.255.0.0
push "route 10.10.0.0   255.255.0.0"

.

.

You have now to instruct the client to use the 1:1 NAT :

# /etc/openvpn/ccd/client_11
ifconfig-push 10.99.99.11 10.99.99.1
push "client-nat snat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat snat 192.168.0.0 255.255.255.0 10.10.11.0"
push "client-nat dnat 10.10.10.0 255.255.255.0 192.168.0.0"
iroute 10.10.11.0 255.255.255.0
iroute 10.10.111.0 255.255.255.0

The first line set the remote router address. Beware about Windows driver requiring special addresses.
The second and last lines allow the distant router to communicate from its 10.99.99.x interface.
Third and fourth lines do the source and destination 1:1 NAT
The fifth line tells OpenVPN what to do with the corresponding packets.

This method allow to connect sites with identical (or not) LAN addresses, without any shadowed host.

Related Question