An important part of my purpose in putting OpenWrt on my travel router is running ExpressVPN in OpenVPN. In my searches I found many trying, but only outdated solutions. So I'm publishing my solution, so working right now that I'm posting this through it.
- I've also posted this as a gist on GitHub.
- The OpenVPN UCI Directives Cheat Sheet I compiled solve this.
Setup ExpressVPN in OpenVPN on OpenWrt
These instructions will get ExpressVPN up & running in OpenVPN on OpenWrt.
opkg update
opkg install -force-overwrite openvpn-openssl luci-app-openvpn
Log back into Luci & there will now be a menu VPN > OpenVPN
.
Firewall
In SSH to the router...
# Configure firewall
uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci del_list firewall.wan.device="tun+"
uci add_list firewall.wan.device="tun+"
uci commit firewall
/etc/init.d/firewall restart
ExpressVPN Files
Create two folders at a convenient location on your computer...
config
openvpn
Log into your ExpressVPN account & navigate to Manual Configuration.
- There's a username & password given. Create a file,
openvpn/user.auth
, with the username as the first line & the password as the 2nd line, & nothing else. - Download all the OpenVPN configuration files you want & save them to
config
. - Download zip file containing certificates & keys.
- Unpack the zip file & put the certificates & keys in
openvpn
. - Check that you have
/etc/openvpn
on the router withls -l /etc
in SSH to the router. If there is no/etc/openvpn
folder, usemkdir /etc/openvpn
to create it. - Use
scp openvpn/* root@OpenWrt:/etc/openvpn/
to copy files to that folder. - Optionally change names of
.ovpn
files to be shorter & more convenient. Keep the charachter set of the new filenames to alphanumeric with hyphens & underscores, & the filenames to 20 characters or less.
UCI Config Files
About UCI Config Files
OpenVPN configuration is defined in a file /etc/config/openvpn
with a definition block for each of one or more OpenVPN instance. The first line of each definition block includes a name which must be unique withing the file. The instance names are limited to 20 characters & a restricted character set. I've found alphanumeric with hyphens & underscores to be safe.
Here I'm turning each .ovpn
file into a version of /etc/config/openvpn
with the OpenVPN instance names as filenames, without an extension. My naming scheme is CC_Location
where CC
is the 2 letter country code.
OVPN to UCI
Rename the .ovpn
files according to whatever naming scheme you decide on. Now that they have no extensions they're not .ovpn
files
Your choice of text editor makes a big difference to the job or turning the files into UCI files. I use BBEdit which has multi-file find & replace, & GREP find & replace. The combination of those features makes transforming a lot of files quick & easy.
First edit certificates & keys out of the .conf
files. These are the same in all the files making it a simple operation with multi-file find & replace.
The files you have now look like this...
dev tun
fast-io
persist-key
persist-tun
nobind
remote example-server.expressnetw.com 1195
remote-random
pull
comp-lzo no
tls-client
verify-x509-name Server name-prefix
ns-cert-type server
key-direction 1
route-method exe
route-delay 2
tun-mtu 1500
fragment 1300
mssfix 1200
verb 3
cipher AES-256-CBC
keysize 256
auth SHA512
sndbuf 524288
rcvbuf 524288
auth-user-pass
The files are identical except for the server URL in the 6th line.
The UCI config files will also be identical except for that URL & the filename. They look like...
config openvpn 'filename' # Country
option enabled '1'
option client '1'
option proto 'udp'
option dev 'tun'
option fast_io '1'
option persist_key '1'
option persist_tun '1'
option nobind '1'
list remote 'example-server.expressnetw.com'
option port '1195'
option remote_random '1'
option pull '1'
option comp_lzo 'no'
option tls_client '1'
option verify_x509_name 'Server name-prefix'
option ns_cert_type 'server'
option route_method 'exe'
option route_delay '2'
option tun_mtu '1500'
option fragment '1300'
option mssfix '1200'
option verb '3'
option cipher 'AES-256-CBC'
option keysize '256'
option auth 'SHA512'
option sndbuf '524288'
option rcvbuf '524288'
option ca '/etc/openvpn/ca2.crt'
option cert '/etc/openvpn/client.crt'
option key '/etc/openvpn/client.key'
option tls_auth '/etc/openvpn/ta.key'
option key_direction '1'
option auth_user_pass '/etc/openvpn/user.auth'
Use whatever methods you prefer to transform the UCI files from the first form to the 2nd.
Files to Router
Create a location in /overlay
of the router for storing OpenVPN config files. I used /overlay/.ovpn
...
mkdir /overlay/.ovpn
Copy UCI files to the router...
scp overlay/* root@OpenWrt:/overlay/.ovpn/
Selecting & Starting ExpressVPN
For the VPN connection you want to use...
cp /overlay/.ovpn/filename /etc/config/openvpn
/etc/init.d/openvpn restart
Do this whenever you want to change your VPN connection.
Combining UCI Config Files
At this point we have a set of UCI files with a single OpenVPN instance in each one. Like this we could have generic names for the OpenVPN instances (I've used Connection
in my set). However we've given them unique names so you can make UCI files with groups of OpenVPN instances.
Concatenate all the files you want in a group, in the order you want them listed, to a new file. Name the new file how you like, avoiding characters that need to be escaped at the command line. I prefix groups with an underscore, _group_file
.
A file with multiple OpenVPN instances should have at most one enabled instance, so replace all occurrences of option enabled '1'
with option enabled '0'
. If there's an instance that you'd like as default within a group, you can leave that one enabled.
Copy your group files to the router the saye way you copied the individual ones...
scp overlay/* root@OpenWrt:/overlay/.ovpn/
... or for individual files...
scp overlay/filename root@OpenWrt:/overlay/.ovpn/
Load a group file the same way you load a single instance file...
cp /overlay/.ovpn/filename /etc/config/openvpn
/etc/init.d/openvpn restart
To start an OpenVPN instance...
- Go to
Luci > VPN > OpenVPN
. - If you have a group default you should see it as running.
- If there's no default check Enabled for the instance you want to start.
- Click Save & Apply.
To change the active OpenVPN instance...
- Go to
Luci > VPN > OpenVPN
. - Uncheck Enabled for the active instance.
- Check Enabled for the instance you want to start.
- Click Save & Apply.
Testing
Follow the testing instructions on the OpenVPN client page of the OpenWrt website.