Tag Archives: VPN

VPN Server and Routing issues (arping)

Like many other people I have a network behind a NAT. The router providing the NAT has a real world routable IP (and a domain name using DynDNS). The router can forward ports to machines inside. So, I installed a VPN server (poptop) on a local machine. My setup:

  gateway: 192.168.0.3
  vpnserver: 192.168.0.2

I configure poptop to use the following IPs:

  #options.pptpd 
  localip 192.168.0.240
  remoteip 192.168.0.241-242

As I now connect, from the internet, to the VPN server, I get IP 192.168.0.241 (or 242), and the VPN server itself holds IP 192.168.0.240 on its ppp-device.

The VPN client can now connect to the VPN server, and the other way around. What doesnt work though is:

  1. VPN client can not connect to other local machines
  2. VPN client can especially not connect to the local gateway, and thus not access the internet via VPN

What is the problem? The other machines on the network:

  1. does not know who has IP 192.168.0.241 and can not reply to it directly
  2. does not have the VPN server (but the gateway) as default gateway

Fixing routing table
One way to fix this is to add a host entry on a local machine. On Linux that would be:

  # route add -host 192.168.0.241 gw 192.168.0.2

(route is similar but the details are different in every OS).
Well, this works, but it sucks because you have to do it on every local host. It sucks even more if you have a NAT-machine that you cannot run the route command on, because then you can anyway not access the internet via VPN anyway.

ARP-hack
I found a solution I liked better. There is a command called arpspoof. Chances are you dont have it :( . What it does is that it sends out pings to machine A, pretending it is machine B. That way, machine A will send its packages to you, instead of to machine B. Normally, that is not such a legitimate thing to do.

However, there is another program that you might have on your VPN server; arping. This program does what arpspoof does, but it doesn’t lie if you ask it to. But it doesn’t need to know it lies, does it? I wrote this little script (works on linux – requires bridge-utils – run it on the VPN server):

  #!/bin/sh
  brctl addbr tmpbr
  ifconfig tmpbr 192.168.0.241
  arping -c 1 -U -I eth0 -s 192.168.0.241 192.168.0.3
  ifconfig tmpbr down
  brctl delbr tmpbr

So we bring up a temporary virtual network interface (tmpbr). We assign it the IP we would want other computers to believe us to have. We send an arp-ping through our normal network interface (eth0), but from the IP of the VPN-client, to the default gateway. Then we bring down tmpbr.

Now, our gateway (192.168.0.3) believes the vpn server has IP 192.168.0.241 (which is actually true). And beyond my knowledge, it seems the other computers on the network learn this thing too :) But they forget quickly if they dont use the information, so you need to run the above script often (like every minute).

You can run the arping command with slightly different switches and still be successful. This worked and made sense to me.

My VPN server happens to run OpenWRT. Both arping and bridge-utils are included by default. If you let the VPN-server be installed on your NAT-router everything is easier. You can also make some things work fairly well setting up a NAT-server on the VPN-server as well, making double NAT to the internet.

Windows VPN on Linux and Qemu

How to connect to a Windows VPN-server using Linux? In my case PPTP was not allowed; I was required to use L2TP and a certificate (plus domain\user and password of course). All my attempts with OpenVPN, Network Manager and Mac OS X were in vain – only Windows VPN clients seemed to work. I wanted to connect from Linux, and was successful with the following strategy:

  1. Install Windows 2000 under Qemu
  2. Configure VPN in virtual machine and share it
  3. Route VPN traffic to virtual Windows machine

My linux machine is located behind a NAT (192.168.0.2) on the 192.168.0.* network.
The network behind VPN is 10.2.*.

Windows and Qemu
I will not write a guide on how to install Windows on Qemu. But, Windows 2000 or later should work. Pick up TinyXP if you dont have a problem with it. Older version of Windows means less disk/ram usage, and you will only use it as a VPN-client anyways. On 2000/XP check out MS knowledge base article 818043.

I used real network mode in Qemu (ie a tap-device). So, I configured a bridge (br0) device, that you I connected both eth0 and tap0 to. See example below for some help. Perhaps -net user can work as well (but be aware that the Windows must have IP=192.168.0.1, see below).

Configure and Share VPN in Windows
Configuring Windows to connect to the VPN should be very easy. When you are done, right-click on your VPN connection and choose the Sharing-tab. Check “Enable Internet Connection Sharing for this connection”. Now happens something weird – the Windows machine has to have IP=192.168.0.1! You have to accept that, and hopefully your local network can be 192.168.0.* and the network you want to connect to is not 192.168.0.*.

Route VPN-traffic to Windows machine
For me, the following command on the linux machine is enough:
sudo route add -net 10.2.0.0/16 gw 192.168.0.1
Now try to ping or ssh to something on the 10.2-network. You might want to change your DNS to a DNS on the VPN.

Qemu-startup-script
I use the following script to start my Qemu machine:

  sudo route add -net 10.2.0.0/16 gw 192.168.0.1
  sudo tunctl -t tap1
  # sudo brctl addif br0 tap1
  sudo qemu -m 128 -net nic -net tap,ifname=tap1 vpn2000.qcow
  # sudo brctl delif br0 tap1
  sudo tunctl -d tap1
  sudo route del -net 10.2.0.0/16 gw 192.168.0.1

I really have no idea why I dont need to connect br0 to tap1, but it happens automatically :)

My working routing table looks like this:

  Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
  192.168.0.0     *               255.255.255.0   U     0      0        0 br0
  10.2.0.0        192.168.0.1     255.255.0.0     UG    0      0        0 br0
  link-local      *               255.255.0.0     U     1000   0        0 br0
  default         192.168.0.2     0.0.0.0         UG    100    0        0 br0