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.
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.
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.
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.
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.
.opvn files follow this format:
client dev tun proto udp remote 18.104.22.168 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.