Hub stage 5: manage each server from one console
Zones, Cache, Blocking, DNS Client, Settings, DHCP and Logs can now be changed on one chosen server through the hub, with that server's admin token. Operators manage cache and blocking; admins also zones, settings and DHCP. Under "All servers", or on a server without an admin token, the controls are disabled with a hint. The hub refuses settings/set changes to a server's web service fields and anything about users, SSO or LDAP; backup, restore, log and stats deletion and admin/* stay refused. Non-admins get settings with secrets blanked. Write params travel in the POST body, downloads pass through with a single-use token, and the audit log names no values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
57e492cceb
commit
8bb1e01936
45 files changed
+1851
-190
No files matched your search
+31
-4
@@ -8,11 +8,11 @@ read-only, Technitium-compatible `/api/*`:
|
||||
- No `node` (or `node=cluster`) asks every server in parallel and merges the answers
|
||||
(statistics are summed, top lists and query logs are merged). If a server does not
|
||||
answer, the others are shown and the response carries `hubWarnings`.
|
||||
- Reads go with each server's read token. The only writes are the app changes below, which use a separate admin token and a role with `apps.write`. Anything else that would change data is refused with `403` (and written to the audit log). The hub has its own accounts with roles, a login rate limit and an audit log.
|
||||
- Reads go with each server's read token. Writes use a separate admin token: the app changes below (role with `apps.write`) and the per-server changes of "Managing one server" (roles with `operate` or `admin`). Anything else that would change data is refused with `403` (and written to the audit log). The hub has its own accounts with roles, a login rate limit and an audit log.
|
||||
|
||||
The servers themselves are not changed: each only needs a read-only API token. Create it
|
||||
for a user whose group has View, and nothing else, on Dashboard, Logs, Apps (the logging
|
||||
apps Query Logs reads from) and Settings (the blocking state).
|
||||
The servers themselves are not changed: each needs a read-only API token (View, and nothing else, on Dashboard, Logs,
|
||||
Apps, Settings, Zones, Cache, Allowed, Blocked, DnsClient and DhcpServer) and, for writes, an admin token whose group has
|
||||
Modify and Delete only where the table in `docs/hub-deploy.md` grants them.
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -86,6 +86,33 @@ Public: `status`, `user/login`. After signing in: `user/session/get`, `user/logo
|
||||
|
||||
Everything else answers `403 The hub is read-only.` and is audited.
|
||||
|
||||
## Managing one server
|
||||
|
||||
The sections Zones, Cache, Blocking (Blocked and Allowed), DNS Client, Settings and DHCP are managed on ONE server at a
|
||||
time. `routes.ts` lists exactly the paths the console calls; an `operate` role (`operator`, `admin`) may change the cache,
|
||||
Blocked and Allowed, the temporary blocking switch and the list update; zones (records, DNSSEC, import), settings and DHCP
|
||||
need `admin`. `viewer` and `apps-admin` only read.
|
||||
|
||||
- A write needs `node=<id>` of a server with an admin token. No node, `cluster` or an unknown id answers `400`
|
||||
("Choose a server: this change is made on one server at a time."); a server without an admin token answers `403`.
|
||||
- The parameters travel to the server in a form body (only `token` stays in the query). A zone import goes on as
|
||||
`multipart/form-data` or `text/plain` (up to 20 MB); `settings/set`, record and scope writes take up to 2 MB and the
|
||||
Blocked/Allowed imports up to 5 MB, for a signed-in caller only.
|
||||
- `dnsClient/resolve` is a read, unless `import` is set: then it writes into a zone and needs `admin`.
|
||||
- `settings/set` is refused when it changes a `webService*` field (compared with the server's current `settings/get`; the
|
||||
console sends the block unchanged with every save) or carries a user, SSO or LDAP field. `settings/get` blanks the TSIG
|
||||
shared secrets and the passwords for every role but `admin`.
|
||||
- Reads that have no merger (`zones/list`, `cache/list`, `allowed|blocked/list`, `dhcp/*`, `logs/list`, `dnsClient/resolve`,
|
||||
the exports) are refused without a node instead of being answered by the first server. `settings/get` is the exception:
|
||||
the header's blocking mark reads it without a node.
|
||||
- Downloads (`zones/export`, `logs/download`, `logs/export`, `allowed|blocked/export`) are passed through (type, file name,
|
||||
body) with the read token. A new tab has no Authorization header, so `user/createSingleUseToken` gives a token that works
|
||||
once, for 60 seconds, for these paths only.
|
||||
- Refused, even for `admin`: `admin/*`, `user/*` (except the hub's own sign-in), `logs/delete`, `logs/deleteAll`,
|
||||
`dashboard/stats/deleteAll`, `settings/backup`, `settings/restore` and `zones/permissions/*`.
|
||||
- The audit line holds the user, role, address, path (dots for slashes), server, one identifier (zone, domain, name or scope)
|
||||
and the outcome. Never a value.
|
||||
|
||||
## App writes
|
||||
|
||||
Needs the `apps.write` role (`apps-admin`, `admin`); others get `403 Your role does not allow this.` and a `denied-write` audit line.
|
||||
|
||||
Reference in new issue
Block a user