[G1 Android Development] balazer:
openvpn client for Android G1

Let me give a big thank you to Fnorder for compiling openvpn and posting it.

His web page with the instructions and files seem to have been removed. I saved them, in case anybody needs a copy.

I've got it working with my JF1.51 ADP rom, so I'll save everyone the trouble and post my configuration. This ROM already includes busybox and tun.ko.

I've also tested it in CyanogenMod 3.6.8.1. In CyanogenMod, the tun device is built into the kernel; there's no need to load it with modprobe. CyanogenMod also includes busybox.

A little background on my setup: my server is Windows XP, and sits on a private LAN behind a NAT/router connected to the Internet. The LAN is 192.168.0.0/24. The VPN is 10.4.0.0/30 with server IP 10.4.0.1 and client IP 10.4.0.2.

I've created up and down scripts such that when the VPN connection is established, the default route will be deleted, and new routes created such that the VPN is still reachable but all other traffic will be routed through the VPN. Upon stopping the VPN, the changes are reversed, deleting the new routes and restoring the old default route, if applicable. (if the underlying network has changed, the down script does the right thing, i.e. not delete anything related to the new underlying network, and not restore the old default route which no longer applies) If the underlying network should change, e.g. if you switch between 3G and WiFi, the client will detect this using ping-retry, tear down the old routes, re-establish the VPN, and create new default routes. But beware that between the time the new underlying network comes up and the time the new VPN routes are created, some of your internet traffic may go over the network without VPN.

The Busybox route command is very finicky. It took a long time to get these scripts right.

UDP and TCP both work; just change proto. I found UDP was a bit more reliable.

Compression and encryption are optional.

Make sure that all of your .sh files have UNIX end-of-line characters. Windows EOLs will mess them up, so don't create these files in Notepad. I use Crimson editor, which lets me set the file type.

Client setup:

/system/xbin/bb/mkdir -p /data/opt/bin
ln -s /system/xbin/bb/ifconfig /data/opt/bin/ifconfig
ln -s /system/xbin/bb/route /data/opt/bin/route
copy openvpn, client.conf, *.sh, and static.key to /data/openvpn
chmod 777 /data/openvpn/*.sh

Windows XP Server setup:

SP2 and lower: Install routing hotfix for kb913522. (download from http://support.microsoft.com/kb/917730)

install openvpn

disable Windows firewall for tap device

enable routing ( http://support.microsoft.com/kb/315236 ) and reboot

add persistent route to vpn with metric lower than internet gw route

e.g.

route /p add 10.4.0.0 mask 255.255.255.252 10.4.0.1 metric 10​

In your internet gateway NAT/router, add a route to the VPN with the server's LAN IP as the gateway. My router (Zyxel X-550) was quite happy to perform NAT for both the LAN and VPN, but I don't know if all routers would. If not, you can do NAT on the server. And of course, you'll need port forwarding from the router's WAN interface to the TCP or UDP port that your openvpn server will be listening on.

Server config (c:\program files\openvpn\config\server.ovpn)

#proto tcp-server
proto udp
lport 800

ifconfig 10.4.0.1 10.4.0.2
dev tun

#comp-lzo
#cipher AES-256-CBC
#secret "/program files/openvpn/config/static.key"

ping 20
ping-restart 30

Client config: (/data/openvpn/client.conf)

#proto tcp-client
proto udp

remote servername.com 800

ifconfig 10.4.0.2 10.4.0.1
dev tun

ipchange "/system/bin/sh /data/openvpn/up.sh"
down "/system/bin/sh /data/openvpn/down.sh"

#comp-lzo
#cipher AES-256-CBC
#secret /data/openvpn/static.key

ping-restart 30
ping 20

/data/openvpn/up.sh

#!/system/bin/sh
set -x
echo "*** up script start ***"

/system/xbin/bb/route |grep default |cut -b 17-32 >/data/openvpn/defgw
echo defgw is `cat /data/openvpn/defgw`
/system/xbin/bb/route add $trusted_ip gw `cat /data/openvpn/defgw` metric 5
/system/xbin/bb/route del default
/system/xbin/bb/route add default gw $ifconfig_remote metric 10 dev tun0

echo "*** up script finish ***"

/data/openvpn/down.sh

#!/system/bin/sh
set -x
echo "*** down script start ***"

/system/xbin/bb/route del default gw $ifconfig_remote
/system/xbin/bb/route del $trusted_ip
/system/xbin/bb/route add default gw `cat /data/openvpn/defgw`

echo "*** down script finish ***"

/data/openvpn/start.sh

#!/system/bin/sh
modprobe tun
/data/openvpn/openvpn --config /data/openvpn/client.conf &

/data/openvpn/stop.sh

#!/system/bin/sh
/system/bin/ps openvpn | /system/xbin/bb/awk '$2 ~ /[0-9]+/ {print "kill " $2}' | sh

Then run openvpn on the server.

To run openvpn on your client, as root:

/data/openvpn/start.sh

If all goes well, after the connection is established, you'll see this routing table like this in the client:

/system/xbin/bb/route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
71.142.94.101 25.195.105.41 255.255.255.255 UGH 5 0 0 rmnet0
10.4.0.1 * 255.255.255.255 UH 0 0 0 tun0
25.195.105.40 * 255.255.255.252 U 0 0 0 rmnet0
default 10.4.0.1 0.0.0.0 UG 10 0 0 tun0

71.142.94.101 is my server's Internet IP address. 25.195.105.41 is the gateway T-Mobile had given me.

The start and stop scripts can be run by GScript Lite. Make sure they run as su. Avoid running start.sh more than once - you'll end up with multiple openvpn processes. But if it happens, stop.sh will stop all of them.