What's new
  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

VPNMON VPNMON-R3 Custom OVPN Server List Generation Tutorials and Examples

Really sorry, @iTyPsIDg ... but this kind of low level customization to just get 1 VPN provider working really goes against what VPNMON-R3 is all about. It's meant to be used with any VPN provider that provides some level of publicly available API that you can query against, if you want to go down that level of automation. I would probably suggest writing a separate custom script that will generate an IP list that you could use to overwrite the one that VPNMON-R3 would use for that slot. Maybe run it once or twice a day to keep the list fresh based on a cron job?
Yeah, I understand. It really overcomplicates things. Thanks for all the work you've done on this.
 
Is the jquery for NordVPN broken for anyone else? I seem to be getting an error when it's executing the auto-update.... Nothing has changed in my config for at least 3 months :/

From the menu option U, I run x1 to update the server list and get the following:


[Executing Script]
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors https://api.nordvpn.com/v1/servers?limit=16354 | jq --raw-output '.[] | select(.locations[0].country.city.name == "New York") | .station'

jq: parse error: Invalid numeric literal at line 1, column 17391818

[0 Rows Retrieved From Source]

[Saved to VPN Client Slot 1 Server List]

[Execution Complete]
 
Is the jquery for NordVPN broken for anyone else? I seem to be getting an error when it's executing the auto-update.... Nothing has changed in my config for at least 3 months :/

From the menu option U, I run x1 to update the server list and get the following:


[Executing Script]
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors https://api.nordvpn.com/v1/servers?limit=16354 | jq --raw-output '.[] | select(.locations[0].country.city.name == "New York") | .station'

jq: parse error: Invalid numeric literal at line 1, column 17391818

[0 Rows Retrieved From Source]

[Saved to VPN Client Slot 1 Server List]

[Execution Complete]
This curl statement seems to work for me?

Code:
ViktorJp@GT-AX6000-3C88:/tmp/home/root# curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors https://api.nordvpn.com/v1/servers?limit=16
354 | jq --raw-output '.[] | select(.locations[0].country.city.name == "New York") | .station'
217.138.198.235
217.138.208.211
217.138.208.219
217.138.208.139
217.138.208.147
86.107.55.227
86.107.55.230
...

Sometimes they can have an error in their data or XML formatting output causing errors like that parse error you see. Perhaps they have already corrected it? :)
 
The full JSON downloads fine and is readable, so it doesn't appear an issue with NordVPN
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors https://api.nordvpn.com/v1/servers?limit=16354 -o servers.json

So, I increased the timeout values and it's working again - hopefully this is helpful for others if they encounter a similar issue
curl --silent --retry 3 --connect-timeout 10 --max-time 60 --retry-delay 1 --retry-all-errors https://api.nordvpn.com/v1/servers?limit=16354 | jq --raw-output '.[] | select(.locations[0].country.city.name == "New York") | .station'
 
The full JSON downloads fine and is readable, so it doesn't appear an issue with NordVPN
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors https://api.nordvpn.com/v1/servers?limit=16354 -o servers.json

So, I increased the timeout values and it's working again - hopefully this is helpful for others if they encounter a similar issue
curl --silent --retry 3 --connect-timeout 10 --max-time 60 --retry-delay 1 --retry-all-errors https://api.nordvpn.com/v1/servers?limit=16354 | jq --raw-output '.[] | select(.locations[0].country.city.name == "New York") | .station'
Nice! Glad you found a workaround ;)
 
My goal with this post is not to reinvent the wheel from all the examples @Viktor Jaep has provided for NordVPN. My goal is to provide two examples for NordVPN so that you can create your own custom server list query for WireGuard. If Viktor wants to cut/paste these instructions into the first post, be my guest. I basically took his post and modified it for WireGuard anyway.

Step 1) Nord uses a single private key for all VPN servers. You will need to visit Nord and generate an access token before you can locate your private key.
  1. Go to this NordVPN link.
  2. Click the "Set up NordVPN manually" button.
    1752941529467.png
  3. After completing the email verification, you will be directed to a page that allows you to generate an access token. Click the "Generate new token" button.
    1752941625203.png
  4. Leave the token expiration as is (private keys don't seem to change, so it is fine if it expires in 30 days). Click the "Generate token" button.
    1752941675000.png
  5. Copy the access token for use in the next step and close the pop-up dialog.
    1752941696381.png

Step 2) Obtain your private key
Bash:
curl -s -u token:"{ACCESS_TOKEN_FROM_PREVIOUS_STEP}" "https://api.nordvpn.com/v1/users/services/credentials" | jq -r .nordlynx_private_key
Use this private key in the following curl examples.

1) Top 5 Recommended WireGuard NordVPN Servers: This example shows you how to export all recommended NordVPN Server IPs that is based on a NordVPN algorithm per your location, and should be the fastest with the lowest load ... copy and paste the curl statements into an SSH window on your router to test their output.

First, determine the ID for your chosen country. (Exact number is of great importance!). The ID is in [ ] directly next to your country name.
Bash:
curl --silent "https://api.nordvpn.com/v1/servers/countries" | jq --raw-output '.[] | . as $parent | .cities[] | [$parent.name, $parent.id, .name, .id] | "\(.[0]) [\(.[1])] - \(.[2]) [\(.[3])]"'

Once you have found your Country ID, replace the ID in the curl statement below. In this example, I'm using the United States, which is ID 228. Also, replace your Private Key with the value you obtained previously. If the output creates a five-column list that looks like a CSV (example output below), you can copy/paste this statement into your VPNMON-R3 Server List Automation Slot and execute it in order to generate a list.
Bash:
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors "https://api.nordvpn.com/v1/servers/recommendations?filters\[country_id\]=228&filters\[servers_groups\]\[identifier\]=legacy_standard&filters\[servers_technologies\]\[identifier\]=wireguard_udp&limit=5" | jq --raw-output '.[] | . as $parent | .technologies | .[] | select(.identifier == "wireguard_udp") | [$parent.name, $parent.station, .metadata[0].value] | "\(.[0]),\(.[1]),51820,{REPLACE_WITH_YOUR_PRIVATE_KEY},\(.[2])"'

Output:

Code:
United States #9397,185.203.218.154,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
United States #9391,185.203.218.142,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
United States #9392,185.203.218.144,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=

Another option, if you want to display the city and server ID in column one, looks like this (and is my preferred method):
Bash:
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors "https://api.nordvpn.com/v1/servers/recommendations?filters\[country_id\]=228&filters\[servers_groups\]\[identifier\]=legacy_standard&filters\[servers_technologies\]\[identifier\]=wireguard_udp&limit=5" | jq --raw-output '.[] | . as $parent | .technologies | .[] | select(.identifier == "wireguard_udp") | [$parent.locations[].country.city.name, ($parent.name | split("#") | .[1]), $parent.station, .metadata[0].value] | "\(.[0]) #\(.[1]),\(.[2]),51820,{REPLACE_WITH_YOUR_PRIVATE_KEY},\(.[3])"'

Output:

Code:
Miami #6610,37.120.215.35,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
Miami #9382,185.203.218.124,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
Miami #9396,185.203.218.152,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
Miami #5940,185.245.86.54,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
Miami #9394,185.203.218.148,51820,PRIVATE_KEY,e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
 
Last edited:
My goal with this post is not to reinvent the wheel from all the examples @Viktor Jaep has provided for NordVPN. My goal is to provide two examples for NordVPN so that you can create your own custom server list query for WireGuard. If Viktor wants to cut/paste these instructions into the first post, be my guest. I basically took his post and modified it for WireGuard anyway.
This is fantastic!! Quick correction - your step 2 has a extra floating parenthesis at the end. ;) Just remove that and it will work.

Here's my CURL to grab all 2200+ NordVPN WG servers in the US. Getting ready to do crazy random resets to random WG servers across the US.

Code:
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 1 --retry-all-errors "https://api.nordvpn.com/v1/servers?limit=16354&filters\[country_id\]=228&filters\[servers_groups\]\[identifier\]=legacy_standard&filters\[servers_technologies\]\[identifier\]=wireguard_udp" | jq --raw-output '.[] | . as $parent | .technologies | .[] | select(.identifier == "wireguard_udp") | [$parent.locations[].country.city.name, ($parent.name | split("#") | .[1]), $parent.station, .metadata[0].value] | "\(.[0]) WG #\(.[1]),\(.[2]),51820,<MY PRIVATE KEY>,\(.[3])"'

Could you please add instructions on how to initially set up your WG slot? Do you download a WG .config from NordVPN? I'm still poking around out there, and not seeing much about it.
 
This is fantastic!! Quick correction - your step 2 has a extra floating parenthesis at the end. ;) Just remove that and it will work.
Thanks! Fixed.
Could you please add instructions on how to initially set up your WG slot? Do you download a WG .config from NordVPN? I'm still poking around out there, and not seeing much about it.
You can use this to create a conf (I don't setup DNS so that it goes through the router):
Code:
# United States - Miami - us9106.nordvpn.com.conf

[Interface]
PrivateKey = {PRIVATE_KEY}
Address = 10.5.0.2/32

[Peer]
PublicKey = e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 94.140.11.25:51820
That should get anyone ready to use VPNMON-R3.
 
Thanks! Fixed.

You can use this to create a conf (I don't setup DNS so that it goes through the router):
Code:
# United States - Miami - us9106.nordvpn.com.conf

[Interface]
PrivateKey = {PRIVATE_KEY}
Address = 10.5.0.2/32

[Peer]
PublicKey = e8LKAc+f9xEzq9Ar7+MfKRrs+gZ/4yzvpRJLRJ/VJ1w=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 94.140.11.25:51820
That should get anyone ready to use VPNMON-R3.
Oh that worked PERFECTLY! :)

1752949937597.png
 
That should get anyone ready to use VPNMON-R3.
@iTyPsIDg ... If you have time, I would love for you to please create a whole separate "VPNMON-R3 Custom Wireguard Server List Generation Tutorials and Examples" thread -- if you're up for managing it! You probably want to claim the first 5 message spots for future expansion. And assign it the "VPNMON" badge?

I think this is definitely going to require some dedicated space to explain the intricate details in getting this working... and kinda like I did with the various VPN providers, getting input from others and making sure the CURL/JQ's work... you seem to be excellent at them! And you have a great handle on Wireguard, and bending my script to your will! Hah!

Would you please do me this honor?? :)
 
@iTyPsIDg ... If you have time, I would love for you to please create a whole separate "VPNMON-R3 Custom Wireguard Server List Generation Tutorials and Examples" thread -- if you're up for managing it! You probably want to claim the first 5 message spots for future expansion. And assign it the "VPNMON" badge?

I think this is definitely going to require some dedicated space to explain the intricate details in getting this working... and kinda like I did with the various VPN providers, getting input from others and making sure the CURL/JQ's work... you seem to be excellent at them! And you have a great handle on Wireguard, and bending my script to your will! Hah!

Would you please do me this honor?? :)
Not today, but I can do that Monday.
 
Not today, but I can do that Monday.
Brilliant work. I did have a script (from reddit) that would give me a list of UK servers, but now I'm happily testing VPNMON-R3 alpha with a list of 15 more local NORD Wireguard servers.
 
My goal is to provide two examples for NordVPN so that you can create your own custom server list query for WireGuard

And you have suceeded admirably. Even a numbskull like me managed to get it working for Sydney Australia ...

Thanks very much @iTyPsIDg !!
 

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Back
Top