Skip to content

v7.2.0

Latest

Choose a tag to compare

@azinchen azinchen released this 11 Aug 22:17
· 15 commits to master since this release
5195826

Access-token authentication (TOKEN), custom tunnel DNS (DNS), and a machine-readable status file headline this release, alongside a large reliability pass: silently skipped NETWORK/FORWARD_FROM values with whitespace, a crash-loop on non-OpenVPN TECHNOLOGY values, racing reconnections, and GATEWAY_DNS=redirect never applying its DNAT rules are all fixed.

📥 Pull this release

docker pull azinchen/nordvpn:7.2.0
docker pull ghcr.io/azinchen/nordvpn:7.2.0

⬆️ Upgrade notes

  • PUID/PGID have been removed. They never had an effect (OpenVPN runs as root; the container writes no host files), so nothing changes functionally — drop them from your configuration to silence the startup warning.
  • TOKEN is a new alternative to USER/PASS: generate an access token in the Nord Account dashboard and the container fetches the service credentials itself, refreshing them on every reconnect. USER/PASS take priority when both are set. See https://github.com/azinchen/nordvpn#getting-service-credentials
  • DNS overrides the server-pushed resolvers (resolution stays inside the tunnel); DNS=off leaves resolv.conf untouched. See https://github.com/azinchen/nordvpn/wiki/Custom-DNS
  • GATEWAY_DNS=redirect users: the redirect DNAT chain was never populated in previous releases; after upgrading, client DNS interception through the tunnel works as documented.
  • List values (NETWORK, COUNTRY, CHECK_CONNECTION_URL, …) now accept ; or , with whitespace around separators ignored.

✨ Features

  • Fetch OpenVPN service credentials from the NordVPN API with a TOKEN access token, with automatic re-fetch on every service start so rotated credentials self-heal (#1238, #1250)
  • DNS variable for custom tunnel resolvers, including DNS=off to leave resolv.conf unmanaged (#1258)
  • Publish the selected server (name, hostname, IP, load, location, timestamp) as world-readable /run/xt/status.json for monitoring (#1251)
  • GATEWAY_DNS_SERVER accepts a list of resolvers; each candidate is probed at startup and the first one answering is used (#1252)
  • NordVPN API access uses the bootstrap IPs exclusively (tried in order), removing the DNS-dependent attempt that always failed under the kill switch (#1240)

🐛 Bug Fixes

  • Trim whitespace around ;/,-separated list values; NETWORK="10.10.0.0/16; 10.20.0.0/16" previously skipped every value after the first separator silently (#1235)
  • GATEWAY_DNS=redirect never populated its DNAT chain: OpenVPN scrubs the environment for its scripts, so the redirect updater always saw the feature disabled — container env is now re-imported from the s6 store (#1258)
  • Non-OpenVPN TECHNOLOGY values (e.g. Wireguard, a typo) crash-looped the service with no log output instead of reporting a clear configuration error (#1241)
  • An unknown or retired specific-server hostname in COUNTRY/CITY aborted the whole server selection mid-loop (#1242)
  • Concurrent reconnections (overlapping cron schedules, manual runs) raced on the shared config paths and interleaved service restarts; runs are now serialized with a lock (#1248)
  • A hung OpenVPN shutdown could leave an orphaned process colliding with the next start on the management port and tun0; the service now records the PID and escalates to SIGTERM/SIGKILL (#1249)
  • The startup log claimed "Added firewall pinhole" even when the iptables rule failed; failures are now reported with a warning (#1247)
  • TOKEN was visible in the process list during the credential fetch; it now travels in a 0600 curl config file (#1246)
  • Scheduled jobs could fire before the VPN service had started; crond now starts after it (#1245)
  • Non-numeric CHECK_CONNECTION_ATTEMPTS/CHECK_CONNECTION_ATTEMPT_INTERVAL silently bypassed validation and broke the health check at runtime (#1243)
  • Network diagnostics printed the literal string AF_INET instead of the peer address (#1244)
  • mgmt_cmd fell back to the username instead of the password when the management password file was missing (#1259)

♻️ Refactoring

  • Remove the no-op PUID/PGID variables and the init-adduser service; a transitional startup warning tells existing configurations the variables can be dropped (#1239)

📖 Documentation

  • Environment variables regrouped into purpose-based tables with wiki deep links; list-separator behavior documented once (#1236, #1237)
  • Wiki: list separators and whitespace tolerance documented across pages, plus a troubleshooting entry for the partially-applied NETWORK symptom on older releases (#1237)
  • Wiki: all four specific-server hostname patterns documented (us1, ca-us100, nl-onion6, socks-nl1) and the resolution mechanism corrected to API lookup (#1255)
  • Wiki: quoted log strings aligned with actual output on four pages (#1254); stale --data-ciphers auto-injection claims removed (#1253)
  • TOKEN examples added to the compose/run example pages; example port mappings fixed to reach the sample app (#1256)
  • Architecture page synced with current behavior (reconnect locking and staging, pidfile shutdown escalation, TOKEN refresh, state files) and the diagnostics guide sample replaced with real output (#1260)
  • Reconnection/health-check tuning guidance (#1232)

🔧 CI/CD Updates

  • Automated apk version bumps are verified against every published architecture before opening a PR, preventing multi-arch build breakage from x86_64-only availability (#1257)
  • Dockerfile architecture mappings aligned with the full Alpine ∩ s6-overlay support matrix (ppc64le/s390x buildable locally; published set unchanged); published vs buildable platforms documented in the wiki (#1257)
  • Bump github/codeql-action from 4.37.4 to 4.37.6 (#1233)

🧩 Component versions

Component Version
OpenVPN 2.7.6
OpenVPN XOR patches 2.7.4
Alpine Linux 3.24.1
s6-overlay 3.2.3.2

Contributors

@azinchen, @dependabot[bot]

Full Changelog: v7.1.0...v7.2.0