OpenWrt with NordVPN: Wireguard

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.

Wireguard is a bit more complex to setup than OpenVPN as NordVPN doesn't support this scenario. But performances are much, much better so I think it's worth the extra effort.

Sources:

  • https://openwrt.org/docs/guide-user/services/vpn/wireguard/client

  • https://forum.openwrt.org/t/instruction-config-nordvpn-wireguard-nordlynx-on-openwrt/89976

Get your NordVPN private key

This is maybe the most cumbersome step of the procedure; you will need to install the official nordvpn linux client.

Say you have a debian based distro somewhere:

sudo apt install wireguard
sudo apt install curl
sudo apt install jq
sh <(curl -sSf https://downloads.nordcdn.com/apps/linux/install.sh)

Log in to your nordvpn app via this command:

sudo nordvpn login

Change connection protocol to nordlynx:

sudo nordvpn set technology nordlynx

Connect to any server, for example in Japan

sudo nordvpn c jp

Now that you're connected, we can get the private key but also the IP address of the wireguard interface

sudo wg show nordlynx private-key

Keep the private key, private! Do not share it.

ifconfig nordlynx

Keep the IP address. In my experience it's always 10.5.0.2

Get a NordVPN server's public key

The next step is to get the public key of the VPN server you want to connect to. This can be done with the following command

curl -s "https://api.nordvpn.com/v1/servers/recommendations?&filters\[servers_technologies\]\[identifier\]=wireguard_udp&limit=1"|jq -r '.[]|.hostname, .station, (.locations|.[]|.country|.city.name), (.locations|.[]|.country|.name), (.technologies|.[].metadata|.[].value), .load'

Alternatively, you can run this command even if you're not connected to NordVPN, given you know the country Id of the country you're interested in.

To get the country list:

 curl --silent "https://api.nordvpn.com/v1/servers/countries" | jq --raw-output '.[] | [.id, .name] | @tsv'

Then use the Id in the following command:

 curl -s "https://api.nordvpn.com/v1/servers/recommendations?filters\[country_id\]=108&\[servers_technologies\]\[identifier\]=wireguard_udp&limit=1"|jq -r '.[]|.hostname, .station, (.locations|.[]|.country|.city.name), (.locations|.[]|.country|.name), (.technologies|.[].metadata|.[].value), .load'

It will print something like

jp553.nordvpn.com                             # hostname
5.181.235.35                                  # host IP
Tokyo
Japan
SAio0Z0suFlRfmydzPdcn6MamqS7Mq4pSOm2YmJkLSs=  # public key
17                                            # current load (lower is better)

Install wireguard on OpenWrt

Now that we have all of the prerequisites, we can go ahead. In a terminal connected to you OpenWrt server:

opkg update
opkg install kmod-wireguard luci-app-wireguard luci-proto-wireguard wireguard wireguard-tools

Then from the LuCI GUI -> network -> interfaces:

  • add a new interface using wireguard vpn protocol

  • once you created your interface, on general tab enter your private key and the internal ip address (most likely 10.5.0.2)

  • on the peers tab, enter the public key SA...Ss=, and allow all IPs like this 0.0.0.0/0

  • same tab, for the endpoint host, enter the IP address of the host (here 5.181.235.35)

  • same tab, for the endpoint port, enter 51820 and set PersistentKeepAlive to 25

Page top