OPNSense with a NordVPN tunnel for clients


NordVPN does not provide support for native router configurations using the WireGuard protocol. NordLynx, which has been developed by NordVPN, is fundamentally based on the WireGuard VPN protocol. It is possible to establish a NordVPN WireGuard tunnel for the router, and to enable the router to offer NordVPN to its clients. Here's how I configured NordVPN on OPNSense version 25.7... 

Step 1. Create a NordVPN Access Token
  • Sign in to NordVPN using your NordVPN Account username and password at https://my.nordaccount.com/dashboard/nordvpn/manual-configuration/.
  • Select Get Access token. NordVPN may ask you to verify your email. Enter the one-time login code to continue.
  • Select Generate new token.
  • Select expire in 30 days (30 days is fine as we only need this to retrieve the configuration parameters).
  • Select Generate Token.
  • Copy the Token and temporarily keep it in a note or text file. In the next step, you will need it to receive WireGuard configuration.

Step 2. Retrieve configuration parameters for WireGuard

Determine which country and city you want:

  • List of country IDs:

curl -s "https://api.nordvpn.com/v1/servers/countries" \ | jq -r '.[] | "\(.id) \(.name)"'

  • List cities in country, using countries returned above:

curl -s "https://api.nordvpn.com/v1/servers/countries" \| jq -r '.[] | select(.code=="US") | .cities[] | "\(.id) \(.name)"'

  • List city ID,

curl -s "https://api.nordvpn.com/v1/servers/countries" \| jq -r '.[] | select(.code=="US") | .cities[] | select(.name=="New York")'

  • To get the Endpoint IP address and PublicKey run the following inserting the country id and city id returned:

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

  • To retrieve the PrivateKey update the command below using the TOKEN from Step 1. and run it:
curl -s -u token:TOKEN https://api.nordvpn.com/v1/users/services/credentials | jq -r .nordlynx_private_key

Step 3. Create a Backup of System Configuration
  • OPNSense
  • Go to System ‣ Configuration ‣ Backup

Step 4. Create a WireGuard Peer

  • Go to VPN ‣ WireGuard ‣ Peers
  • Click + to add a new Peer
Configure the Peer as follows (if an option is not mentioned below, leave it as the default):
  • Public Key: obtain and insert this key from Step 2.
  • Allowed IPs: 0.0.0.0/0,::/0 # route everything
  • Endpoint Address: insert the address from Step 2.
  • Endpoint Port: Blank if 51820 was provided.
  • Instances: Nothing selected.
  • Keepalive interval: 25
  • Save.
Step 5. Create a WireGuard Instance
  • Go to VPN ‣ WireGuard ‣ Settings ‣ Instances
  • Click + to add a new Instance
Configure the Instance as follows (if an option is not mentioned below, leave it as the default)
  • Advance Mode: Toggled.
  • Name: WG_NordVPN (or whatever you choose).
  • PublicKey: Leave Blank. It will be generated based on your PrivateKey
  • PrivateKey: Obtain from step 2.
  • MTU: 1420 (WireGuard default) or 1412 when connecting to a PPPoE network (like most DSL connections).
  • DNS Servers: 103.86.96.100,103.86.99.100 (NordVPN DNS Servers).
  • Tunnel Address: 10.5.0.2/32. (same for all NordVPN tunnel).
  • Peers: Select the peer that you created in step 4.
  • Gateway: any unused IP within the tunnel address. For instance, the tunnel address is 10.5.0.2/32. we can use 10.5.0.3 as the Gateway IP address.
Step 6. Assign an interface to WireGuard
  • Go to Interfaces ‣ Assignments
  • Select the WireGuard – WG_NordVPN (wg0 if this is your first one) in the dropdown.
  • Add a description (ex WG_NordVPN).
  • Click Add to add it, then click Save.
Configure it as follows (if an option is not mentioned below, leave it as the default):
  • Then, select your new interface under the Interfaces menu.
  • Enable Interface: checked.
  • Prevent interface removal: checked (optional).
  • Save.
  • Apply chances.
Step 7. Create a Gateway
  • Go to System ‣ Gateway ‣ Configuration
  • Click + to add a new Gateway.
Configure the Gateway as follows (if an option is not mentioned below, leave it as the default):
  • IP Address: Endpoint IP Address from step 1 or the config file.
  • Far Fateway: Checked.
  • Disable Gateway Monitoring: Unchecked.
  • Monitor IP: Endpoint IP Address from step 1 or the config file.
  • Save.
Step 8. Create an Alias for local Host(s)/Net(s)
  • Go to Firewall ‣ Alias.
  • Click + to add a new alias.
Configure the Alias as follows (if an option is not mentioned below, leave it as the default):
  • Name: WG_NordVPN_Clients (or whatever you choose).
  • Type: if you select a single host or multiple hosts, then select Host(s). If you want to tunnel the whole subnet, then select Network(s).
  • Description: Local hosts/nets that will access the tunnel (optional).
  • Save.
Repeat the same step to create a second Alias for all local (private) networks.

Configure the Alias as follows (if an option is not mentioned below, leave it as the default):
  • Name: RFC1918_Networks
  • Type: Network(s)
  • Content:192.168.0.0/16
  • 10.0.0.0/8
  • 172.16.0.0/12
  • Description: All local (RFC1918) networks
  • Save.
  • Apply.
Step 9. Create a firewall rule for VPN client traffic heading outside the LAN
  • Go to Firewall ‣ Rules ‣ LAN
  • Click Add to add a new rule
Configure the LAN Rule as follows (if an option is not mentioned below, leave it as the default):
  • Source: WG_NordVPN_Clients (the first alias you created in step 8).
  • Destination/Invert: Checked.
  • Destination: RFC1918_Networks (the second alias you created in step 8).
  • Set local tag: NO_WAN_EGRESS (optional for adding a VPN kill Switch later)
  • Save
Step 10. Create a firewall rule to pass DNS traffic to the router (if used as a DNS server)
  • Go to Firewall ‣ Rules ‣ Floating
  • Click Add to add a new rule
Configure the Floating Rule as follows (if an option is not mentioned below, leave it as the default):
  • Source: WG_NordVPN_Clients
  • Destination: This firewall
  • Destination Port: TCP/UDP 53
  • Save the rule, and then click Apply changes
Step 11. Create a firewall rule to pass VPN traffic from the client and the gateway itself to the NordVPN gateway
  • Click Add to add a new rule
Configure the Floating Rule as follows (if an option is not mentioned below, leave it as the default):
  • Quick: Unchecked.
  • Source: WG_NordVPN address, WG_NordVPN_Clients
  • Destination / Invert: Checked.
  • Destination: WG_NordVPN net
  • Gateway: WAN_NordVPN.
  • Allow options: checked.
  • Save the rule, and then click Apply changes
Step 12. Create an rule for the VPN interface to NAT the VPN clients
  • Go to Firewall ‣ NAT ‣ Outbound
  • Select “Hybrid outbound NAT rule generation” If it is not already selected, click Save and then Apply changes.
Interface: WG_NordVPN
  • Source Address: WG_NordVPN_Clients (the first lias created at step 8.)
  • Description: Outbound rule for NordVPN (optional).
  • Save and Apply changes.
Step 13. Create a VPN Kill Switch (optional)
  • Go to Firewall ‣ Rules ‣ Floating
  • Click Add to add a new rule
Configure the Floating Rule as follows (if an option is not mentioned below, leave it as the default):
  • Action: Block
  • Interface: WAN
  • Direction: Out
  • Description: VPN Kill Switch
  • Match local tag: NO_WAN_EGRESS
Step 14. Testing

Check the tunnel is connected:
  • Go to VPN ‣ WireGuard ‣ Status
  • Ensure the NordVPN interface is green / connected
  • Ensure that the NordVPN peer is green / connected
From a client checking the tunnel:
Step 15. Troubleshooting

If the tunnel is connected but the client cannot reach the internet, then check the ordering of the LAN rules from step 9, ensure the rule created is above any rules that deny / drop traffic. 


Credit to:

bluewalk@github for original concept
dumbasPL@github for providing an efficient alternative method for retrieving this configuration

No comments:

Post a Comment

Note: only a member of this blog may post a comment.