Setup OpenVPN Server on OpenWRT Router

Run Your Own OpenVPN Server

Provide access to local services/servers/applications from outside of your home

By Fahad Usman

Why do we need this?

Ever wondered how could you access services or applications such as plex media server or radarr, sonarr, freenas storage that you are hosting on your local Lan from outside your home?

The answer is yes! You could setup a local OpenVPN server ready to connect you to your local services from outside your home from anywhere in the world! All you need is an internet connection!

“Connect to your local services from outside your home using OpenVPN”

In this guide, I will take you through step by step how to set it up using OpenVPN Server.

Requirements:

All you need is a good router with OpenWrt running. I am using the Linksys WRT3200ACM router.

You also need to make sure that you have your duckdns setup and a cron job is running either on your FreeNas box to keep updating the IP address or you will need to set it up on the Router as well. In my case I don’t need to do it on my router because I have set it up somewhere else on my servers.

reverse proxy setup

In my setup above, I have a private domain that has a CNAME pointing to my duckdns server. In this case, I don’t need to use my WAN IP address and will be using my domain name to connect via a client to the server. It’s a following 3 stage process:

Stage 1 is to install packages via ssh into your router and then generating server ca certificates and keys

Stage 2 is to setup router interfaces and firewalls

Stage 3 is to setup OpenVPN Configs

Stage 4 is to generate client certificates and keys

Stage 5 is to download these files and setup on your local devices.

“DuckDNS will help us to keep track of our WAN IP address.”

Stage 1 – ssh into your router and install the following packages:

Just ssh into your router using root.

Now install the following packages:

opkg update
opkg install openvpn-easy-rsa (For easy server and client crts and keys generation)
opkg install luci-app-openvpn (for GUI)
opkg install openssh-sftp-server (for FileZilla login to the router and downloading client files)
opkg install openvpn-openssl (for TLS certs/key generation)

Generate server keys/certs using easy-rsa:

It is recommended that you move your easy-rsa files from the default locations so that you don’t accidentally override those in case of system update.

mkdir /etc/config/openvpn-config
mv /etc/easy-rsa/* /etc/config/openvpn-config/
rm -rf /etc/easy-rsa/
ln -s /etc/config/openvpn-config/ /etc/easy-rsa

Now to generate the certificates

for the server and client(s). We need to start by editing a few lines in the /etc/easy-rsa/vars file.

Keep the key size to at least 2048 bits as default. A key size of 4096 is preferred, but your client has to support it, plus it adds additional encryption overhead.

set_var EASYRSA_KEY_SIZE=2048

Fill out other info as appropriate:

set_var EASYRSA_REQ_COUNTRY "YOUR_COUNTRY_CODE"
set_var EASYRSA_REQ_PROVINCE "YOUR_PROV"
set_var EASYRSA_REQ_CITY "YOUR_CITY"
set_var EASYRSA_REQ_ORG "YOUR_ORG"
set_var EASYRSA_REQ_EMAIL "[email protected]"
set_var EASYRSA_REQ_OU "MYOU"

Next, create your certificate authority, Diffie-Hellman parameters (this will take time depending on your router hardware…it took about 10+ minutes on my router), and certificates. 

cd /etc/easy-rsa
source vars
easyrsa -h (to see help)
easyrsa init-pki
easyrsa build-ca (you can setup a passphrase if you want but then you will need to mention it everytime you create a crt/key for clients/server)
easyrsa gen-dh

Stage 2 – Setup Firewall and your network interface at the router:

We need to configure a new network interface and assign a firewall zone to it. Paste the following in your ssh session terminal: 

uci set network.vpn0="interface"
uci set network.vpn0.ifname="tun0"
uci set network.vpn0.proto="none"
uci set network.vpn0.auto="1"
uci commit network

uci add firewall rule
uci set [email protected][-1].name="Allow-OpenVPN-Inbound"
uci set [email protected][-1].target="ACCEPT"
uci set [email protected][-1].src="wan"
uci set [email protected][-1].proto="udp"
uci set [email protected][-1].dest_port="1194"
uci add firewall zone
uci set [email protected][-1].name="vpn"
uci set [email protected][-1].input="ACCEPT"
uci set [email protected][-1].forward="ACCEPT"
uci set [email protected][-1].output="ACCEPT"
uci set [email protected][-1].masq="1"
uci set [email protected][-1].network="vpn0"
uci add firewall forwarding
uci set [email protected][-1].src="vpn"
uci set [email protected][-1].dest="wan"
uci add firewall forwarding
uci set [email protected][-1].src="vpn"
uci set [email protected][-1].dest="lan"
uci commit firewall

/etc/init.d/network reload
/etc/init.d/firewall reload

This will create a new LAN interface called vpn0. Setup the Firewall and reload network and firewalls.

Enable packet forwarding

We also need to check if packet forwarding is enabled (it should be by default).

cat /proc/sys/net/ipv4/ip_forward

If it is not enabled, edit the above file and set the value to 1.

Step 3 – Setup the OpenVPN Server config:

See the comments in the commands below for more information. Just run the following commands in the ssh terminal connected to your router.

#set and enable vpn
uci set openvpn.myvpn="openvpn"
uci set openvpn.myvpn.enabled="1"

#specify TUN vs. TAP (if you're not sure, you want TUN)
uci set openvpn.myvpn.dev="tun"

#specify port to use (default is 1194)
uci set openvpn.myvpn.port="1194"

#specify protocol to use (default is UDP)
uci set openvpn.myvpn.proto="udp"

#specify to use compression
uci set openvpn.myvpn.comp_lzo="yes"

#logging
uci set openvpn.myvpn.status="/var/log/openvpn_status.log"
uci set openvpn.myvpn.log="/tmp/openvpn.log"
uci set openvpn.myvpn.verb="3"
uci set openvpn.myvpn.mute="5"

#ping every 10 seconds, assume not responding after 120 seconds
uci set openvpn.myvpn.keepalive="10 120"

#keep key and tunnel persistent across restarts
uci set openvpn.myvpn.persist_key="1"
uci set openvpn.myvpn.persist_tun="1"

#set user and group to less-privileged account (UNIX/Linux only)
uci set openvpn.myvpn.user="nobody"
uci set openvpn.myvpn.group="nogroup"

#certificate information
uci set openvpn.myvpn.ca="/etc/config/openvpn-config/pki/ca.crt"
uci set openvpn.myvpn.cert="/etc/config/openvpn-config/pki/issued/server.crt"
uci set openvpn.myvpn.key="/etc/config/openvpn-config/pki/private/server.key"
uci set openvpn.myvpn.dh="/etc/config/openvpn-config/pki/dh.pem"

#server settings
uci set openvpn.myvpn.mode="server"
uci set openvpn.myvpn.tls_server="1"
uci set openvpn.myvpn.server="10.8.0.0 255.255.255.0"

#specify topology to use
uci set openvpn.myvpn.topology="subnet"

#specify gateway to use
uci set openvpn.myvpn.route_gateway="dhcp"

#allow clients to "see" one another
uci set openvpn.myvpn.client_to_client="1"

#options to push to clients
uci add_list openvpn.myvpn.push="comp-lzo yes"
#keep key and tunnel persistent across restarts
uci add_list openvpn.myvpn.push="persist-key"
uci add_list openvpn.myvpn.push="persist-tun"
#set user and group to less-privileged account (UNIX/Linux only)
uci add_list openvpn.myvpn.push="user nobody"
uci add_list openvpn.myvpn.push="user nogroup"
#specify topology to use
uci add_list openvpn.myvpn.push="topology subnet"
#specify gateway to use
uci add_list openvpn.myvpn.push="route-gateway dhcp"
#redirect ALL traffic through the VPN server (this is IMPORTANT if you don't trust your local network)
uci add_list openvpn.myvpn.push="redirect-gateway def1"
#push a local route to your clients (allow your clients to access the server's network)
uci add_list openvpn.myvpn.push="route 10.10.1.0 255.255.255.0"
#push DNS to your clients (this is IMPORTANT if you don't trust your local network)
uci add_list openvpn.myvpn.push="dhcp-option DNS 9.9.9.9"
uci add_list openvpn.myvpn.push="dhcp-option DNS 1.1.1.1"
uci commit openvpn

Be sure to start and enable the OpenVPN server.

/etc/init.d/openvpn start
/etc/init.d/openvpn enable

Next, look at the logfile at /tmp/openvpn.log. With any luck, you should see Initialization Sequence Completed, showing that your OpenVPN server is up!

[email protected]:/etc/config/openvpn-config# cat /tmp/openvpn.log 
Thu Mar 26 18:18:15 2020 OpenVPN 2.4.7 arm-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD]
Thu Mar 26 18:18:15 2020 library versions: OpenSSL 1.1.1d  10 Sep 2019, LZO 2.10
Thu Mar 26 18:18:15 2020 Diffie-Hellman initialized with 2048 bit key
Thu Mar 26 18:18:15 2020 TUN/TAP device tun0 opened
Thu Mar 26 18:18:15 2020 TUN/TAP TX queue length set to 100
Thu Mar 26 18:18:15 2020 /sbin/ifconfig tun0 10.8.0.1 netmask 255.255.255.0 mtu 1500 broadcast 10.8.0.255
Thu Mar 26 18:18:15 2020 Could not determine IPv4/IPv6 protocol. Using AF_INET
Thu Mar 26 18:18:15 2020 Socket Buffers: R=[163840->163840] S=[163840->163840]
Thu Mar 26 18:18:15 2020 UDPv4 link local (bound): [AF_INET][undef]:1194
Thu Mar 26 18:18:15 2020 UDPv4 link remote: [AF_UNSPEC]
Thu Mar 26 18:18:15 2020 GID set to nogroup
Thu Mar 26 18:18:15 2020 UID set to nobody
Thu Mar 26 18:18:15 2020 MULTI: multi_init called, r=256 v=256
Thu Mar 26 18:18:15 2020 IFCONFIG POOL: base=10.8.0.2 size=252, ipv6=0
Thu Mar 26 18:18:15 2020 Initialization Sequence Completed

This means that we have successfully setup our OpenVPN server.

Stage 4 – Generate your client certificates, keys, ovpn files

These files are required for your clients to connect to your OpenVPN server. You should generate one certificate per client e.g. if you have an iPhone, iPad, Macbook, Windows laptop then you need separate certificates, ovpn files, keys for all these devices.

 

easyrsa build-client-full client1 nopass

You will need the passphrase if you setup during the ca.crt file generation. You will have to repeat this for every device configs you wish to use to connect back to your home OpenVPN Server.

Step 5 –  Download client files and put them into your devices

Finally we could download these files using FileZilla by connecting to your router and copying these files over to your devices. The sample OVPN file looks like this:

#specify TUN vs. TAP (if you're not sure, you want TUN)
dev tun
#specify protocol to use (default is UDP)
proto udp
###############################################################################
# The certificate file of the destination home VPN Server.
#
# The CA certificate file is embedded in the inline format.
# You can replace this CA contents if necessary.
# Please note that if the server certificate is not a self-signed, you have to
# specify the signer's root certificate (CA) here.
<ca>
-----BEGIN CERTIFICATE-----
PASTE THE GIBRISH HERE
-----END CERTIFICATE----- </ca>
############################################################################### # The client certificate file (client1.crt). # # In some implementations of OpenVPN Client software # (for example: OpenVPN Client for iOS), # a pair of client certificate and private key must be included on the # configuration file due to the limitation of the client. <cert> -----BEGIN CERTIFICATE-----
PASTE YOUR GIBRISH HERE
-----END CERTIFICATE----- </cert> # client1.key <key> -----BEGIN PRIVATE KEY-----
PASTE YOUR GIBRISH HERE
-----END PRIVATE KEY----- </key> #client settings client remote-cert-tls server remote vpn.example.com 1194

 

Router Port Forwarding 

Open up the port 1194 on your router and forward it to your VPN0 interface.

That’s it!

Leave a Reply

Close Menu