Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NordVPN WireGuard Config Generator (web app)

A small web app with a landing page that shows NordVPN's recommended WireGuard server — country flag, city, endpoint IP, hostname, live load meter and feature tags — and builds a ready-to-import WireGuard .conf from it. Deploys to Netlify or Vercel with no changes.

🔒 Your private key never leaves your browser. The config is assembled client-side. The serverless functions proxy the public server lookup — and, only if you opt into it, one authenticated call that turns your NordVPN access token into a private key (details).

Landing page

The page auto-loads a recommended server on open and displays:

  • Flag + country + city (flags are SVGs from flagcdn — emoji flags don't render on Windows)
  • Endpoint IP, hostname, and server name
  • A load meter (green / amber / red by utilization)
  • Feature chips from the server's groups (e.g. P2P)
  • A country picker to choose any location, plus Get another server to re-roll, and a link to view the location on a map

Why detection happens in the browser

NordVPN's recommendations endpoint picks the closest server based on the IP that calls it. If the serverless function called it directly, every visitor would get a server near the deploy region (e.g. a US server from a US datacenter). So the browser detects the visitor's country client-side (via geojs.io, falling back to ipapi.co / ipwho.is), maps it to a NordVPN country id using /api/countries, and passes it to /api/recommend?country=<id>. The picker lets visitors override the detected country.

Below that, two more sections: fetch your private key from a NordVPN access token, then the config builder — private key → live .conf preview → download or copy.

Deep links

Both steps are addressable, so you can link straight to the one you need:

Link Lands on
https://nordconf-wg.netlify.app/#private_key the access-token → private-key step
https://nordconf-wg.netlify.app/#build_conf the .conf builder

Aliases are accepted and case-insensitive: #private-key, #privatekey, #key, #token all resolve to the first; #build-conf, #buildconf, #build, #config, #conf to the second. An unrecognised hash is ignored and the page loads normally.

The target section is scrolled to the top, flashed briefly so it's obvious where you landed, and its input is focused — except on touch devices, where the on-screen keyboard would cover it. Because the hero grows when the server loads (pushing the sections below it down), the position is corrected once after the first render rather than relying on the browser's initial jump alone.

Getting the private key from an access token

If you don't have your NordLynx private key handy, paste a NordVPN access token instead (Nord Account → Services → NordVPN → Manual setup → Generate new token). The app exchanges it for the key and fills the builder below.

⚠️ The token does pass through the serverless function. NordVPN's /v1/users/services/credentials endpoint requires HTTP Basic auth and sends no CORS headers, so the browser can't call it directly. The function forwards the token once, never logs or stores it, and responds Cache-Control: no-store. This is the one exception to the "nothing sensitive leaves the browser" rule — the private key itself still never does.

Don't want to trust the proxy? The page has a Run it yourself instead toggle with the equivalent command:

curl -s -u token:<YOUR_TOKEN> \
  https://api.nordvpn.com/v1/users/services/credentials \
  | grep -o '"nordlynx_private_key":"[^"]*"'

How it works

Browser  ──click──▶  /api/recommend  ──▶  NordVPN recommendations API
   ▲                       │
   │   name, endpoint IP,  │
   └───  public key  ◀─────┘
   │
   └─ you type your PrivateKey ─▶ .conf is built & downloaded locally

The serverless function exists only to dodge browser CORS on the NordVPN API. It never receives — and never handles — your private key.

Where each value comes from

Config field Source
name (file name) API → name (e.g. Greece #111 → saved as Greece_111.conf)
Endpoint IP API → station; port 51820 is fixed for wireguard_udp
PublicKey (peer) API → the wireguard_udp technology's metadata.public_key
PrivateKey You — typed into the browser, kept local; or fetched via /api/credentials from your access token
Address = 10.5.0.2/16 Static NordLynx client address (same for every server)
DNS = 103.86.96.100 Static NordVPN resolver (secondary 103.86.99.100)

Get your PrivateKey from your NordVPN account's manual WireGuard setup page, or use the access-token section described above.

Project layout

public/                 # static front-end (served at /)
  index.html
  style.css
  app.js                # builds & downloads the .conf, entirely client-side
lib/nordvpn.js          # shared: recommendation, country list, token → key
api/                    # Vercel serverless functions
  recommend.js
  countries.js
  credentials.js        # POST { token } → { privateKey }
netlify/functions/      # same three, Netlify flavour
  recommend.js
  countries.js
  credentials.js
vercel.json             # Vercel: static = public/, function config
netlify.toml            # Netlify: publish dir, functions dir, /api redirects

Both platforms serve public/ as the site and expose the functions under /api/*.

Deploy

Vercel

  1. Push this folder to a Git repo (GitHub/GitLab/Bitbucket).
  2. In Vercel, New Project → Import the repo.
  3. Framework preset: Other. Leave build command empty. Deploy.

Or from the CLI:

npx vercel        # preview
npx vercel --prod # production

Netlify

  1. Push to a Git repo.
  2. In Netlify, Add new site → Import an existing project, pick the repo. netlify.toml sets everything (publish dir, functions, /api redirect).

Or from the CLI:

npx netlify-cli deploy         # draft
npx netlify-cli deploy --prod  # production

Run locally

The static page alone (the Fetch button needs the function, so use a platform CLI for the full flow):

npm run dev            # static only, http://localhost:3000
npm run dev:vercel     # full app with the function (Vercel CLI)
npm run dev:netlify    # full app with the function (Netlify CLI)

Node 18+ is required (the function uses the built-in global fetch).

Security notes

  • The generated .conf contains your private key — treat it like a password. *.conf is git-ignored.
  • /api/recommend and /api/countries send no query data beyond an optional numeric country id and never log or store request bodies.
  • /api/credentials is the only endpoint that sees a secret. Your access token is forwarded to NordVPN in one Basic-auth request and discarded — not logged, not stored, response marked no-store. Treat the token like a password, and revoke it in Nord Account if you ever suspect it leaked. If you'd rather not send it at all, use the curl command above and paste the key manually.

License

MIT

About

Web app that turns NordVPN's recommended WireGuard server into a ready-to-import .conf — private key never leaves your browser.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages