docs: expand nordvpn client setup and troubleshooting

This commit is contained in:
Stefano Fiorini
2026-03-12 02:45:21 -05:00
parent 7d8eb89911
commit e6dccb5656
3 changed files with 476 additions and 129 deletions

View File

@@ -2,14 +2,21 @@
Cross-platform NordVPN lifecycle skill for macOS and Linux.
## What it does
## Overview
- Probes whether NordVPN is already installed or automation-ready
- Bootstraps the required backend if missing
- Handles login/bootstrap
- Connects to a country or city target
- Disconnects and reports status
- Verifies public IP and geolocation after connect
`nordvpn-client` is the operator-facing VPN control skill for OpenClaw. It can:
- detect whether the host is ready for NordVPN automation
- install or bootstrap the required backend
- validate auth
- connect to a target country or city
- verify the public exit location
- disconnect and restore normal local networking state
The skill uses different backends by platform:
- Linux: official `nordvpn` CLI
- macOS: NordLynx/WireGuard with `wireguard-go` and `wireguard-tools`
## Commands
@@ -21,46 +28,15 @@ node skills/nordvpn-client/scripts/nordvpn-client.js verify
node skills/nordvpn-client/scripts/nordvpn-client.js verify --country "Italy"
node skills/nordvpn-client/scripts/nordvpn-client.js verify --country "Italy" --city "Milan"
node skills/nordvpn-client/scripts/nordvpn-client.js connect --country "Italy"
node skills/nordvpn-client/scripts/nordvpn-client.js connect --city "Milan"
node skills/nordvpn-client/scripts/nordvpn-client.js connect --city "Tokyo"
node skills/nordvpn-client/scripts/nordvpn-client.js connect --country "Japan" --city "Tokyo"
node skills/nordvpn-client/scripts/nordvpn-client.js disconnect
node skills/nordvpn-client/scripts/nordvpn-client.js status --debug
```
## Platform behavior
### macOS
- preferred backend: NordLynx/WireGuard
- install path: `brew install wireguard-go wireguard-tools`
- automation requirements:
- `NORDVPN_TOKEN` or `NORDVPN_TOKEN_FILE`
- `wireguard-go`
- `wireguard-tools`
- non-interactive `sudo` for `~/.openclaw/workspace/skills/nordvpn-client/scripts/nordvpn-wireguard-helper.sh`
- the macOS WireGuard config uses NordVPN DNS directly:
- `103.86.96.100`
- `103.86.99.100`
- before connect, the skill automatically suspends Tailscale if it is active
- after disconnect, or after a failed connect, the skill brings Tailscale back up if it suspended it
- `NordVPN.app` may stay installed but is only the manual fallback
- the app login is not reused by the automated WireGuard backend
Quick start:
1. `node skills/nordvpn-client/scripts/nordvpn-client.js install`
2. put your token in `~/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt` or set `NORDVPN_TOKEN` / `NORDVPN_TOKEN_FILE`
3. `node skills/nordvpn-client/scripts/nordvpn-client.js login`
4. `node skills/nordvpn-client/scripts/nordvpn-client.js connect --country "Italy"` or `--city "Milan"`
5. `node skills/nordvpn-client/scripts/nordvpn-client.js verify`
### Linux
- install path follows NordVPN's official installer script
- primary control path is the official `nordvpn` CLI
- token login is supported through `nordvpn login --token <token>`
## Credentials
Supported env vars:
Supported inputs:
- `NORDVPN_TOKEN`
- `NORDVPN_TOKEN_FILE`
@@ -68,34 +44,328 @@ Supported env vars:
- `NORDVPN_PASSWORD`
- `NORDVPN_PASSWORD_FILE`
Do not put secrets in the skill docs or repo.
Default OpenClaw credential paths:
- token: `~/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt`
- password: `~/.openclaw/workspace/.clawdbot/credentials/nordvpn/password.txt`
## Verification model
Recommended setup on macOS is a token file with strict permissions:
`status`, `verify`, and `connect` emit JSON suitable for agent use:
```bash
mkdir -p ~/.openclaw/workspace/.clawdbot/credentials/nordvpn
chmod 700 ~/.openclaw/workspace/.clawdbot/credentials/nordvpn
printf '%s\n' '<your-nordvpn-token>' > ~/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt
chmod 600 ~/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt
```
- platform
- install state
- control mode (`cli`, `wireguard`, `app-manual`)
- auth state
- connection state
- requested target
- public IP / geolocation lookup
Do not commit secrets into the repo or the skill docs.
After `connect`, the intended workflow is:
## Platform Backends
1. `nordvpn-client connect ...`
2. `nordvpn-client verify ...` if an explicit location check is needed
3. run the follow-up task such as `web-automation`
### macOS
## Limitations
Current macOS backend:
- Linux behavior still depends on the official `nordvpn` CLI.
- macOS automated connects require token-based WireGuard setup; GUI-app login alone is insufficient.
- macOS automated connects intentionally suspend Tailscale for the duration of the NordVPN session.
- The Homebrew `nordvpn` app does not need to be uninstalled.
- NordLynx/WireGuard
- `wireguard-go`
- `wireguard-tools`
- NordVPN DNS in the generated WireGuard config:
- `103.86.96.100`
- `103.86.99.100`
Important behavior:
- `NordVPN.app` may remain installed, but the automated backend does not reuse app login state.
- The skill automatically suspends Tailscale before connect if Tailscale is active.
- The skill resumes Tailscale after disconnect, or after a failed connect, if it stopped it.
- The Homebrew NordVPN app does not need to be uninstalled.
### Linux
Current Linux backend:
- official `nordvpn` CLI
- official NordVPN installer
- token login through `nordvpn login --token ...`
## Install / Bootstrap
### macOS
Bootstrap the automation backend:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js install
```
Equivalent Homebrew command:
```bash
brew install wireguard-go wireguard-tools
```
What `install` does on macOS:
- checks whether `wireguard-go` is present
- checks whether `wg` and `wg-quick` are present
- installs missing packages through Homebrew
### Linux
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js install
```
What `install` does on Linux:
- downloads NordVPNs official installer script
- runs it
- leaves subsequent login/connect to the official `nordvpn` CLI
## macOS sudoers Setup
Automated macOS connect/disconnect requires passwordless `sudo` for the helper script that invokes `wg-quick`.
Installed OpenClaw helper path:
```text
/Users/stefano/.openclaw/workspace/skills/nordvpn-client/scripts/nordvpn-wireguard-helper.sh
```
Edit sudoers safely:
```bash
sudo visudo
```
Add this exact rule:
```sudoers
stefano ALL=(root) NOPASSWD: /Users/stefano/.openclaw/workspace/skills/nordvpn-client/scripts/nordvpn-wireguard-helper.sh probe, /Users/stefano/.openclaw/workspace/skills/nordvpn-client/scripts/nordvpn-wireguard-helper.sh up, /Users/stefano/.openclaw/workspace/skills/nordvpn-client/scripts/nordvpn-wireguard-helper.sh down
```
If you run the repo copy directly instead of the installed OpenClaw skill, adjust the helper path accordingly.
## Common Flows
### Status
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js status
```
Use this first to answer:
- is the correct backend available?
- is the token visible?
- is `sudoReady` true?
- is the machine currently connected?
### Login
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js login
```
On macOS this validates the token and populates the local auth cache. It does not connect the VPN.
### Connect
Country:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js connect --country "Germany"
```
City:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js connect --country "Japan" --city "Tokyo"
```
Expected macOS behavior:
- stop Tailscale if active
- select a NordVPN server for the target
- bring up the WireGuard tunnel
- verify the public exit location
- return JSON describing the chosen server and final verified location
### Verify
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js verify --country "Germany"
```
Use this after connect if you want an explicit location check without changing VPN state.
### Disconnect
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js disconnect
```
Expected macOS behavior:
- attempt `wg-quick down` whenever there is active or residual NordVPN WireGuard state
- remove stale local NordVPN state files after teardown
- resume Tailscale if the skill had suspended it
## Output Model
Normal JSON is redacted by default.
Redacted fields in normal mode:
- `cliPath`
- `appPath`
- `wireguard.configPath`
- `wireguard.helperPath`
- `wireguard.authCache.tokenSource`
Operational fields preserved in normal mode:
- `connected`
- `wireguard.active`
- `wireguard.endpoint`
- `requestedTarget`
- `verification`
- public IP and location
For deeper troubleshooting, use:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js status --debug
```
`--debug` keeps the internal local paths and other low-level metadata in the JSON output.
## Troubleshooting
### `Invalid authorization header`
Meaning:
- the token file was found
- the token value is not valid for NordVPNs API
Actions:
1. generate a fresh NordVPN access token
2. replace the contents of `~/.openclaw/workspace/.clawdbot/credentials/nordvpn/token.txt`
3. run:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js login
```
### `sudoReady: false`
Meaning:
- the helper script is present
- the agent cannot run `wg-quick` non-interactively
Actions:
1. add the `visudo` rule shown above
2. rerun:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js status
```
Expected:
- `wireguard.sudoReady: true`
### WireGuard tools missing
Meaning:
- macOS backend is selected
- `wireguard-go`, `wg`, or `wg-quick` is missing
Actions:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js install
```
or:
```bash
brew install wireguard-go wireguard-tools
```
### Tailscale interaction
Expected behavior on macOS:
- Tailscale is suspended before the NordVPN connect
- Tailscale is resumed after disconnect or failed connect
If a connect succeeds but later traffic is wrong, check:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js status
/opt/homebrew/bin/tailscale status --json
```
Look for:
- `connected: true` and a foreign exit IP while NordVPN is up
- `connected: false` and Texas/Garland IP after disconnect
### Status says disconnected after a verified connect
This was a previous macOS false-negative path and is now normalized in the connect response.
Current expectation:
- if `connect` verifies the target location successfully
- the returned `state` snapshot should also show:
- `connected: true`
- `wireguard.active: true`
If that regresses, capture:
- `connect` JSON
- `verify` JSON
- `status --debug` JSON
### Disconnect says “no active connection” but traffic is still foreign
The current macOS disconnect path now treats residual WireGuard state as sufficient reason to attempt teardown.
Safe operator check:
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js disconnect
node skills/nordvpn-client/scripts/nordvpn-client.js verify
```
Expected after a good disconnect:
- Texas/Garland public IP again
- `wireguard.configPath: null` in normal status output
- `wireguard.lastConnection: null`
If that regresses, capture:
- `disconnect` JSON
- `verify` JSON
- `status --debug` JSON
## Recommended Agent Workflow
For VPN-routed work:
1. `status`
2. `install` if backend tooling is missing
3. `login` if token validation has not happened yet
4. `connect --country ...` or `connect --country ... --city ...`
5. `verify`
6. run the follow-up skill such as `web-automation`
7. `disconnect`
8. `verify` again if you need proof the machine returned to the normal exit path