Skip to content

Instantly share code, notes, and snippets.

@bluewalk
Last active October 2, 2024 18:58
Show Gist options
  • Save bluewalk/7b3db071c488c82c604baf76a42eaad3 to your computer and use it in GitHub Desktop.
Save bluewalk/7b3db071c488c82c604baf76a42eaad3 to your computer and use it in GitHub Desktop.
Getting NordVPN WireGuard details

About

Instructions to obtain WireGuard details of your NordVPN account. These can be used to setup a WireGuard tunnel on your router to NordVPN.

Source: https://forum.gl-inet.com/t/configure-wireguard-client-to-connect-to-nordvpn-servers/10422/27

Prerequisites

If you have any linux machine, use that or install a vm if you don't have one.

Get their official linux app installed. Make sure you have wireguard installed too. And set the used technology to Nordlynx by running nordvpn set technology nordlynx

Fetching details

Connect to nordvpn with command: nordvpn connect (don't forget to login with nordvpn login --legacy).

Fetch (your) IP address

After successful connection run

ifconfig nordlynx

Fetch your private key

Run

sudo wg show nordlynx private-key

Output of this command should be something like this:

CKMAE9LARlt2eZHgGnNaSUYiKllKJN7f3hed/bWm5E8=

The key above is just a random key for demo purposes.

Fetch your public key

Run

sudo wg show nordlynx public-key

Output of this command should be something like this:

TO158iXbNXt2eZHgGnNaSUYiKZHgGN7f3hed/bWm5E8=

The key above is just a random key for demo purposes.

Fetch server details

Make sure you have curl and jq installed on your host/router. These are needed to be able to fetch the config of NordVPN Server. If not installed, go ahead and install

opkg install curl jq

After installation enter the command below to fetch the recommended server config:

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'

Output:

uk1818.nordvpn.com #your endpoint host
178.239.166.185 #its ip address
London #city
United Kingdom #country
K53l2wOIHU3262sX5N/5kAvCvt4r55lNui30EbvaDlE= #Server public key
10 #Server load at the time.

Or just visit the following url https://api.nordvpn.com/v1/servers/recommendations?&filters\[servers_technologies\]\[identifier\]=wireguard_udp&limit=1 from your browser and look for the details manually.

@dsvf
Copy link

dsvf commented Jun 4, 2022

Here is a script to automatically collect this info and write it into a config file, as well as display the config as a QR code. Requires jq and qrencode. The script expects you to be connected via Nordlynx and sudo asks you for your password to get your private key and IP.

#!/bin/bash
my_interface=$(sudo wg show | grep interface | cut -d" " -f2)
my_privkey=$(sudo wg show $my_interface private-key)
my_ip=$(ip -f inet addr show $my_interface  | awk '/inet/ {print $2}')

read host ip city country serv_pubkey < <( echo $(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)'))

sid=$(echo $host | cut -d. -f1)
fn="nvpn_"$sid".conf"
echo Server: $host \($ip\) has pubkey $serv_pubkey

echo writing config to $fn
echo "#config for nordvpn server $sid"  > $fn
echo "[Interface]"                      >> $fn
echo "Address = $my_ip"                  >> $fn
echo "PrivateKey = $my_privkey"            >> $fn
echo ""                                 >> $fn
echo "[Peer]"                           >> $fn
echo "PublicKey = $serv_pubkey"         >> $fn
echo "AllowedIPs = 0.0.0.0/0"           >> $fn
echo "Endpoint = $host:51820"           >> $fn

echo ""
echo "Content of $fn:"
cat $fn

qrencode -t ansiutf8 < $fn

# uncomment this line to automatically copy the .conf to the wg directory, then you can use it directly with "wg-quick up nvpn_xy1234"
#sudo mv $fn /etc/wireguard && sudo chmod 600 /etc/wireguard/$fn

(quick edit to shorten the .conf filename, since wg-quick on linux does not support it if the .conf filename is longer than 15 chars)

@tekwarfare
Copy link

tekwarfare commented Aug 22, 2022

Thank you very much, @dsvf
I couldn't get my unraid wireguard tunnel working by entering the details manually - I didn't really know what went where. Happily, importing the conf generated by your script just worked. :)

@g-a-c
Copy link

g-a-c commented Jan 28, 2023

The nordvpn login --legacy no longer appears to work; it could be because I enabled MFA on my account or it could just be fully deprecated now.

However, the Nord VPN account panel allows you to generate a token (I recommend doing a 30 day expiry since I don't believe you should need to repeat these instructions), and then you can do

nordvpn login --token <TOKEN>

I was also doing this on a remote headless Linux machine (because it was quicker than downloading an ISO to make a local VM) and found that as soon as it was connected to the VPN I lost all access - almost certainly because the default route changed so my mosh session was disrupted. I tried doing nordvpn set routing off to try and stop the Nord VPN client from doing dumb stuff with my routing table, but that didn't work. What did work was taking advantage of "shortest-route-wins" and adding a route for my source IP to use the existing gateway which took precedence over the new default route:

# find my default gateway
root@instance:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         172.20.0.1      0.0.0.0         UG        0 0          0 enp0s3
169.254.169.254 172.20.0.1      255.255.255.255 UGH       0 0          0 enp0s3
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U         0 0          0 br-1d9cab47c790
172.20.0.0      0.0.0.0         255.255.255.192 U         0 0          0 enp0s3
172.20.0.1      0.0.0.0         255.255.255.255 UH        0 0          0 enp0s3

# add a new route via the existing gateway, substitute your source IP for 127.127.127.127
# if you don't know your IP then https://ipv4.icanhazip.com from your client machine
root@instance:~# route add -host 127.127.127.127 gw 172.20.0.1

# verify the route was added
root@instance:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         172.20.0.1      0.0.0.0         UG        0 0          0 enp0s3
127.127.127.127 172.20.0.1      255.255.255.255 UGH       0 0          0 enp0s3 <<<<<<<<<<<
169.254.169.254 172.20.0.1      255.255.255.255 UGH       0 0          0 enp0s3
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U         0 0          0 br-1d9cab47c790
172.20.0.0      0.0.0.0         255.255.255.192 U         0 0          0 enp0s3
172.20.0.1      0.0.0.0         255.255.255.255 UH        0 0          0 enp0s3

Hope this helps someone stumbling across this gist...

@benknight
Copy link

It's been quite difficult to get set up with a Linux VM on macOS to be able to do this. I've tried using Lima and well as a Docker image and hit dead ends in both cases. Lima doesn't work because as soon as you turn on the VPN you can no longer access the VM. Docker doesn't work because systemctl isn't supported in Docker images. If anyone has a simple and free way to get a Linux VM working on macOS where you can actually get the Nord Wireguard config, please share!

@g-a-c
Copy link

g-a-c commented Feb 13, 2023

It's been quite difficult to get set up with a Linux VM on macOS to be able to do this. I've tried using Lima and well as a Docker image and hit dead ends in both cases. Lima doesn't work because as soon as you turn on the VPN you can no longer access the VM. Docker doesn't work because systemctl isn't supported in Docker images. If anyone has a simple and free way to get a Linux VM working on macOS where you can actually get the Nord Wireguard config, please share!

I would expect Virtualbox would work fine, since even if you lose network connectivity you still have the virtual console?

Otherwise it may be that you can use the same behaviour I posted above (shortest route wins in a routing table) to allow local traffic to not be disrupted within your VM. If you were to check the routing table on your Lima VM before starting, then add routes for 192.168.0.0/16, 172.16.0.0/12 and 10.0.0.0/8 via whatever the pre-existing gateway is, you may find that network access is retained.

@bluewalk
Copy link
Author

You can whitelist SSH ports to be able to access your box even when VPN is on (or use the console from your VPS hoster).

nordvpn whitelist add port 22 - Add a rule to whitelist a specified incoming port. You can also whitelist multiple ports — just separate their numbers with a space.
nordvpn whitelist remove port 22 - Remove the rule to whitelist a specified port.
nordvpn whitelist add subnet 192.168.0.0/16 - Add a rule to whitelist a specified subnet.
nordvpn whitelist remove subnet 192.168.0.0/16 - Remove the rule to whitelist a specified subnet.

as per https://support.nordvpn.com/Connectivity/Linux/1325531132/Installing-and-using-NordVPN-on-Debian-Ubuntu-Raspberry-Pi-Elementary-OS-and-Linux-Mint.htm

Or simpler; chain the commands ending with nordvpn disconnect

@benknight
Copy link

benknight commented Feb 13, 2023

Beautiful! Running nordvpn whitelist add port 22 on my VM did the trick.

By the way, I think the public key should be the Wireguard server's public key as for example returned by the API rather than the output of sudo wg show nordlynx public-key which is a different value.

@darki73
Copy link

darki73 commented Mar 11, 2023

Here is an updated version of the script, which will also install any required packages in order to generate configuration file:

#!/usr/env/bin bash

required_packages=()

check_if_connected() {
    if [ -n "$(nordvpn status | grep "Status: Connected")" ]; then
        return 0
    else
        return 1
    fi
}

# Check whether jq package is installed
if ! command -v jq &> /dev/null; then
    required_packages+=("jq")
fi

# Check whether wireguard package is installed
if ! command -v wg &> /dev/null; then
    required_packages+=("wireguard")
fi

# Check if curl package is installed
if ! command -v curl &> /dev/null; then
    required_packages+=("curl")
fi

# Check if nordvpn package is installed
if ! command -v nordvpn &> /dev/null; then
    required_packages+=("nordvpn")
fi

# Install missing packages required to generate the configuration file
if [ ${#required_packages[@]} -gt 0 ]; then
    sudo apt install -y "${required_packages[@]}"
fi

if ! check_if_connected; then
    nordvpn connect
fi

interface_name=$(sudo wg show | grep interface | cut -d " " -f 2)
private_key=$(sudo wg show $interface_name private-key | cut -d " " -f 2)
my_address=$(ip -f inet addr show $interface_name | grep inet | awk '{print $2}' | cut -d "/" -f 1)

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

server_identifier=$(echo $host | cut -d "." -f 1)
configuration_file="nordvpn-$server_identifier.conf"

{
    echo "# Configuration for $host ($ip) in $city, $country"
    echo "[Interface]"
    echo "Address = $my_address"
    echo "PrivateKey = $private_key"
    echo ""
    echo "[Peer]"
    echo "PublicKey = $server_public_key"
    echo "AllowedIPs = 0.0.0.0/0"
    echo "Endpoint = $host:51820"
} > "$configuration_file"

if check_if_connected; then
    nordvpn disconnect
fi

It will also automatically connect to NordVPN and then disconnect after configuration file is generated.

@helipos
Copy link

helipos commented Apr 29, 2023

nordvpn login --legacy

This options looks like it has been removed at least in Nordvpn 3.16.2

To get around that.
From https://www.reddit.com/r/nordvpn/comments/rp59mn/log_in_to_nordvpn_in_the_terminal/

linux# nordvpn login
Follow the link on a web browser somwhere,
login and cancel the popup link
copy the link address for the "continue" link

linux#nordvpn login --callback "PASTE THAT CONTINUE LINK HERE"

You should now be logged on.

@tekwarfare
Copy link

I could not get the web browser login to work method to work no matter what variations I tried. The only method I managed to get working was the one mentioned by @g-a-c

nordvpn login --token
Go to nordaccount.com and click on NordVPN.
Scroll down until you see the Access token tab. Click on Generate new token.

@rausb
Copy link

rausb commented Oct 10, 2023

Learn here how to login NordVPN via command line, you can now generate login tokens in your account overview

@JohanChungus
Copy link

what about on android?

@onxb
Copy link

onxb commented Nov 5, 2023

I have successfully authenticated via the token ( via Docker Ubuntu VM) however running "nordvpn connect" quickly errors out with
"Connection failed. Please try again. If the problem persists, contact our customer support."
Any suggestions while I wait for the support team to reply?

@kinhsman
Copy link

Does anyone know how to fetch the server details on a specific country/city?

@ShakeyPlace
Copy link

@ kinhsman, just connect to the specific country, city or server first then get the details as in the script.
for example nordvpn connect dallas you can also run commands to get valid names for countries or cities

@lluked
Copy link

lluked commented Dec 15, 2023

I was looking for a fast way to update config with little input so I created a docker compose project based off of this, https://github.com/lluked/NordVPN_Get-WireGuard-Config/tree/main

All that is needed is a NordVPN Token, once run the config is outputted to the output folder.

@stayingarmed
Copy link

has anyone had any luck with the script posted by dsvf lately? I just tried it and it doesn't seem to pull the privatekey info and if I manually check the public key it doesn't match what is in the config file that the script pulls.

@bobziroll
Copy link

For anyone interested in a way to get the private key on MacOS, this video shows how to do it simply by opening the KeyChain Access program and getting it from there! Takes about 1 minute :)

@stayingarmed
Copy link

For anyone interested in a way to get the private key on MacOS, this video shows how to do it simply by opening the KeyChain Access program and getting it from there! Takes about 1 minute :)

I’m gonna say they killed this off. I tried it a couple of times on Ventura and can’t pull the info needed

@bobziroll
Copy link

I’m gonna say they killed this off. I tried it a couple of times on Ventura and can’t pull the info needed

I'm on the most updated MacOS Sonoma 14.2.1 and it worked fine. 🤷🏻‍♂️

@vgyarfas
Copy link

vgyarfas commented Feb 8, 2024

For anyone interested in a way to get the private key on MacOS, this video shows how to do it simply by opening the KeyChain Access program and getting it from there! Takes about 1 minute :)

I’m gonna say they killed this off. I tried it a couple of times on Ventura and can’t pull the info needed

This only works if you download the app from the Mac App Store and NOT directly from the NordVPN website. Struggled with this a little bit myself.

@bobziroll
Copy link

This only works if you download the app from the Mac App Store and NOT directly from the NordVPN website. Struggled with this a little bit myself.

Good to know. I don't remember downloading it from the Mac App Store, but it's definitely possible I did. Hope it's still able to help someone else in the future though!

Copy link

ghost commented Feb 10, 2024

Does this work for Raspberry Pi OS?

@dz-c0d3r
Copy link

dz-c0d3r commented Feb 28, 2024

I update the script to get all configs for a specific city and technology.

`
#!/bin/bash

my_interface=$(sudo wg show | grep interface | cut -d" " -f2)
my_privkey=$(sudo wg show $my_interface private-key)
my_ip=$(ip -f inet addr show $my_interface | awk '/inet/ {print $2}')

servers=$(curl --silent "https://api.nordvpn.com/v1/servers?limit=999999" | jq --raw-output '.[] | select(.locations[].country.city.name == "Paris") | select(.technologies[] | .name == "Wireguard") | select(.status == "online") | "(.hostname) (.station) ((.locations|.[]|.country|.city.name)) ((.locations|.[]|.country|.name)) ((.technologies|.[].metadata|.[].value))"')

echo "$servers" | while read -r server_info; do
read -r host ip city country serv_pubkey <<<"$server_info"
sid=$(echo $host | cut -d. -f1)
fn="nvpn_${sid}.conf"
echo "Server: $host ($ip) has pubkey $serv_pubkey"

echo "writing config to $fn"
{
    echo "#config for nordvpn server $sid"
    echo "[Interface]"
    echo "Address = $my_ip"
    echo "PrivateKey = $my_privkey"
    echo ""
    echo "[Peer]"
    echo "PublicKey = $serv_pubkey"
    echo "AllowedIPs = 0.0.0.0/0"
    echo "Endpoint = $host:51820"
} > "$fn"

echo ""
echo "Content of $fn:"
cat "$fn"
echo "----------------------------------------"

done
`

Enjoy it <3

@macnug
Copy link

macnug commented Mar 3, 2024

HI
I did run the script, but my fritzbox show error:

"Unfortunately, it was not possible to apply your settings.
Imported configuration file of WireGuard remote site triggered a key conflict with existing connections. Click on 'Close' to go to the WireGuard overview and set up the WireGuard connection again".

I did try delete all the other wireguard connections but now i have:

"Unfortunately, your settings could not be applied correctly.
Click "Close" to access the WireGuard overview and re-establish the WireGuard connection."

Any suggestion?

Thank you very much!

@dumbasPL
Copy link

dumbasPL commented Mar 5, 2024

alternative way without downloading their software (needs curl and jq):

  1. go to https://my.nordaccount.com/dashboard/nordvpn/manual-configuration/ and create an access token
  2. get your private key
curl -s -u token:<ACCESS_TOKEN> https://api.nordvpn.com/v1/users/services/credentials | jq -r .nordlynx_private_key
  1. get server info
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'
  1. create config:
[Interface]
PrivateKey = <PRIVATE_KEY> # from step 2
Address = 10.5.0.2/32 # this IP is always the same
DNS = 9.9.9.9 # your favorite DNS server

[Peer]
PublicKey = <PUBLIC_KEY> # from step 3
AllowedIPs = 0.0.0.0/0, ::/0 # route everything
Endpoint = <ENDPOINT>:51820 # endpoint or IP from step 3, the port is always the same

@mzdial
Copy link

mzdial commented Mar 6, 2024

Works perfectly for me. Thanks so much for posting this!

alternative way without downloading their software (needs curl and jq):

snip

@frankthecrank
Copy link

Works perfectly for me. Thanks so much for posting this!

did you use it by any chance in a fritzbox router?

HI I did run the script, but my fritzbox show error:

"Unfortunately, it was not possible to apply your settings. Imported configuration file of WireGuard remote site triggered a key conflict with existing connections. Click on 'Close' to go to the WireGuard overview and set up the WireGuard connection again".

I did try delete all the other wireguard connections but now i have:

"Unfortunately, your settings could not be applied correctly. Click "Close" to access the WireGuard overview and re-establish the WireGuard connection."

Any suggestion?

Thank you very much!

no suggestions, did you fix it? cause I am trying the same, and i get all the keys, the endpoint IP for a turkey-server, but the wireguard vpn won't work, so I guess its a fritzbox problem?

@macnug
Copy link

macnug commented Mar 9, 2024

—snip—- let’s keep this readable

no suggestions, did you fix it? cause I am trying the same, and i get all the keys, the endpoint IP for a turkey-server, but the wireguard vpn won't work, so I guess its a fritzbox problem?


I did try but i figured out that frtitzbox need to have also DHCP ip modification. I don't want to modify the fixed ips of 50 devices, so i don't know how to proceed

@J-K3X4
Copy link

J-K3X4 commented Mar 9, 2024

—snip—- let’s keep this readable

I did try but i figured out that frtitzbox need to have also DHCP ip modification. I don't want to modify the fixed ips of 50 devices, so i don't know how to proceed

Maybe this is for other post but just one question, have you been able to load conf file on a fritzbox? For me it has been impossible.

However, I have tested to load this conf file on a standard wireguard client and it works perfectly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment