1

I run several VPN connections that give me different external IP addresses. But these VPN servers often give me the same local IP address.

So I can end up with the following configuration:

eth0 [main ip address]
tun0 10.200.1.31
tun1 10.200.1.32
tun2 10.200.1.31

where eth0 is my main network adapter and tunX are virtual network interfaces created by OpenVPN

When I want to make requests from a specific VPN connection, I can bind a socket to an IP address (10.200.1.31 for instance). But I can not bind it to a specific interface (I can not manually choose tun2).

Once I bind it to a specific local IP address, I have an additional routing table (using iproute2) that tells the system to send packets coming from a local IP address to go through the corresponding network interface.

This works fine when each VPN interface has a different local IP.

But for tun0 and tun2, I will have two routing tables, one telling to route packets from 10.200.1.31 through tun0, and the other telling to route them through tun2. So the final route is unpredictable.

How can I overcome this issue?

I have two ideas, but I don't know how to implement them nor if they can work:

  1. Create a dummy interface for each VPN connection, with a unique IP address, and use iptables to somehow edit the source address of outgoing packets and send them through the proper VPN interface?
  2. or maybe is there a way to create a virtual NAT router that will do a similar job? What software should I been looking for?

EDIT:

I'm researching the first idea. I am trying to create a dummy interface dummy0 (with a unique local IP address) that will redirect all the packets to the VPN interface tun0.

Creating the dummy interface:

modprobe dummy
ifconfig dummy0 192.168.1.1 up

Redirecting the traffic from the dummy interface to the VPN:

iptables -t nat -A POSTROUTING -s 192.168.1.1 -j SNAT --to 10.200.1.31 -o tun0

Redirect the traffic from the VPN interface back to the dummy one:

iptables -t nat -A PREROUTING -d 10.200.1.31 -j DNAT --to-destination 192.168.1.1

Unfortunately, this doesn't work:

ping -I 192.168.1.1 google.com
PING google.com (173.194.40.132) from 192.168.1.1 : 56(84) bytes of data.
--- google.com ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1009ms

Do you have an idea why?

  • I ran into something similar with a physical interface and was led to look into policy routing - blog.scottlowe.org/2013/05/29/… - I could not get it to work but maybe it will be helpful. – LawrenceC Nov 18 '14 at 22:16
  • I'm already using policy routing (iproute2), but it's not enough, because routes are calculated based on the source IP address, and I might have to identical source IP addresses leading to two different network interfaces. – alexpirine Nov 19 '14 at 6:40
1

I found out that the solution was quite simple:

First, we create enough dummy interfaces:

modprobe numdummies=254

Than we do three things:

  • Set up a dummy interface to be able to bind to the unique IP address of the dummy interface
  • Avctivate IP masquerade on each VPN interface
  • Setup a rule that tells to use the routing table associated to the VPN interface for packets comming from the IP of the dummy interface

This can be implemented by the following shell script:

for n in {0..253}
do
  n1=`expr $n + 1`
  ifconfig dummy$n 192.168.42.$n1/32 up
  iptables -t nat -A POSTROUTING -o tun$n -j MASQUERADE
  ip rule add from 192.168.42.$n1 lookup tun$n
done

My routing tables look like this, example for tun0:

default via 10.200.0.1 dev tun0
10.200.0.0/22 dev tun3  scope link  src 10.200.1.31

The job is done!

0

I believe the crux of your problem lies in the statement:

somehow edit the source address of outgoing packets

I do know that I have never been able to set the IP address of outgoing packets to anything but the base IP of the interface. I believe the kernel networking code is designed to work this way due to the overhead of keeping track of which interface should this packet go out on.

You may need to look at the network drivers, and perhaps do some mods there.

If you DO manage to mangle the IP outside of the kernel, beware of the performance penalty you will pay for the logic.

  • What about adding a dummy network interface, assign a unique IP address, and then redirect the packets going to this dummy interface to the VPN interface, while replacing the source IP address by the IP of the VPN interface (and vice-versa for the incomming packets). I guess I have to use NAT capabilities of iptables, but I didn't manage to make it work. P.S. I will edit my question to include what I've done. – alexpirine Nov 18 '14 at 21:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.