OPNsense with NordVPN: Wireguard

I decided to revisit my setup for watching Japanese TV. So far I've been using Wireguard on a Netgear R6220 which has OpenWrt installed; but I want to give OPNsense a try. This will be on a little Protectli Vault FW4C appliance. Most of the tedious steps to retrieve the NordVPN configuration remains valid.

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 be 10.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:

Page top