Your own OpenVPN, or: How to make all WiFi hotspots trustworthy

If you normally browse the web (and you don’t block ads), you’ve probably already seen hundreds, if not thousands, of advertisements for “VPNs” or “VPN software/subscriptions” — how you “need” one to have any kind of privacy, how “they”1 can track you everywhere if you don’t use one, and so on. And they’re usually not cheap. Interestingly, and probably because of some recent “revelations”, all those advertisements seem to focus on privacy or anonymity only.

But using a VPN can offer you something else: mobile security; namely, the ability to make your mobile devices “be”, on demand, part of your home network (or your server’s network, if you have, say, a VPS somewhere), no matter where you are, regardless of whether you’re using 3G/4G mobile data, or some random WiFi hotspot. Yes, even one with no encryption at all; it won’t matter. You can, absolutely, trust random open hotspots again; even their owner won’t be able to read or alter your traffic in any way. And you can do it for free, too (assuming you already have an always-connected Linux server); you just need to configure your own OpenVPN server, which you’ll be able to do by following this (hopefully accessible) guide.

Installing OpenVPN:

This tutorial will be Debian/Ubuntu-based, but it’s easy enough to adapt to other distributions (e.g. for a Red Hat-based Linux, just do “yum install” instead of “apt install“, and some defaults may be slightly different). Just enter:

apt install openvpn
Configuring OpenVPN:

(Note: this guide will focus on the goal mentioned in the second paragraph: configuring your “home” server (which doesn’t need to actually be at your home) to accept VPN connections from your mobile device(s), which will then make that/those device(s) act as if they were part of your “home” network. OpenVPN can do other stuff, but we won’t go into that here.)

(Note 2: if you’re using a server at home, you probably need to configure your modem/router to forward OpenVPN connections to your server. The default OpenVPN port is 1194 (UDP), but it can be changed (it’s specified in the configuration files below.))

First, copy some default configuration files:

mkdir /etc/openvpn/easy-rsa/
cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/

Then edit the /etc/openvpn/easy-rsa/vars text file, and change the following variables from the defaults to something that makes sense for you. Most of these are “cosmetic”, so they don’t really matter, but it’s ugly to keep the defaults 🙂 :

export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"
export KEY_NAME="EasyRSA"

Add another setting to that file:

export KEY_ALTNAMES="mysite.mydomain.com"

(replacing “mysite.mydomain.com” with your server’s external name, of course.)

Then do:

cd /etc/openvpn/easy-rsa
ln -s openssl-1.0.0.cnf openssl.cnf # if there's a file for a newer OpenSSL version, use that one
source ./vars
./clean-all
./build-ca

The last command will ask for details for your private Certificate Authority (CA)’s certificate. Just answer with the same details you entered in the “vars” file above. In particular, “Common Name” must be your server’s public address.

Continuing:

./build-key-server myhostname # replace if desired; if so, don't forget to do the same everywhere else

Again, this will ask for certificate details. It’s OK to use the same you used for the CA. This will also confirm if you want to sign the certificate and commit the certification; answer “yes” both times.

Now enter:

./build-dh # this will take a while
cp keys/myhostname.* /etc/openvpn/
cp keys/dh2048.pem /etc/openvpn/
cp keys/ca.crt /etc/openvpn
chmod 600 /etc/openvpn/*.key /etc/openvpn/easy-rsa/keys/*.key

Now, there are example server configuration files in /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz , but we’ll just create a simple one from scratch. Save the following as /etc/openvpn/server.conf :

port 1194

proto udp

dev tun

ca ca.crt
cert myhostname.crt
key myhostname.key
dh dh2048.pem

topology subnet

server 10.8.0.0 255.255.255.0

ifconfig-pool-persist ipp.txt

# replace the following with the DNS server your server uses
push "dhcp-option DNS 192.168.1.1"

push "redirect-gateway def1 bypass-dhcp"

keepalive 10 120

cipher AES-256-GCM

comp-lzo

persist-key
persist-tun

status openvpn-status.log
verb 3

explicit-exit-notify 1

Right now, you should be able to restart OpenVPN and have it running with no complaints. But, of course, this is just the server part; we still need to create a configuration file for each of your clients (which can be computers, tablets, mobile phones, etc.). In the following example, we’ll create one for an Android phone (though nothing here will be specific to Android).

On your server, do:

cd /etc/openvpn/easy-rsa/
./build-key android01 # replace with an identifier of your choice, if so desired

As before, it will ask for certificate details. Enter what you’d like, even in the “Common Name” field; here they’re all cosmetic.

Now create an .ovpn file for the new client. Put the following in an /etc/openvpn/android01.ovpn text file:

client
# replace the following with your external address
remote mysite.mydomain.com
port 1194
proto udp
dev tun
dev-type tun
ns-cert-type server
reneg-sec 86400
auth-nocache
auth-retry interact
comp-lzo yes
verb 3

But this is not complete. For laziness’s sake (and, in my experience, required for iOS devices), we’ll also add the certificates (CA and client) and the client key here. Assuming they’re where the tutorial so far left them,

echo "<cert>" >> /etc/openvpn/android01.ovpn
cat /etc/openvpn/easy-rsa/keys/android01.crt >> /etc/openvpn/android01.ovpn
echo "</cert>" >> /etc/openvpn/android01.ovpn
echo "<key>" >> /etc/openvpn/android01.ovpn
cat /etc/openvpn/easy-rsa/keys/android01.key >> /etc/openvpn/android01.ovpn
echo "</key>" >> /etc/openvpn/android01.ovpn
echo "<ca>" >> /etc/openvpn/android01.ovpn
cat /etc/openvpn/easy-rsa/keys/ca.crt >> /etc/openvpn/android01.ovpn
echo "</ca>" >> /etc/openvpn/android01.ovpn

You also need a masquerading rule in your firewall. For instance (using the default OpenVPN network of 10.8.0.0/24):

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Replace “eth0” with your public/outgoing network interface. And make it permanent, of course. If using ufw, just add:

-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

to /etc/ufw/before.rules .

You must also have IP forwarding enabled. If your server acts as a firewall, it’s probably already on. You can check it with the command:

sysctl net.ipv4.ip_forward

If it’s “1”, you’re fine. If not, you can do:

sysctl -w net.ipv4.ip_forward=1

to enable it, and:

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf

to make it permanent.

And that should be it. You now need to transfer this new .ovpn file (keep it safe, by the way, including from any other local users on your server!) to your Android (or other) device, and then open it in the OpenVPN client (which you need to install, of course — don’t worry, it’s free.) Each device has a specific way to import the .ovpn file, and the client typically helps you in doing so, so you’ll eventually succeed. 🙂 If everything goes well, you’ve just connected your phone (or some other device) to your own network, and everything between the two is fully encrypted. You may now want to play around with shortcuts so that you can “VPNize” your phone at the click of a button (say, when connecting to a public hotspot.)

As implied in this (now quite long) post’s introduction, this won’t do anything for your privacy; any site you access will see your home/server address, no matter where you are. So don’t use it to communicate with other insurgents, or hack government sites, or anything. 🙂 The point is simply to “make” even unknown hotspots as trustworthy as if you were home. (It may also help you get around some firewalls or traffic shaping, but you didn’t read that here. 🙂 )

Any comments/suggestions, please let me know in the comments.

  1. “them” again? annoying fellows…

2 Replies to “Your own OpenVPN, or: How to make all WiFi hotspots trustworthy”

  1. Thanks to Reddit user ZeusHoldsMyJockstrap for reminding me about the missing IP forwarding part. 🙂 My home server has had IP forwarding enabled since 2007, so I totally forgot about it when writing this guide.

Leave a Reply