Introduction

In my last post, I setup the Ubiquiti EdgeRouter Lite (ERL) as a basic router and firewall. Is this post, I’ll be going over the setup of an OpenVPN server. In the past, I used an Archer C7 running OpenWrt to host OpenVPN, so I’ll be applying most of those principles again here.

VPN types

If you need a refresher on the different types of VPNs, see below.

PPTP

L2TP/IPSec

OpenVPN

Pro

Available in most operating systems by default

Available in most operating systems by default

More secure than PPTP

No known security flaws

Very configurable

Uses open source software

More secure than PPTP

No known security flaws

Can use any port, setting to TCP 443 makes it almost indistinguishable from HTTPS traffic

Con

Uses IP protocol 47 (GRE) and UDP port 1723, making it easily detectable and blockable by a firewall

Encryption is not strong

First on NSA's "to-hack" list

Uses UDP ports 50, 500, 1701, and 4500, making it easily detectable and blockable by a firewall

Slightly more overhead than OpenVPN, since traffic is passing through the tunnel and encryption in two separate steps

Not available in most operating systems by default, requires a third-party application

Split-tunnel vs full-tunnel

When setting up a VPN, you’ll have to choose whether to use split-tunnel or full-tunnel for the clients.

Split-tunnel – Allows your local client to access resources on the remote server network (e.g., network shares, file servers, email servers, etc…). Regular internet traffic does not flow through the tunnel and is not encrypted.

Full-tunnel – Allows your local client to access resources on the remote server network (e.g., network shares, file servers, email servers, etc…). Regular internet traffic does flow through the tunnel and is encrypted. However, this might cut your client off from local resources. Typically, clients will have to connect/disconnect based on which group of resources they want to access (local or remote).

I usually choose to go full-tunnel, since I’m usually trying to get access to resources at home and I’m not concerned about local resources. This is easy enough to change on each client by adding or removing one option.

Hardware acceleration

A big advantage of the ERL is that it allows you to offload some functions to hardware. One of these is the IPSec VPN, which greatly improves the throughput. Expect to get about 10Mbps (with one CPU at 100%) while using OpenVPN, and expect up to 150Mbps while using IPSec/L2TP with hardware offload enabled.

I’m choosing to use OpenVPN because it’s what I’m more familiar with. If the performance is really bad, I’ll switch to IPSec/L2TP.

OpenVPN security

By default, OpenVPN developers tend to favor compatibility and speed over security. That’s not necessarily a bad thing, but in this case, I’m going to be changing a few default options. OpenVPN defaults to the following:

cipher – Blowfish in Cipher Block Chaining mode (BF-CBC)

authentication digest – SHA1

OpenVPN themselves recommend AES-256 for more security. In addition, SHA1 is outdated, and shouldn’t be used if SHA2 is available. I’m going to be using the following:

cipher – AES-256-CBC

authentication digest – SHA256

For more security reading, check out the resources here, here, and here.

OpenVPN setup

We’re basically going to create our own Certificate Authority (CA) on the router and use it to sign certificates for authentication. This isn’t best-practice, since the CA should be on its own machine, but it will do for this situation.

Create CA

First, you’ll need to become root.

sudo su -

Next, move into the necessary directory and create a new CA certificate.

cd /usr/lib/ssl/misc/
./CA.sh -newca

Once this completes, you’ll have a new directory called demoCA. The two most important files in here are as follows:

private/cakey.pem – This is the private key for your CA (keep this secret)

cacert.pem – This the public key for your CA (you’ll be giving this out to your clients)

Create server certificate

Next, we’ll generate a public/private key for the server. The Common Name (CN) of your server certificate should be something unique (I used my dynamic DNS name).

./CA.sh -newreq

Once this completes, you’ll have two new files, as follows:

newkey.pem – This is the private key for your server (keep this secret)

newreq.pem – This is the unsigned public key of the server (this needs to be signed by your CA)

Now, sign the request.

./CA.sh -sign

You’ll have one more file, shown below.

newcert.pem – This is the public key for your server

Move files

I recommend moving the important files to a directory where they won’t be wiped out during a firmware upgrade. In addition to moving the files, we’re also renaming them.

Set DNS

Tell DNS to listen for requests on the new vtun0 interface.

configure
set service dns forwarding listen-on vtun0
commit
save

Setup client configuration

The client configuration will vary from client-to-client, but the configuration below should work for Android phones or Linux clients. If you’re using Windows, you’re going to have a tougher time, because it needs some extra options.

Verify connection

Try to browse a public site (e.g., www.google.com), then try to browse to your router’s IP (e.g., 10.10.2.1). If everything is setup correctly, both should load. You can also check your IP with an external tool, such as WhatIsMyIP, and you should see your router’s public IP. I’d also advise to check for DNS leaks (your DNS should be set to the DNS servers we set on the router).

Speedtest

On a Nexus 5 on AT&T LTE, I get 25.61Mbps down, and 23.37Mbps up.

When connected to the VPN while on the same LTE, I get 11.52Mbps down and 5.35Mbps up. Not great, but certainly not bad.

Backup CA

Thanks to Axel for pointing this out. You should backup the entire /usr/lib/ssl/misc directory because it is wiped on a firmware upgrade, and you won’t be able to create any new certificates without creating a new CA from scratch.

cp -r /usr/lib/ssl/misc /config/

Then, after an upgrade, you can restore the misc directory from /config back to /usr/lib/ssl.

I’ve never used it, but it seems like a good idea! It seems like there is a configuration for it (shared-secret-key-file). You’d have to find a way to get it to your clients in a secure manner.shared-secret-key-file
File containing the secret key shared with remote end of tunnel

Question:
Do you know configuration changes I would need to make in order to make this setup a split tunnel configuration? E.g. internet connectivity goes through my local connection, and then the VPN traffic(e.g. access a file server) goes through the the VPN?

I stuffed up when I entered the password the second time and it looks like it failed creating the /usr/lib/ssl/misc/demoCA/cacert.pem File is there a way I can restart the process?
I did try but its just not creating the missing file?

Hello, i really like to read your tutorial, you take your time to explain things so even a newbie like me could make it so thanks for that lol. How you ever tried to use openvpn like a server in the cloud ? i see aws got instances set for that. I was thinking about running one and connect as client several edgerouter from different location on it for remote access each of them separately from time to time.

What will be the best configuration on both part ? I keep looking around but don’t see no tutorial on this case ! thanks for your thoughts

Your client configuration worked in Windows 10 for me. I started by toying with the client configuration by comparing it to an old OpenVPN setup I had but in the end used the same conf you have. Thanks for such a straight forward tutorial.

Shane, unfortunately, I don’t know how to add it. I believe the PAM plugin would be to authenticate with a username/password on the ERL itself. According to the docs, --auth-user-pass-verify should do it.

You may need to add a line to the client config as well.--auth-user-pass [up]
Authenticate with server using username/password. up is a file containing username/password on 2 lines (Note: OpenVPN will only read passwords from a file if it has been built with the --enable-password-save configure option, or on Windows by defining ENABLE_PASSWORD_SAVE in config-win32.h).
If up is omitted, username/password will be prompted from the console.
The server configuration must specify an --auth-user-pass-verify script to verify the username/password provided by the client.

Couple words according tls-auth 🙂
You may use it via
set interfaces openvpn vtun0 openvpn-option “–tls-auth 0”
for ex
openvpn-option “–tls-auth /config/auth/static.key 0” at the server side
and
–tls-auth 1 in client config
or
remote-cert-tls server
key-direction 1

—–BEGIN OpenVPN Static key V1—–
—–END OpenVPN Static key V1—–

in ovpn file
I had to remove hash256 to force it works
Also some options may be ommited like
set interfaces openvpn vtun0 openvpn-option –tls-server
you may check which options sent twice via ps|grep

If I accidentally forgot to backup /usr/lib/ssl/misc during a firmware upgrade, is there some way to recover the index.txt and serial files needed to create new client certs? I was able to grab the CA certs and key from /config/auth but it seems that isn’t enough.

Unfortunately, no (unless you get some forensic tools to recover data from deleted portions of the filesystem). I got bit by this as well and had to create a new CA. Now, I backup /usr/lib/ssl before an upgrade.

Nice ERL blog you got here, for us that are found of the UBNT ERL series.
– I was looking around for a faster way to do SITE2SITE – IPsec trottling above 150Mps, when I dropped into your blog, but have to admit its like beliving in Santa that Ubiquity will release some faster below USD100 routers that have optimized ASICS…

May-be the Calculator people what won the battle of now releasing new stuff until the market is fed up waiting..

Ive been running the expensive stuff in yrs (like Junos +++), and do fancy more the Vyos fork than the Microtik os shit when looking for the best bang for the buck. A bit disappointing with the slow release of new firmware since Stig quit the dev department. What a shame for Ubiquity 🙁

But hopefully they will – give the community more power, better os and bang for the buck in the future.

I wish that Egdeos also will have more power for coping with black-list ip´s and services that makes it easier to setup and more ram for routing – tables.. ++

Edgemax is the poor mans stuff for crowd-blocking the DDos from growing spammers..

If they manage to make the firmware better for doing that OUTofTHEbox!

First, great set of blogs on configuring the ERL. It has been very helpful. Thanks for providing them.

I am planning on replacing an existing NGFW/Router with the ERL and I am slightly confused on the settings and rules I may need to recreate. Specifically for OpenVPN access. I currently have an OpenVPN server in my network (using Synology OpenVPN). I am assuming that because I already have the server and the client certs generated, I can just skip to the setting up the firewall sections of your instructions? Do I still need to create the interface?

In my configuration I have Verizon FIOS as well. My network setup is a sfollows:

Verizon router External interface on NGFW (192.168.x.x) Internal Interface on NGFW (192.168.y.y) Ethernet switch for internal network
(Hopefully that makes sense) The OpenVPN server sits on the internal network and both the Verizon router and the NGFW have the OpenVPN port forwarded to the IP Address of the server. I use the Tunnelblick client on my MAC to access the VPN. I also already have the Dyn setup on the FIOS router. I had to use destination NAT for the port forwarding the NGFW. I am assuming that is not the case on the ERL. Please let me know if I am not explaining anything correctly.

Sounds like the hard work is already done, you just need to swap out the router/firewall. So you’re double-NATed right? You have the FiOS router in front, the then ERL behind it? If that’s the case, you can skip the firewall section for the ERL (assuming you use/trust the FiOS firewall). Although, it wouldn’t hurt to run two firewalls. You don’t need an interface for vtun0 on the ERL, since the Synology runs OpenVPN. The OpenVPN traffic is just passing through the ERL.

Just thinking out loud, I think all you need to do is forward the port (assuming you’re using 1194) through the ERL to the Synology. Something like this just says “forward 1194 to 1194 on 192.168.2.25”.port-forward {
auto-firewall enable
hairpin-nat enable
lan-interface eth1
rule 10 {
description "Forward VPN to Synology"
forward-to {
address 192.168.2.25
port 1194
}
original-port 1194
protocol udp
}
wan-interface eth0
}

If you run into issues, just tail the logs and grep for that port.tail -f /var/log/messages | grep 1194

Thanks for getting back to me so quickly. You are correct, I am double NAT-ed thanks to Verizon and the crazy way they configure their media server stuff. (I have FIOS TV as well as their internet service, have never been able to change the default IP addressing scheme on the FIOS router because the media server is hard coded to look for their default address. Stupidest thing I’ve ever heard of, if you know a way around that, I’m all ears).

I don’t mind running two FW’s but I’ll try your suggested config first and see were it takes me. I’m glad I was thinking along the correct path too, thanks for confirming.

I am running into some issues and was hoping for some sage advice. I ran through all the steps, everything went smoothly, no errors. Grabbed the keys off the router via sftp, made an openvpn profile with the configs above, but I am getting a tls error and it won’t connect. Any suggestions? Here is my client config:

Something I’d like to add. I had some issues with accessing network shares unless I did a full tunnel. I didn’t want the internet traffic to be going over the vpn, as my main purpose is for file sharing, not anything else. So I found that I could add
route 0.0.0.0 192.0.0.0 net_gateway
route 64.0.0.0 192.0.0.0 net_gateway
route 128.0.0.0 192.0.0.0 net_gateway
route 192.0.0.0 192.0.0.0 net_gateway

Logan thanks a million for the amazing write-ups. These instructions worked right out of the box for me too, and are clear and super straightforward.

As you note, “The VPN subnet can’t be the same as your LAN subnet.”

As given, I can join my LAN from a device on openvpn and use dns for explicit routing to systems on my LAN, but has anyone tried (or, hopefully, succeeded) in setting up some sort of masquerade to bridge vtun0 to eth1 so they’re in the same broadcast domain?

What I want are random apps (like smartthings and the like) to work remotely over openvpn… any advice?

Thanks for the step-by-step it is great!! I am getting the error ” OpenVPN configuration error: Specified cert-file “/config/auth/host.pem” is not valid. ” I have tried to recreate the host.pem file but I still get the error. Any thoghts?

Thanks Logan,
You were right on with the signing of the key. Oh the joy of copy-and-paste 🙂 I didn’t notice that the cli had kicked me out the step prior to the signing. New to the ubnt world and am really getting to like the edge router and switch.
I made the mistake of getting a unifi switch, as well which I can’t configure without all of the other cloud software. I’m using it like an expensive hub now 🙁 Again thanks and I enjoy reading your blog,
R/
Tim

You can host the controller on a your desktop temporarily (Win/Mac/Ubuntu/Debian) until you find a more permanent home for it. I host mine on a VM, but a RPi3 will work, as well as a VPS. Ubiquiti also sells the Cloud Key that is basically a linux device that hosts the controller locally.

Incredibly helpful–thank you! I came back to your site a year later after my certificates expired and was able to get my EdgeRouter X-SFP OpenVPN server back up and running (with longer expiration dates).

I found CA.sh use environment variable DAYS and CADAYS, defaults are 1 year and 3 years respectively. I guess we just need set up those environment variables before generating certificates. Could you please confirm?

The host and client certificates aren’t any different, they are the same thing, we’re just calling one “host” and one “client”. So, you can generate a new host certificate just like a new client certificate, just rename it to “host” when you’re done.

I’ve found it difficult to get the 4 files over to the OpenVPN app on an iPhone. Immensely easier to embed into the ovpn and just get the one file across. The note above by Tim seems good, but I wanted to update what worked for me specifically on an up to date iPhone/iOS (July 2018).

To embed the certs and keys, simply place the appropriate text from each cert/key into the respective tags in your .ovpn config file. Example draft text is below (you can use this to create your ovpn file).

Thanks for the post, really useful. I follow all the steps and I was able to connect using Android, everything works, I see the traffic in the dashboard.

The only thing that I can’t make it work is be able to connect to ip addresses that belong to my home network. I type them in the browser but nothing. I follow the very same IP address schema in your post but no luck. What do you think am I missing?

Yes. My home subnet is 10.10.0.0/24 and the VPN subnet is 10.10.10.0/24. From a client I can successfully query my internal DNS and it works (I have some custom domain names) but I can’t reach any device in my local network. I did reboot the ERL but nothing.

Hey Logan.
I have seen it, but it’s unclear to me what changes I have to make in order to connect with win client?
I followed your guide and successfully connected with android device, but I am unable to connect with same certificate on windows machine.
Do I have to create new cert? Is there anything I have to change on edgerouter itself?
Thank you for your patiance.

Finaly maged to connect!
The problem was I saved a folder with certs in there on root of the c driver, when I moved the folder in C:\Users\USER\OpenVPN\config and edited with Randy’s ovpn template, everything works!
Thank’s a lot for your patiance!

Thank’s again! I did manage to get it up and running, but I had trouble creating new client cert’s, also in last few days I had trouble opening web pages from remote pc connected to OpenVPN…
So I managed to setup L2TP ipsec VPN, and it’s working way better than OpenVPN, also it was super easy to set it up! Already created and succssesfuly connected multiple users (android, windows10, iOs…).
So I’m giving up on OpenVPN, since I’m way more satesfied with L2TP setup.
One last thing remains is to remove OpenVpn server from edgerouter.
Is it enough to delete interface from config tree, and delet firewall rule for 1943, or is there something else I should remove also?