I own an OpenWrt router which I want connected to a VPN 24/7. Major VPN providers all support this scenario, however I currently have a NordVPN subscription so let's go with that for now.
There are 2 main options to run NordVPN on an OpenWrt router: OpenVPN and Wireguard. OpenVPN is the easiest but also slowest solution in terms of performance. Let's tackle this one first.
Source https://support.nordvpn.com/Connectivity/Router/1047411192/OpenWRT-CI-setup-with-NordVPN.htm
Installation of OpenVPN
Once you have a terminal connected to your OpenWrt server:
opkg update opkg install openvpn-openssl opkg install ip-full
To have a LuCI GUI with it
opkg install luci-app-openvpn
Once you have installed the OpenVPN package, you can make it launch automatically whenever the router starts:
/etc/init.d/openvpn enable
Download configuration file and store credentials
Easy as it gets. Next let's get a VPN conf. Head over to https://nordvpn.com/servers/tools/ to download a configuration. Click Show available protocols and then Download config for UDP or TCP. The file contains OpenVPN configuration files with the .ovpn extension. The file name in the archive defines the server’s country, number, and used protocol. For example, in the file name al1.nordvpn.com.ovpn, al stands for Albania, 1 is the server number, and tcp means TCP protocol.
The OpenVPN configuration for NordVPN requires you to input the username and password every time OpenVPN starts. To provide credentials automatically, append the word "secret" with a preceding space to the string auth-user-pass. The resulting string should be auth-user-pass secret.
Create a file with the name "secret" in the same folder and enter the credentials in it. The first line is your NordVPN service username, and the second is your NordVPN service password:
username password
You can find your NordVPN service credentials in the Nord Account dashboard at
Configure OpenVPN
Let's use the "al1.nordvpn.com.tcp.ovpn" file example:
1) Specify the file name in /etc/config/openvpn. You can use uci:
uci set openvpn.nordvpn=openvpn uci set openvpn.nordvpn.enabled='1' uci set openvpn.nordvpn.config='/etc/openvpn/al1.nordvpn.com.tcp.ovpn' uci commit openvpn
The file /etc/config/openvpn should contain the following appended strings:
config openvpn 'nordvpn' option enabled '1' option config '/etc/openvpn/al1.nordvpn.com.tcp.ovpn'
Configure the network
Create a new network interface:
uci set network.nordvpntun=interface uci set network.nordvpntun.proto='none' uci set network.nordvpntun.ifname='tun0' uci commit network
The file /etc/config/network should contain the following appended strings:
config interface 'nordvpntun' option proto 'none' option ifname 'tun0'
Create a new firewall zone and add a forwarding rule from LAN to VPN:
uci add firewall zone uci set firewall.@zone[-1].name='vpnfirewall' uci set firewall.@zone[-1].input='REJECT' uci set firewall.@zone[-1].output='ACCEPT' uci set firewall.@zone[-1].forward='REJECT' uci set firewall.@zone[-1].masq='1' uci set firewall.@zone[-1].mtu_fix='1' uci add_list firewall.@zone[-1].network='nordvpntun' uci add firewall forwarding uci set firewall.@forwarding[-1].src='lan' uci set firewall.@forwarding[-1].dest='vpnfirewall' uci commit firewall
The file /etc/config/firewall should contain the following appended strings:
config zone option name 'vpnfirewall' option input 'REJECT' option output 'ACCEPT' option forward 'REJECT' option masq '1' option mtu_fix '1' list network 'nordvpntun' config forwarding option src 'lan' option dest 'vpnfirewall'
Now you need to configure the DNS servers. The simplest approach is to use NordVPN DNS for the WAN interface of the router. Here’s how to add NordVPN DNS:
uci set network.wan.peerdns='0' uci del network.wan.dns uci add_list network.wan.dns='103.86.96.100' uci add_list network.wan.dns='103.86.99.100' uci commit
The file /etc/config/network should contain the section 'wan' with the following strings (the three bottom strings have been appended):
config interface 'wan' option ifname 'eth0.2' option force_link '1' option proto 'dhcp' option peerdns '0' list dns '103.86.96.100' list dns '103.86.99.100'
Hardening
This step is optional. To prevent traffic leakage in case the VPN tunnel drops, you can edit the file /etc/firewall.user with the following content:
# This file is interpreted as a shell script. # Put your custom iptables rules here, and they will be executed with each firewall (re-)start # Internal uci firewall chains are flushed and recreated on reload, so # put custom rules into the root chains, e.g. INPUT or FORWARD, or into the # special user chains, e.g. input_wan_rule or postrouting_lan_rule. if (! ip a s tun0 up) && (! iptables -C forwarding_rule -j REJECT); then iptables -I forwarding_rule -j REJECT fi
You should also create the file 99-prevent-leak in the folder /etc/hotplug.d/iface/ with the following content:
#!/bin/sh if [ "$ACTION" = ifup ] && (ip a s tun0 up) && (iptables -C forwarding_rule -j REJECT); then iptables -D forwarding_rule -j REJECT fi if [ "$ACTION" = ifdown ] && (! ip a s tun0 up) && (! iptables -C forwarding_rule -j REJECT); then iptables -I forwarding_rule -j REJECT fi
In some cases, OpenVPN hangs with a log message like “couldn't resolve host …”. In this case, the tunnel stays, but the connection is lost. You should reconnect it manually with the following script /etc/openvpn/reconnect.sh, which is added to /etc/rc.local as:
/etc/openvpn/reconnect.sh &
"reconnect.sh" should contain this script:
#!/bin/sh n=10 while sleep 50; do t=$(ping -c $n 8.8.8.8 | grep -o -E '[0-9]+ packets r' | grep -o -E '[0-9]+') if [ "$t" -eq 0 ]; then /etc/init.d/openvpn restart fi done