lightscale-client/README.md
2026-02-13 17:08:17 +09:00

287 lines
6.4 KiB
Markdown

# lightscale-client
Minimal control-plane client for Lightscale. It registers nodes, sends heartbeats, fetches
netmaps, and can manage the WireGuard data plane (kernel or userspace) with basic NAT traversal.
This client already uses profile-scoped state files so multiple networks can be supported later by
running separate profiles.
## Configure a profile
```sh
cargo run -- --profile default init http://127.0.0.1:8080
```
Multiple control URLs (failover):
```sh
cargo run -- --profile default init http://10.0.0.1:8080,http://10.0.0.1:8081
```
## Register a node
```sh
cargo run -- --profile default register <token> --node-name laptop
```
Register a node with an auth URL flow:
```sh
cargo run -- --profile default register-url <network_id> --node-name laptop
```
The command prints a one-time approval URL. Open it in a browser (or curl it) to approve the node.
## Admin actions
Set an admin token when the control plane is protected (CLI flag or env var):
```sh
export LIGHTSCALE_ADMIN_TOKEN=<token>
```
List nodes in a network (use `--pending` to show only unapproved nodes):
```sh
cargo run -- --profile default admin nodes <network_id> --pending
```
Update a node's name or tags (admin):
```sh
cargo run -- --profile default admin node update <node_id> --name laptop --tags dev,lab
```
Clear tags:
```sh
cargo run -- --profile default admin node update <node_id> --clear-tags
```
Approve a node by ID:
```sh
cargo run -- --profile default admin approve <node_id>
```
Create an enrollment token:
```sh
cargo run -- --profile default admin token create <network_id> --ttl-seconds 3600 --uses 1 --tags lab
```
Revoke an enrollment token:
```sh
cargo run -- --profile default admin token revoke <token>
```
## Heartbeat
```sh
cargo run -- --profile default heartbeat \
--endpoint 203.0.113.1:51820 \
--route 192.168.10.0/24
```
Optionally include your WireGuard listen port so the server can add the observed
public endpoint from the heartbeat connection:
```sh
cargo run -- --profile default heartbeat --listen-port 51820
```
Use STUN to discover a public endpoint (best effort):
```sh
cargo run -- --profile default heartbeat --stun --stun-server stun.l.google.com:19302
```
Advertise exit node routes:
```sh
cargo run -- --profile default heartbeat --exit-node
```
## Fetch netmap
```sh
cargo run -- --profile default netmap
```
## Show status
```sh
cargo run -- --profile default status
```
Include WireGuard peer info (handshake age + endpoint):
```sh
cargo run -- --profile default status --wg
```
## Configure WireGuard (Linux)
Bring up an interface using the latest netmap:
```sh
sudo cargo run -- --profile default wg-up --listen-port 51820
```
Use boringtun (userspace WireGuard) instead of the kernel module:
```sh
sudo cargo run -- --profile default wg-up --listen-port 51820 --backend boringtun
```
This runs the userspace tunnel inside the client process. Keep the command
running (or use `agent`) to keep the tunnel alive.
Apply advertised subnet/exit routes at the same time:
```sh
sudo cargo run -- --profile default wg-up --listen-port 51820 --apply-routes --accept-exit-node
```
Optionally probe peers to trigger NAT traversal (UDP probe, no ICMP):
```sh
sudo cargo run -- --profile default wg-up --listen-port 51820 --probe-peers
```
Conflicting routes are skipped by default; use `--allow-route-conflicts` to force them.
Select a specific exit node by ID or name:
```sh
sudo cargo run -- --profile default wg-up --listen-port 51820 --apply-routes --accept-exit-node \
--exit-node-id <peer_id>
```
Remove the interface:
```sh
sudo cargo run -- --profile default wg-down
```
If you used the boringtun backend, stop the process that created the tunnel
(for example `Ctrl+C` in the foreground or stopping the agent). The command
below attempts to remove the interface if needed.
```sh
sudo cargo run -- --profile default wg-down --backend boringtun
```
## Run the agent loop
Keep WireGuard and routes updated using long-polling + periodic heartbeats:
```sh
sudo cargo run -- --profile default agent --listen-port 51820 --apply-routes --accept-exit-node \
--heartbeat-interval 30 --longpoll-timeout 30
```
Tune endpoint rotation (stale seconds + max rotations before relay fallback):
```sh
sudo cargo run -- --profile default agent --listen-port 51820 \
--endpoint-stale-after 15 --endpoint-max-rotations 2
```
Use boringtun backend in the agent:
```sh
sudo cargo run -- --profile default agent --listen-port 51820 --backend boringtun
```
Enable STUN discovery in the agent:
```sh
sudo cargo run -- --profile default agent --listen-port 51820 --stun \
--stun-server stun.l.google.com:19302
```
Enable stream relay signaling (peer probe via relay):
```sh
sudo cargo run -- --profile default agent --listen-port 51820 --stream-relay
```
With `--stream-relay`, the agent also maintains local relay tunnels that can be
used as a fallback when direct endpoints stop handshaking.
Probe peers when netmap updates arrive (UDP probe to endpoints, no ICMP):
```sh
sudo cargo run -- --profile default agent --listen-port 51820 --probe-peers
```
## Enable subnet/exit routing (Linux)
Configure IP forwarding and (optionally) SNAT for a subnet router or exit node.
This uses nftables via `libmnl`/`libnftnl` (the Nix dev shell installs them):
```sh
sudo cargo run -- --profile default router enable --interface ls-default --out-interface eth0
```
Disable SNAT to require return routes on the LAN:
```sh
sudo cargo run -- --profile default router enable --interface ls-default --out-interface eth0 --no-snat
```
Remove forwarding/NAT rules:
```sh
sudo cargo run -- --profile default router disable --interface ls-default --out-interface eth0
```
## DNS and relay info
Export host-style DNS entries:
```sh
cargo run -- --profile default dns
```
Export DNS info as JSON (debug output):
```sh
cargo run -- --profile default dns --format json --output /tmp/lightscale-dns.json
```
Show relay configuration (STUN/TURN/stream relay/UDP relay):
```sh
cargo run -- --profile default relay
```
## UDP relay (best effort)
Send a test message via the UDP relay:
```sh
cargo run -- --profile default relay-udp send <peer-id> "hello"
```
Listen for relay messages:
```sh
cargo run -- --profile default relay-udp listen
```
## Stream relay (best effort)
Send a test message via the stream relay:
```sh
cargo run -- --profile default relay-stream send <peer-id> "hello"
```
Listen for relay messages:
```sh
cargo run -- --profile default relay-stream listen
```