OpenVPN Connect for Android

So it was about time that I got around to connecting my Android devices to my VPN, which I implemented a while back using OpenVPN and wrote about in Linux Voice.

The Android client is called OpenVPN Connect, a proprietary application available for free from the Google Play Store. However, I used the Evozi APK Downloader to download it so that I could sideload it onto devices where I don't have (e.g. Amazon Fire) or don't want Google (Samsung S3 and anything else).

There is also a client for iOS which I may try as well.

Server Configuration

The first thing that I had to deal with was that, as per the OpenVPN Connect Android FAQ, only tun devices can be used with the Android client:

The Android VPN API supports only tun-style tunnels at the moment. This is a limitation of the Android platform.

Because I was running a bridged tap VPN, I had to set up a second OpenVPN instance configured to use tun. Doing so was straightforward and I won't go into the details here, except to say that I used UDP port 1195 to serve a 172.16.0.0/24 network.

One everything was working, I stopped the tap VPN and changed the tun one back to port 1194.

My server.conf configuration file is similar to this:

port 1195
proto udp
dev tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh2048.pem
server 172.16.1.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.0.0.0 255.0.0.0"
keepalive 10 120
tls-auth /etc/openvpn/ta.key 0
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
push "redirect-gateway def1"

The other server configuration task is to enable IP Forwarding if it isn't already. This allows packets to be forwarded to the VPN from other hosts on the server's network.

The server.conf pushes a route to the client to allow it to reach the server's local network (10.0.0.0/8 in the above example). A converse route needs to be added to that network's default gateway which, in my case, is my router. I added the required route through its CLI like this:

=> ip rtadd dst=172.16.0.0 dstmsk=255.255.0.0 gateway=10.0.200.11

That's for my router, others probably require something different.

Client Configuration

Installing the client is straightforward, either directly from the Google Play Store or by sideloading a downloaded APK (which is what I did). I'll assume you know how to install an app on an Android device!

Configuring the client involves creation of a profile which is a text file with the suffix .opvn that contains client-side settings similar to the client.conf file used on a desktop client but with one subtle difference: the Unified Format, as explained here. Essentially, the certificate and key files are embedded in the file.

For each device, I used Easy RSA to prepare a new key and certificate, created the .opvn profile and uploaded it to the device. I could then select it from within the import page of the OpenVPN Connect app.

The key and certificate were created like this:

$ cd path/to/easy-rsa
$ source vars
$ ./build-key my-phone

This produced the necessary key (my-phone.key) and certificate (my-phone.crt) which contain the key material required for the unified format profile.

My profile .opvn files follow this format:

client
dev tun
proto udp
remote 1.2.3.4 1195
nobind
comp-lzo
mtu-test
<ca>
-----BEGIN CERTIFICATE-----
e3VQ7KkEgBDW...Jd+rmlBYziU82d
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
MIIE0DCCA7...igAwIBAgIBAjANBg
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
MIIEvQIBADA...NBgkqhkiG9w0BA
-----END PRIVATE KEY-----
</key>
key-direction 1
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
e8894f6jj47b...6c5mjf83782487
-----END OpenVPN Static key V1-----
</tls-auth>

I've truncated the key material and used an example server IP address.