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
Login is done via the browser by default, and I had to copy/paste the token as explained here: https://askubuntu.com/a/1399896
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 OPNsense
This is still valid as of OPNsense version 23.7.8, however the wireguard plugin should be included by default starting in version 24.1. Choose the os-wireguard plugin under System -> Firmware -> Plugins. Do not use os-wireguard-go, I understand it's obsolete (why is it still in the plugins list then?)
WireGuard
Instances
Add a server by pressing the little + icon
MAKE SURE TO SELECT "SHOW ADVANCED"
- Enabled: [-]
- Name: NordVPN
- Public Key: paste public key
- Private Key: paste private key
- Listen Port: 51820 (or another unused port)
- DNS Server: 103.86.96.100, 103.86.99.100 (source)
- Tunnel Address: 10.5.0.2/16 (insert inet address from
ip addr show nordlynx
which should still be10.5.0.2
) - Peers: Nothing selected, leave blank for now
- Disable Routes: Check
- Gateway: 10.5.0.1
Click Save. Probably the DNS Server are used for allowing a FQDN on Endpoint Address instead of IP? Anyway, add the Address from which you have connected.
Peers
Create a new Peer by hitting the + icon. Here you will copy the information from the [peer] section (sudo wg).
- Name: jp524.nordvpn.com
- Public Key: insert public key from
sudo wg
(21dz9Y6HFRzaXKLpFpcZHjcI5AJQopJW/JZShKjTKkZ=
) - Shared Secret: leave empty
- Allowed IPs: 0.0.0.0/0
- Endpoint Address: 212.102.50.209
- Endpoint Port: 51820
- Keepalive: 25
Click Save.
Now, go back to Instances. Select the NordVPN WireGuard instance. Hit Edit (the little pencil).
- Under Peers, select the newly created
jp524.nordvpn.com
peer.
Click Save.
General
[-] Enable WireGuard
Hit Save.
After you have selected Save- go to List Configuration (might take some time to load).
Because of our persistent keepalive - you should see the received and sent transfer is steadily increasing.
Assignments
Now go to Interfaces > Assignments. You'll have a new interface you can assign (wg1
).
Assign this interface. After assignment, click the name of the interface (OPT3
or something similar).
Enable Interface
- Description: WG1
Leave rest of the configuration as is. Click Save.
Apply the changes.
Gateways
Go System > Gateways Click +Add gateway.
Name: WAN_WG1 Description: Interface WAN_WG1 Gateway Interface: WG1
IP address: 10.5.0.1
Far Gateway
Monitor IP: 1.1.1.1
Set rest to default.
Click Save, Apply.
Aliases
Go to Firewall > Aliases.
Add a new Alias.
- Enabled Checked
- Name wg_nordvpn_hosts
- Type Select either Host(s) or Network(s) in the dropdown, depending on whether you want specific host IPs to use the tunnel, or an entire local network (such as a VLAN)
- Content Enter the host IPs, or the network in CIDR format
Add a new Alias
- Enabled Checked
- Name RFC1918_Networks
- Type Select Network(s) in the dropdown
- Content 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
- Description All local (RFC1918) networks
Rules
Go to Firewall > Rules.
Select the designated interface for which you want to use WG. This can be LAN, but in my in case I chose OPT1.
Add Rule.
Action Pass Quick Checked Interface Whatever interface you are configuring the rule on (LAN, OPT1, VLAN, ...) Direction in TCP/IP Version IPv4 Protocol any Source / Invert Unchecked Source wg_nordvpn_hosts Destination / Invert Checked Destination RFC1918_Networks Destination port range any Gateway WAN_WG1
While we are at it, do this to enable a kill-switch for your traffic should the WireGuard interface go down. In Advanced settings: * Set local tag: NO_WAN_EGRESS
Click Add.
Add another rule on the same interface, but this time - make sure to select Block
.
Leave the rest as default.
This will also be our, additional, "kill switch". Make sure the block
rule is below the allow rule.
Kill switch
Firewall > Rules > Floating > +Add
Action: Block Interface: WAN Direction: out Description: NO_WAN_EGRESS match Match local tag: NO_WAN_EGRESS
Routing
Then go to Firewall ‣ Rules ‣ Floating
Click Add to add a new rule
- Action Pass
- Quick Unchecked
- Interface Do not select any
- Direction out
- TCP/IP Version IPv4
- Protocol any
- Source / Invert Unchecked
- Source "WG1 address"
- Destination / Invert Checked
- Destination "WG1 net"
- Destination port range any
- Gateway WAN_WG1
- allow options Checked (in advanced settings)
NAT
Firewall > NAT > Outbound Select Hybrid outbound NAT rule generation. Click Save and Apply Rules.
Then click +Add.
Interface WG1 TCP/IP IPv4 Source adress wg_openvpn_hosts Translation / target Interface address
Save. Apply changes.
DNS
Let us provide some security regards to DNS leaks on this 10_VPN interface of ours.
Services > DHCPv4
- OPT1
Add DNS servers provided by NordVPN here, so that DHCP offers DNS servers provided by NordVPN:
- DNS servers 103.86.96.100, 103.86.99.100
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 +
icon.
* Name: wg_nordvpn_dns
* Type: Host(s)
* Content: 103.86.99.100, 103.86.96.100
* Description: NordVPN DNS servers
Now, go to Firewall > NAT > Port Forward.
+Add
- Interface: OPT1
- Protocol: TCP / UDP
- Source: wg_nordvpn_hosts
- Destination / Invert: checked
- Destination: wg_nordvpn_dns
- Destination port range: DNS
- Redirect target IP: wg_nordvpn_dns
- Redirect target port: DNS
Sources: