Thanks to https://forum.gl-inet.com/t/configure-wireguard-client-to-connect-to-nordvpn-servers/10422/27 and https://imgur.com/gallery/JBf2RF6, this is how I made a whole subnet go out on the internet through a NordVPN WireGuard connection.
Table of contents
- Getting started
- OPNSense configuration
- OPNsense 20.7.8_4-amd64
- Ubuntu 20.04
- NordVPN user account
Even though WireGuard requires static IPs, NordVPN has deviced a solution which makes this connection as secure as any other available protocol for both authentication and session data, namely double NAT’ing. Read more here: https://nordvpn.com/blog/nordlynx-protocol-wireguard/.
We need to fetch our private key and the corresponding site’s public key. Since there are no documentation for 3rd party apps yet, we’ll have to use what is available to do this for now, using the linux cli, WireGuard itself and software from NordVPN.
Subnet which will travel through NordVPN WireGuard interface is
192.168.10.0/24 - named
WireGuard tunnel interface is named
NordVPN WireGuard gateway is
WireGuard on a linux machine. Check tutorial here; https://www.wireguard.com/install/.
sudo apt install wireguard
Install NordVPN. Check tutorial here; https://support.nordvpn.com/Connectivity/Linux/1325531132/Installing-and-using-NordVPN-on-Debian-Ubuntu-Raspberry-Pi-Elementary-OS-and-Linux-Mint.htm.
sudo sh <(curl -sSf https://downloads.nordcdn.com/apps/linux/install.sh)
Check internet IP address before you start:
sudo nordvpn login Please enter your login details. Email / Username: firstname.lastname@example.org Password: Welcome to NordVPN! You can now connect to VPN by using 'nordvpn connect'.
Change from default VPN protocol OpenVPN to NordLynx (WireGuard):
sudo nordvpn set technology NordLynx Technology is successfully set to 'NordLynx'.
Connect with NordVPN:
sudo nordvpn connect Connecting to France #111 fr111.nordvpn.com You are connected to France #111 (fr111.nordvpn.com)!
You’ll notice that your public IP has changed.
After a successfull connection, figure out the IP scheme of this particular connection:
sudo wg interface: nordlynx public key: UTZ4PHmX5zAOSvdhqp0Ed8q4z0OHgMk8ztalChHaPU= private key: (hidden) listening port: 39069 fwmark: 0xca6c peer: 21dz9Y6HFRzaXKLpFpcZHjcI5AJQopJW/JZShKjTKkZ= endpoint: 126.96.36.199:51820 allowed ips: 0.0.0.0/0 latest handshake: 39 seconds ago transfer: 3.09 KiB received, 3.46 KiB sent persistent keepalive: every 25 seconds
(These are not valid keys by the way).
What about tunnel address?
ip address show nordlynx 8: tun0: <POINTOPINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 link/none inet 10.5.0.2/16 scope global nordlynx valid_lft forever preferred_lft forever
Allright. Whats the opposite side’s address?
ping 10.5.0.1 PING 10.5.0.1 (10.5.0.1) 56(84) bytes of data. 64 bytes from 10.5.0.1: icmp_seq=1 ttl=64 time=6.86 ms
Let’s assume this is the gateway address :)
Now, figure out which private key you have for your user:
sudo wg show nordlynx private-key FSzJDH1171AJKldoqohndlakO3918djals/jkdjkfl0=
(This is not a valid key by the way).
Now you have everything you need. Your private key, your public key, servers public key, the endpoint address and the port.
Allright, we have what we need to get things going regards to configuring our OPNsense firewall.
Add a server by pressing the little + icon
MAKE SURE TO SELECT “SHOW ADVANCED”
- Enabled: [-]
- Name: NordVPN
- Public Key: insert public key from
- Private Key: insert private key from
sudo wg show nordlynx private-key:
- Listen Port: 51822 (use a random port which is not in use on the system)
- DNS Server: 188.8.131.52, 184.108.40.206 (https://support.nordvpn.com/General-info/1047409702/What-are-your-DNS-server-addresses.htm
- Tunnel Address: insert inet address from
ip addr show nordlynx:
- Peers: Nothing selected, leave blank for now
- Disable Routes: Check
- Gateway: 10.5.0.1
Create a new Endpoint by hitting the + icon. Here you will copy the information from the
[peer] section from
- Name: fr111.nordvpn.com
- Public Key: insert public key from
- Shared Secret:
- Allowed IPs: 0.0.0.0/0
- Endpoint Address: 220.127.116.11
- Endpoint Port: 51820
- Keepalive: 25
Now, go back to Local. Select the NordVPN WireGuard instance. Hit Edit (the little pencil).
- Under Peers, select the newly created
[-] Enable WireGuard
After you have selected Save- go to
Because of our persistent keepalive - you should see the received and sent transfer is steadily increasing. You’ll also notice you have a successfull
Handshake with the specific interface whenever this is > 0 (
Now go to Interfaces > Assignments. You’ll have a new interface you can assign (
Assign this interface. After assignment, click the name of the interface (
OPT5 or something similar).
[x] Enable Interface
- Description: WAN_WG_NordVPN_FR
Leave rest of the configuration as is. Click Save.
Apply the changes.
Go System > Gateways Click +Add gateway.
- Name: GW_WG_NordVPN_FR
- Description: PIA through WG_NordVPN_FR
IP adress: 10.5.0.1
- Far Gateway [x]
Set rest to default.
Click Save, Apply.
Go to Rules.
Select the designated interface for your subnet which you would like to go out on internet through this WireGuard VPN.
Allow any any IPv4, but be sure to select
- Gateway: GW_WG_NordVPN - 10.5.0.1 as your gateway under Advanced settings.
While we are at it, do this to enable a kill-switch for your traffic should the WireGuard interface go down:
- Set local tag: NO_WAN_EGRESS
Add another rule on the same interface, but this time - make sure to select
Block. Leave the rest as default. This will be our “kill switch”. Make sure the
reject rule is below the allow rule.
Firewall > Rules > Floating > +Add
- Action: Block
- Interface: WAN
- Direction: out
- Description: NO_WAN_EGRESS match
- Match local tag: NO_WAN_EGRESS
Firewall > NAT > Outbound Select Hybrid outbound NAT rule generation. Click Save and Apply Rules.
Then click +Add.
Interface: WG_NordVPN_FR Source adress: 10_VPN net Translation / target: Interface address Description: 10_VPN to WG_NordVPN_FR
Save. Apply changes.
Let us provide some security regards to DNS leaks on this 10_VPN interface of ours.
Services > DHCPv4
Add DNS servers provided by NordVPN here, so that DHCP offers DNS servers provided by NordVPN:
- DNS servers : 18.104.22.168, 22.214.171.124
If you have devices that have hardcoded DNS servers, you want to redirect those requests to NordVPN’ DNS servers. We’ll define an ALIAS and use NAT port forwarding to achieve this.
Firewall > Aliases. Hit the
- Name: ALIAS_HOSTS_NordVPN_DNS
- Type: Host(s)
- Content: 126.96.36.199, 188.8.131.52
- Description: NordVPN DNS servers
Now, go to Firewall > NAT > Port Forward.
- Interface: 10_VPN
- Protocol: TPC / UDP
- Source: 10_VPN net
- Destination / Invert: checked
- Destination: ALIAS_HOSTS_NordVPN_DNS
- Destination port range: DNS
- Redirect target IP: ALIAS_HOSTS_NordVPN_DNS
- Redirect target port: DNS
resolvectl | grep 'DNS' Current DNS Server: 184.108.40.206
dnsleaktest.sh from https://github.com/macvk/dnsleaktest
./dnsleaktest.sh Your IP: 220.127.116.11 [France BE1800 K19] You use 1 DNS server: 18.104.22.168 [France BE1800 K19]
Are you connected through a VPN?
Make sure you have
curl is used to transfer data from a server and
jq is a lightweight and flexible command-line JSON processor.
sudo apt install jq curl
After installation, enter the command below to fetch the 4 recommended servers closest to you, with support for WireGuard:
curl -s "https://api.nordvpn.com/v1/servers/recommendations?&filters\[servers_technologies\]\[identifier\]=wireguard_udp&limit=4"|jq -r '.|.hostname, .station, (.locations|.|.country|.city.name), (.locations|.|.country|.name), (.technologies|..metadata|..value), .load' fr111.nordvpn.com #your endpoint host 22.214.171.124 #its ip address Paris #city France #country K19dhzkuUGsQkosdahaDKjall18/00idianhkplaUJkmk= #Server public key 15 #Server load at the time. (...)
Bosnia and Herzegovina:
curl --silent https://api.nordvpn.com/server | jq --raw-output '. | select(.country == "Bosnia and Herzegovina") | .domain'
Display the country ID:
curl --silent "https://api.nordvpn.com/v1/servers/countries" | jq --raw-output '. | select(.name == "Bosnia and Herzegovina") | [.name, .id] | "ID for \(.) is \(.)"'
curl -s "https://api.nordvpn.com/v1/servers/recommendations?&filters\[servers_technologies\]\[identifier\]=wireguard_udp&filters\[country_id\]=209&limit=4"|jq -r '.|.hostname, .station, (.locations|.|.country|.city.name), (.locations|.|.country|.name), (.technologies|..metadata|..value), .load'