Tuesday, October 7, 2008

SSH to tether your iphone with OpenVPN over USB cable

With appearance of PdaNet for iphone the connection of your PC to the Internet through the iphone (tethering) turns into a trivial task. You only need to arrange ad-hoc wifi connection between your PC and iphone and forget about all socks, proxy, tunnels etc. PdaNet turns your iphone into a wireless router giving you FULL Internet access on the computer for all protocols/ports/services you need.

In this post I'll try to show how to reach the same functionality connecting your PC to the iphone over cable with the help of OpenVPN. Why OpenVPN? Because it is the only vpn suite which can use TCP protocol and one port for connection. That's why we can arrange ssh local tunnel to link the PC with external vpn server over iphone's GPRS/EDGE/3G.
OpenVPN is a great cross-platform freeware and open source program for creating virtual private network (VPN) between computers. I found some original guides in linux guru blogs (here and here) so my idea is only to repeat the same tricks for Windows.
We need two PCs, one is a laptop to be tethered where we'll install openvpn client. Another machine is home or small-office PC connected to broadband Internet line and to be configured as openvpn server.
The main idea of VPN is gaining secure access to the intranet shared resources, company internal web-site or mailserver over fast Internet line through encrypted tunnel between client and server hosts. In addition, vpn-server can be a kind of "router" for the remote vpn-client giving full Internet access to it. Typically it's not needed because vpn-client is already in the Internet and gains only access to the private resources at the server's LAN. But in our case it is essential, the laptop will be connected to the vpn server over GPRS/EDGE/3G and get full Internet access from it. All requests will be wrapped into openvpn tunnel which in turn will be wrapped into ssh tunnel between ssh-client, the laptop, and ssh-server, the iphone. Sounds complicated? Let's see.
First, we need to install and configure our openvpn hosts. The latest release version of openvpn is 2.09, you can download it from official page at http://www.openvpn.net/index.php/downloads.html, there is GUI interface for Windows at http://openvpn.se. Besides, the new openvpn version 2.1 (pre-release is available) supports Vista and contains GUI already inside. I experimented with this pre-release version on my Vista Home Premium laptop connecting it to my office openvpn 2.09 server without problem.
The installation is rather easy, one extra tun/tap pseudo network adapter is added to each system. This adapter will be used for point-to-point connection, it is fully controlled by openvpn so don't touch it at all.
Assume we have openvpn server with fictitious address remote.vpn.com somewhere in Internet. This server has two real Ethernet adapters. One is for external connection, another is part of small-office LAN within 172.29.10.x range, this LAN adapter address is, the third "adapter" is openvpn MyTap. So server's Network Places look like this (ignore Incoming connections here):

In order to provide the Internet access for MyTap adapter, i.e. for vpn-client, we will enable Internet Connection Sharing on External Connection for MyTap adapter

and disable the Windows Firewall on MyTap adapter

We need to prepare and tune up ovpn configuration file, one on laptop, another on server, samples are stored in sample-config subdirectory. So just copy client.ovpn from sample-config to config subdirectory on laptop, do the same for server.ovpn on your server. Note that openvpn is rather sensitive for config files changes so please modify them if you know what you do.
For both config.ovpn and client.ovpn it is essential to have:

# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
proto tcp
;proto udp


# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
# Use "dev tap0" if you are ethernet bridging
# and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface.
# If you want to control access policies
# over the VPN, you must create firewall
# rules for the the TUN/TAP interface.
# On non-Windows systems, you can give
# an explicit unit number, such as tun0.
# On Windows, use "dev-node" for this.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
dev tap
;dev tun

For client.ovpn we use for ssh tunnel connection, not real server address here.

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote 1194

For server.ovpn we need to append (highlighted in blue) the following section:

# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# the TUN/TAP interface to the internet in
# order for this to work properly).
# CAVEAT: May break client's network config if
# client's local DHCP server packets get routed
# through the tunnel. Solution: make sure
# client's local DHCP server is reachable via
# a more specific route than the default route
# of
push "redirect-gateway def1"

and these

# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
# The server will take for itself,
# the rest will be made available to clients.
# Each client will be able to reach the server
# on Comment this line out if you are
# ethernet bridging. See the man page for more info.

# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses. CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
push "dhcp-option DNS"
push "dhcp-option WINS"

At this point we consider openvpn configuration finished. I intentionally skip the important part of secure keys generating. It is described in details in hundreds of online openvpn manuals and guides. Remember, you must generate client keys on server console and then transfer them to client for further use.

Let's return to our ssh-client on laptop and configure Tunnelier (which we so successfully used before) to arrange the only one C2S tunnel. Please disable any other options which we used before for socks-proxy and mail tunnels (see my older posts). Now we have only this entry in C2S Forwarding screen:

where remote.vpn.com is our openvpn server address in the Internet and 1194 is port OpenVPN uses.
We connect the iphone to the laptop with USB cable, check ssh is ON in iphone's Bossprefs, change auto-lock to Never and start Runtunnel.cmd on laptop to enable itunnel (see my older posts). Make sure the GPRS/EDGE/3G is available on the iphone and press Login in Tunnelier.
If ssh connection is OK you can start openvpn client connection. Use OpenvpnGUI icon in tray to start openvpn session. If it's successful the laptop's tap-adapter will get from openvpn server which according to ICS main rule keeps for itself.
The server provides full NAT (network address translation) for client's requests wrapped into openvpn tunnel. Then the client gains FULL Internet access directly, now without any changes in its browser/mailer/im configuration. You can easily start, for instance, ftp-session or mail client or RDP in your notebook without any extra preparations. Moreover, after openvpn you can even start PPTP/L2TP/IPSec vpn connection with some third-party vpn-server which was not possible before because of ssh limitation to serve TCP protocol only.
As a result, we have encrypted and compressed openvpn tunnel between laptop and soho server on TCP port 1194 and get FULL Internet access for laptop over GPRS/EDGE/3G provided by iphone!


beso said...

Excellent! It worked for me too. I was able to utilize iphone's 3G net to make VOIP (SIP) calls, since you can do UDP too. Some Intranet sites stopped responding though (since Def gateways was pushed), but I think that can be corrected by modifying routing table.

I wish machine in the middle could be eliminated, to utilize full network just by iphone's 3G.

nubela said...

Can this be done in Linux? The app for linking the iPhone to the PC is a .exe, is there a linux alternative?

Richard Jeong said...

I second the linux question. I'm using ubuntu (Hardy) and having a hellva time with ad-hoc networks. I've been using the iphone PDANet net, which seems an simplified app version of what's described here and works on a windows machine without a hitch, but has problems in ubuntu. Specifically DHCP problems it looks like, but I can't figure it out.

Victor said...

Do you have to have an Enterprise data plan in order for the OpenVPN connection from the laptop to the server, via iPhone, to work?

I've heard that VPN is blocked for the normal data plan. If that's the case, I'm wondering if you could create a tunnel from the iPhone to the server and redirect the openVPN connection through that?

alk said...

Victor said...
I've heard that VPN is blocked for the normal data plan...
If you mean filters that (Russian) GSM Carriers apply, yes, they really block GRE protocol packets needed for PPTP VPN operation. But no problems with OpenVPN which uses TCP only. So you can use OpenVPN for tunneling over GPRS.

Jovi said...

Thanks for sharing that information alk !

After 2 long nights I finally managed to get it work and would like to add few things to help others struggling with this.

- Before lauching SSH-connection to iPhone open Safari in iPhone and keep it open as OpenVPN does not seem to open 3G connection by itself. (I think that you can lock your phone after that if you like to, but Im not 100% sure about it).

- push "redirect-gateway def1" directive in server config might not work as there is no any working gateway in client machine this option could replace with so you may need to add: push "route" to config.

- DNS was not working even route to my local router's subnet was ok so I needed to push DNS server addresses to my OpenVPN client with this directive in server config: push "dhcp-option DNS ip.to.isps.dns"

- Never got iTunnel.exe work with WinXP Pro SP3 (Win32), works well with Windows Vista Business (Win32).

My system:
- OpenVPN server 2.1_rc7 installed in Ubuntu 8.04 (does not have public IP)
- Linux iptables NAT used to share internet connection (OpenVPN TAP adapter to ethernet, interfaces are both in different private subnets)
- Linksys WLAN WRT54GS router works as DHCP- and DNS server and shares internet connection to LAN clients, OpenVPN port from OpenVPN server machine port-forwarded to this device.
- Client machine installed with MS Vista Business (Win32), OpenVPN 2.1_rc15, OpenSSH command-prompt client (version OpenSSH_3.8.1p1)
- Cygwin. Not propably needed but I used it to change the priviledges of my ssh-keys to get rid of some nags and to get publickey authentication of SSH work.