Commit Graph
7 Commits
Author SHA1 Message Date
maeneko 53d5a08bbd Add shaping, Prometheus, monitor tab and peer audit
Baseline TypeScript version before the Go rewrite: CAKE fair sharing with
automatic deprioritisation of heavy devices, per-key priority, /metrics with
a metrics token, the built-in Prometheus install/remove, the Monitor tab,
grouped sidebar tabs and the dead-peer audit.
2026-10-14 13:27:23 +00:00
maeneko a85f5d87b2 Manage master keys through the external API
API keys now see a set of servers instead of one, and /api/v1 gains the
master-key operations the panel already had.

- api_key_servers holds each key's servers (migrated from server_id,
  which stays the default server for /api/v1/users). /users follows
  X-Server-Id within the set; a server outside it is 404. PATCH
  /ui/apikeys/:id changes the set without reissuing the key.
- /api/v1/masterkeys: create (returns the sen:// link), list, get with
  link and devices, patch label/limit/servers, rotate, rekey, delete, and
  nested device routes (unlink, rekey, PSK). A key sees a master key only
  if all of its servers are in the key's set, so it cannot delete or
  re-point service on a server it cannot see; anything else is 404,
  servers outside the set are 403. Creating refuses with 503 before
  writing anything if the subscription cannot issue links.
- sub.ts: the panel routes and the API share one service layer, the
  panel's behaviour is unchanged.
- Node deletion: owners check in beforeDelete (no writes, a later hook
  may still veto) and clean up in afterDelete. Previously a forced delete
  could release a waiting master key and then be vetoed. A node that is
  the only server of an API key is refused; other keys just lose it.
- Panel: server checkboxes are a shared ServerPicker, used by the master
  key settings and the new API key settings row; the API keys table shows
  each key's servers.
- README: the API section covers server sets and master keys.
2026-09-27 15:59:16 +03:00
maeneko 789538756a Manage several servers from one panel: core + nodes
A node is a VPN server without a panel. awg-agent on it dials the panel
(core) over an outbound WSS connection and runs the panel's requests on its
own awg-ctrl, which stays on 127.0.0.1 and is unchanged. No inbound port on
the node, works behind NAT.

- awg-ui/nodes.ts: node registry in ui.db, WSS hub on NODE_PORT with a
  self-signed cert whose SPKI pin goes into the join string, RPC with
  timeouts, health polling, /ui/nodes routes.
- Nodes enroll with a one-time awgjoin:// string (secret stored hashed,
  1 hour) and then authenticate by their own Ed25519 key. The agent checks
  the pin before sending anything and only forwards /health, /api/*, /awg/*.
- server_id 0 is the panel's own awg-ctrl; LOCAL_NODE=off makes the panel
  run without a VPN of its own. The panel picks a server with X-Server-Id,
  API keys use their server_id. sen:// still serves one server.
- UI: a card per server in the server bar, switching remounts the tab,
  «Добавить сервер» gives the join command.
- CLI: agent service, roles from cli.env, join / unjoin commands.
- Release archives include awg-agent.
2026-09-26 19:48:33 +03:00
maeneko a11cfc88de Bring back the external API keys
Commit 0dbb13f removed the whole feature: the apikeys tab, the /ui/apikeys
routes, requireApiKey, the /api/v1 router, the ApiKey type, the better-sqlite3
dependency and UI_DB_FILE in the CLI and the installer. Only the untracked
awg-ui/API.md survived, so the README went on to claim there was no key-based
API at all.

Restores all of it: ui.db with the api_keys table, awgk_ key generation storing
only the SHA-256 and a display prefix, the JWT-guarded CRUD, and the /api/v1
router mounted before the JWT proxy on /api so the key auth is not swallowed.
The tab comes back as its own folder and the registry picks it up on its own.
UI_DB_FILE points at /etc/amnezia/amneziawg/ui.db, outside the install tree, so
reinstalling keeps the keys; a fresh install moves the old one aside with its
WAL sidecars.

better-sqlite3 takes the slot of jsonwebtoken, which arrived with the MA7
integration and has been unused since 068cab4 removed it.

One defect is not reproduced: the /api/v1 handlers called ctrl() without a
try/catch, and Express 4 does not catch async rejections, so a single request
with awg-ctrl down killed the panel process. They now answer 502 like proxy()
already did.

The API contract is documented in the README rather than linked: .gitignore
excludes every markdown but README.md, so awg-ui/API.md is not in the repo and
the link would break on a clone.

Checked against a running server: login, key create/list/delete, 400 on a bad
label, 401 without a JWT, "API key required" rather than "Unauthorized" on
/api/v1, "Invalid API key" for a deleted key, last_used updating, and all three
/api/v1 routes returning 502 with the process still alive.
2026-09-10 00:24:18 +03:00
maeneko 0dbb13f120 com 2026-08-27 01:39:06 +03:00
maeneko 44c637f7af Add AmneziaWG 3.1 support with key reissue
Protocol generation is now derived from awg1.conf rather than stored: an
interface speaks 3.1 when HeaderProtectionKey is set and 2.0 otherwise. The
3.0/3.1-only keys (HeaderProtectionKey, ContentPaddingAddition, the
Rekey/Reject/Keepalive timers, MaxHandshakeAttempts, RandomTrailers,
DisableCookies) are read from the conf and emitted only when non-empty, so 2.0
output stays byte-identical — verified by diffing both the client .conf and the
full vpn:// string against the previous implementation.

Changing generation invalidates every issued vpn:// key, so add
POST /api/users/reissue. It recovers the client private key from inside the
stored blob (the only place it exists), keeping ip/pub_key/psk_key intact, so
nothing changes on the wire and users only need to re-import. users gains
key_gen and vpn_key_prev, and users.db is snapshotted before the pass.

install.sh gates 3.1 on module 3.x and kernel >= 5.5 (header protection needs
the chacha library API, absent before 5.5) and falls back to writing a 2.0 conf
instead of aborting, so older kernels keep working as before.
HeaderProtectionKey is generated with awg genpsk and preserved on KEEP_DATA.

The panel marks keys issued on a different generation and offers to reissue
them; /api/v1 now returns gen alongside name/ip/vpn_key.

Also add MIT license headers across the awg-ui sources.
2026-08-17 17:58:00 +03:00
maeneko 54ffcf9bc0 Initial commit 2026-07-10 00:19:05 +03:00