OpenVPN

This is an advanced tutorial on how to connect a router with OpenWRT firmware to NordVPN.

 

Please note that this configuration has not been tested by NordVPN staff – it has been shared and tested by our wonderful customers instead. However, if any issues arise, feel free to contact our support team with further help! Also, being an advanced tutorial, it glances over some simpler instructions.

NordVPN would like to thank ulmwind, an active member of OpenWRT community, for his continuous assistance in providing us with the up to date OpenWRT instructions.

 

 

Initially, you should have a router with OpenWRT firmware with the OpenVPN client enabled. The main page of the firmware is http://openwrt.org

The router, flashed with OpenWRT firmware image, initially accepts connection only via the telnet protocol, so you should connect to it via telnet to the IP 192.168.1.1 and change the root password with command “passwd”. After this command, it accepts connection via SSH. By default the OpenVPN package isn’t included in the firmware image, so you should install it by use of opkg:

# opkg update
# opkg install openvpn-openssl
# opkg install ip-full

You can also install luci-component of openvpn configuration, but it is optional:

# opkg install install luci-app-openvpn

You can also build firmware image with openvpn.

 

A good reference manual of a general OpenVPN client configuration you can find on this page: https://github.com/jlund/streisand/wiki/Setting-an-OpenWrt-Router-as-OpenVPN-Client .We will follow it with modifications, specific for NordVPN.

 

After installing the OpenVPN package you can make it start automatically when the router starts:

# /etc/init.d/openvpn enable

Download the file “config.zip” from this link: https://nordvpn.com/api/files/zip

This file contains OpenVPN configuration files with extension “ovpn”. File name in the archive defines country, number, protocol and port. For example, consider first file “al1.nordvpn.com.tcp443.ovpn” “al” means Albania, “1” means server number in the country, “tcp” means TCP protocol, and “443” means port number. We will use this file for example, other files are treated similarly.

Copy the file “al1.nordvpn.com.tcp443.ovpn” with pscp or WinSCP programs in Windows, scp command in Linux to /etc/openvpn/ folder of router filesystem. In case of copy problems you should force using exactly scp protocol (it also can use sftp). The OpenVPN configuration specific for NordVPN requires input of username and password in each start of OpenVPN. To provide credentials automatically, append the word “secret” with a space to the string “auth-user-pass”, so the resulting string should be “auth-user-pass secret”, create the file with the name “secret” in the same folder, and provide credentials in it as follows: first line is your login, second line is your password.

The file itself contains contents of file “ca.crt” between tags “<ca>” and “</ca>” and contents of file “ta.key” between tags “<tls-auth>” and “</tls-auth>”. You can create separate files “ca.crt” and “ta.key” with corresponding content excluding tags, in the same folder, and replace tags with content in original file with following strings:

ca ca.crt
tls-auth ta.key 1

You can also download an archive here: https://nordvpn.com/api/static/ca_and_tls_auth_certificates.zip and find in it corresponding files with extensions “crt” and “key”. The files are specific for each VPN-server.

 

Configuration of OpenVPN using the file “al1.nordvpn.com.tcp443.ovpn” could be implemented in two ways.

1) Change the extension of the file “ovpn” to “conf”. In this case OpenVPN will find it automatically by extension.

2) Specify 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.tcp443.ovpn'
# uci commit openvpn

The file /etc/config/openvpn should contain following appended strings:

config openvpn 'nordvpn'
        option enabled '1'
        option config '/etc/openvpn/al1.nordvpn.com.tcp443.ovpn'

You can also change extension of the file “ovpn” to “conf”, and speficify it in the file /etc/config/openvpn, in this case OpenVPN will start with this configuration file just once.

 

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 following appended strings:

config interface 'nordvpntun'
        option proto 'none'
        option ifname 'tun0'

Create a new firewall zone and add 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 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 we should configure DNS servers. The simplest approach is to use NordVPN DNS for the WAN interface of router. You can add NordVPN DNS:

# uci set network.wan.peerdns='0'
# uci del network.wan.dns
# uci add_list network.wan.dns='162.242.211.137'
# uci add_list network.wan.dns='78.46.223.24'
# uci commit

The file /etc/config/network should contain section ‘wan’ with following strings (three bottom strings has been appended):

config interface 'wan'
        option ifname 'eth0.2'
        option force_link '1'
        option proto 'dhcp'
        option peerdns '0'
        list dns '162.242.211.137'
        list dns '78.46.223.24'  

You can also add GoogleDNS:

# uci set network.wan.peerdns='0'
# uci del network.wan.dns
# uci add_list network.wan.dns='8.8.8.8'
# uci add_list network.wan.dns='8.8.4.4'
# uci commit

The appended strings should be similar to previous one.

To prevent traffic leakage in case VPN-tunnel drops you can edit the file /etc/firewall.user with following content:

# This file is interpreted as shell script.
# Put your custom iptables rules here, 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 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 log message like (couldn’t resolve host …). In this case tunnel stays up, but connection is lost. It should be reconnected 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 '\d+ packets r' | grep -o -E '\d+')
        if [ "$t" -eq 0 ]; then
                /etc/init.d/openvpn restart
        fi
done

When you finish these instructions, the connection should be configured, and you should be connected successfully. You can check by visiting NordVPN.com/profile/ and checking if you show up as “Protected”.