Select Page

OpenVPN is one of the most secure (and flexible) Virtual Private Network solutions out there, and it’s sort-of easy to implement on the Unifi USG – even on the lite “3P” version. From various discussions I found on the web I gather that it causes the transfer rates to drop considerably, but for those occasions where you must have access to your home network, or pretend that you’re home while vacationing in another state – this is as good as you can get.

There is already a dozen or so guides on the web on how to set this up, for example:

So why one more?

Two reasons: 1) all of the guides are unnecessarily complex (they use RADIUS server for authentication), and 2) they use outdated / insecure settings (LZO compression and SHA1 authentication mechanism).

In this guide I am going to keep things as simple as possible. No radius, no insecure settings, not too much fiddling with the terminal. Just bare minimum – simple and sweet.

Outline

Prerequisites:

  • Working Dynamic-DNS service – you can use one of the free DDNSes or buy your own domain name and set-up the DDNS record for it.
  • Admin access to your cable modem.
  • Unifi USG… obviously.

There are 5 basic steps to set up OpenVPN:

  1. Generate the certificates for the server and the clients.
  2. Set up the USG.
  3. Set up the Controller and enable OpenVPN.
  4. Set up your modem.
  5. Set up the clients.

1. Generating the Certificates

This can be done directly on the USG (see guides above), but I didn’t like this solution. It takes a long time (my USG-3P has a slow processor), and it is difficult to move the client certificates out of USG afterwards. I chose to do this using my Mac laptop, and posted the entire guide as a separate post: Generating OpenVPN certificates using OSX Mojave.

Return here after you’re done with the certificates. Just remember one thing: the certificates must be kept secure – to the extent of being paranoic. If anyone gets hold of your certificates, they will be able to log into your network, see (or erase) all of your files and use your computers and devices for their potentially malicious purposes.

Do not, ever, put the certificates in a “cloud” location. Better to have an USB thumb drive which you keep in a secure location. Encrypted.

2. Setting up the USG

Once you have the server Certificates in hand, log into your USG via SSH. Open the Terminal and type:

ssh admin@1.2.3.1

Naturally, change the numbers in red to your USG’s IP. If you have previously set-up certificate-based SSH access, you’ll be logged right in, otherwise you’ll be prompted for a password. In this guide there is not too much fiddling with USG over the Terminal, so even password access is OK.

You then need to create a directory on the USG that will persist reboots and re-provisions. That folder, however, will not be directly accessible from outside the USG, so we also need another folder “keys” to use temporarily.

sudo mkdir /config/auth/keys/
mkdir keys
exit

And we’re done with the first session with USG – just one more to come. Now you should be back to your Mac’s terminal. Make sure you are in the “pki” folder (created by easy-rsa) and copy the 4 required certificate files to the temp directory using ‘scp’:

scp ca.crt admin@1.2.3.1:/home/admin/keys
scp dh.pem admin@1.2.3.1:/home/admin/keys
scp private/server.key admin@1.2.3.1:/home/admin/keys
scp issued/server.crt admin@1.2.3.1:/home/admin/keys

Change the numbers in red to your USG’s IP as well. And then log back into the USG to check if the certificates were copied.

ssh admin@1.2.3.1
cd keys
ls -la

You should see the 4 files you just copied. Now move them to the destination directory and remove the temporary folder:

sudo mv * /config/auth/keys
cd ..
rmdir keys
exit

And you’re done with USG.

3. Setting up the Controller

That one is easy – thanks to the config.gateway.json file that I have here for you, with all the necessary settings already in place. By the way, credit for this file goes to xantari, I just modified it to my needs. Here it is:

{
 "firewall": {
  "name": {
   "WAN_LOCAL": {
    "rule": {
     "20": {
      "action": "accept",
      "description": "Allow OpenVPN clients in",
      "destination": {
       "port": "1234"
      },
      "log": "disable",
      "protocol": "udp"
     }
    }
   }
  }
 },
 "interfaces": {
  "openvpn": {
   "vtun0": {
    "encryption": "aes256",
    "mode": "server",
    "server": {
     "push-route": "1.2.3.0/24",
     "name-server": "1.2.3.1",
     "subnet": "1.2.4.0/24"
    },
    "openvpn-option": [
     "--keepalive 8 30",
     "--duplicate-cn",
     "--user nobody --group nogroup",
     "--verb 1",
     "--proto udp6",
     "--port 1234",
     "--push redirect-gateway def1"
     "--auth sha256"
    ],
    "tls": {
     "ca-cert-file": "/config/auth/keys/ca.crt",
     "cert-file": "/config/auth/keys/server.crt",
     "dh-file": "/config/auth/keys/dh.pem",
     "key-file": "/config/auth/keys/server.key"
    }
   }
  }
 },
 "service": {
  "nat": {
   "rule": {
    "5010": {
     "description": "Masquerade for WAN",
     "outbound-interface": "eth0",
     "type": "masquerade"
    }
   }
  }
 }
}

Compared to other guides, there are 3 major differences: the "--comp-lzo" option is removed (insecure compression), a couple of other lines related to RADIUS are removed, and the "--auth sha256" option is added (highlighted in green).

In order for this to work for your set-up, you need to:

  • Edit all entries in red:
    • port numbers in 2 places: I have “1234” here, most people use port 1194 for some reason, but there is no reason to use any number that does not conflict with your other services. I think it is even better if you use a non-standard port as it will be more difficult to hack into.
    • IP addresses in 3 places: I have 1.2.3 and 1.2.4 above, most people would use 192.168.1 and 192.168.2 or 10.1.1 and 10.1.2, etc. Pick a combination consistent with your current network set-up, just keep in mind that “subnet” must be different than “push-route” in the 3rd number.
  • Put the above file in the Controller (not the USG) directory …data/sites/default. The exact path will depend somewhat on how your Controller is set-up. If you’re using a Docker image on a NAS, like me, this could not be easier: just navigate to the folder with your container’s “data” folder and then go to “sites/default/” folder and put the file in there.
    Otherwise, duckduckgo where you should put the config.gateway.json file on your controller – this is not complicated.
  • Re-provision the USG.

Bonus: your settings will now persist re-provisions and reboots, for free, without any additional effort.

4. Setting up the modem

You also need to forward the OpenVPN port in the modem, to the USG. The process to do that very much depends on the ISP and brand/model of your modem.

In general terms, what you need to do is this:

  • Log into your modem’s admin interface.
  • Look for advanced settings, “Port Forwarding” tab.
  • Add new port-forward rule: enter your USG’s IP and the port # you selected for OpenVPN.
  • Apply / save the settings.

I’ll leave you with duckduckgo to figure the details of this process. It’s important to remember that this must be done, though – otherwise: no-go.

5. Setting up the clients

First thing: you need to install a VPN client on each of your devices. I am using OpenVPN Connect app – on my MacBook and on my phone, this works fine.

Secondly, you need a configuration file for each of your devices. Each such file will have the same settings, but different certificates, which you need to create for each client separately (step 1). Credit for this file goes to the authors of the 3 references I posted in the beginning, I only modified it a bit. Open a text editor, and copy the following configuration file:

client
float
dev tun
proto udp4
remote your.domain.name 1234
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth-nocache
verb 4
tun-mtu 1500
auth SHA256
cipher AES-256-CBC


<ca>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
</key>

Change the lines in red. Enter your DDNS domain name and port # under the “remote” tag, and copy/paste the certificates in between the xml tags:

  • <ca></ca> – contents of ca.crt
  • <cert></cert> – contents of your-device-name.crt
  • <key></key> – contents of your-device-name.key

Save the file as “your-device-name.ovpn“, and import in your VPN app. Switch networks to something else than your home network, and connect…

Final touches

If you want, you can monitor the connections to your VPN server by logging into your USG and using this command:

show openvpn status server

That’s it.