Monday, January 6, 2014

Using an Android phone as a secure OpenVPN Gateway

I'm running a small OpenVPN setup at home, through which I can connect to my home network from various places securely and safely. I really like OpenVPN. It's robust, safe and fairly easy to set up. There is only one small caveat - it is not a standard VPN client in Windows. In order to use it, an OpenVPN client is required. Such client exists, of course, and it's can be downloaded and installed on any computer. There are occasions, though, that downloading and installing software is either impossible or inappropriate. For example, using a company provided notebook computer or a friend's computer.
One way to overcome this limitation is to use of an Android smartphone as a VPN gateway. The phone runs OpenVPN and has access to the private network. The client computer is tethered to the phone and set up in such way that access to the private network addresses from the PC is routed through the phone and forwarded over the secure tunnel. This is the ideal solution - the computer doesn't have to know anything about OpenVPN, no software has to be installed and no key has to be deployed. The only tweak required - sometimes - on the PC side is adding an entry to the routing table. In Windows 7 it seems that it can even be done without administrative privileges.
In order for this setup to work, some tweak are required on the phone side. The remaining of this post explains more about it.


First of all - a rooted Android phone. Mine is a Samsung Galaxy S-II (also known as GT-I9100) with CyanogenMod ROM. I've never tested this procedure on any other phone, but I'm sure it will work on most of them.
The second requirement is a working OpenVPN setup. I won't get into the details of this setup, there are plenty of tutorials on the Internet. When OpenVPN works computer-to-computer, it's very easy to migrate it to the phone - just install the OpenVPN client from Google Play, put the configuration files on an SD card and let OpenVPN on the phone know where the files are.


We will use the iptables utility to instruct the phone to forward IP traffic through the secure tunnel. For the sake of the discussion, let me assume that the private network is on the subnet.

The first step is instructing the phone to forward packets to/from the secure tunnel (tun0) and Masquerade them:

iptables -I FORWARD -i tun0 -j ACCEPT
iptables -I FORWARD -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE     

These commands can be entered directly using a phone terminal software (such as the one installed by default when installing CyanogenMod on the phone), or better using an SSH server such as this one.

The second step is to enable packet forwarding from the interface tethered to the PC. There are multiple options here, and it may be necessary to detect which of the network interfaces is use for which purpose. This can easily be done with the netcfg command on the phone. Run it once, without the tethering and the once again with the tethering activated. The network interface that was used for this purpose should go from DOWN to UP state, and an address should appear. In my phone, the interfaces are wlan0, rndis0 and bt_pan for WLAN, USB and Bluetooth tethering respectively.
And now back to the iptables command:

iptables -I FORWARD -o rndis0 -j ACCEPT 
iptables -I FORWARD -i rndis0 -j ACCEPT

(replacing rndis0 with the appropriate interface name).

Finally, we have to tweak the routing table on the PC to redirect the traffic of the private network to the right place. This step is not always required - if the PC's only network connection is the phone, this will happen naturally.
For all other cases, a new route is required. The routing table on Windows is managed using the route utility. First, open a command line window. In Windows 8, it must be run as an administrator. Now, we'll have to identify the network interface used for the tethering:
route print

This command prints the routing table, but in this stage we're only interested in the header of the result, the one listing the network interfaces on the computer:

In the case of Bluetooth tethering the first interface in the example is the one being used. In the case of WLAN tethering we'll select the wireless LAN adapter (not shown) and in the case of USB tethering it is shown as USB to Ethernet adapter. The first number in each line is the interface number.
Now, the route is created as follows:

route add /p mask route if 23

This address is the address of the private network; the address is the phone's address (on the tethering interface, obtained with ipconfig) and the number 23 is the network interface number as demonstrated above. The /p switch makes the route permanent, meaning that we won't have to touch the routing table every time the phone is connected.

That's it! Now, you should be able to access the private network from the PC.

Just one additional note: to make the changes permanent on the phone side (that is, they will be available after the phone is being reset), create a file called in /data/local and put all the iptable commands  in it. For example:


# Add iptables rules for forwarding packets from tethered interface
# to OpenVPN connection
iptables -I FORWARD -i tun0 -j ACCEPT
iptables -I FORWARD -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

# For USB
iptables -I FORWARD -o rndis0 -j ACCEPT
iptables -I FORWARD -i rndis0 -j ACCEPT

# For Bluetooth
iptables -I FORWARD -o bt-pan -j ACCEPT
iptables -I FORWARD -i bt-pan -j ACCEPT

# For WLAN
iptables -I FORWARD -o wlan0 -j ACCEPT
iptables -I FORWARD -i wlan0 -j ACCEPT