swarm options: no swarm.* value depends on a deploy option or this host's hive
- swarm.serviceDomains lists every swarm service name on every host. The
store's issuing role is built from it, so the store now admits a leaf
for grafana, metrics, otel, logs, the bao UI and the apex whichever host
runs the store. Each gateway's own leaf stays narrowed by
localServiceDomains.
- swarm.matrix.apiUrl defaults to http://<swarm.matrix.gatewayHost>
(null when gatewayHost is null) instead of loopback on the matrix host.
- The authelia vhost proxies /bridge/ to swarm-authelia-bridge with the
prefix stripped, and deploy.swarm-controller.authBridgeUrl defaults to
${swarm.authelia.url}/bridge on every host. swarm.authelia.bridgeUrl is
removed.
- swarm-authelia-bridge admits only swarm-controller's OIDC client on
every request (403 for any other active token), configured by
SWARM_AUTHELIA_BRIDGE_CONTROLLER_CLIENT_ID (renamed from
..._OPERATOR_READER_CLIENT_ID, which gated ListOperators alone).
- swarm.peerHives is removed; swarm-wireguard.nix filters this host's own
hive out of swarm.hives itself.
Closes #4933
This commit is contained in:
parent
207b089498
commit
bed4358e19
21 changed files with 226 additions and 283 deletions
|
|
@ -82,10 +82,10 @@ pin the value before the homeserver mints any ids under the default.
|
|||
|
||||
## Default-closed firewall
|
||||
|
||||
`deploy.matrix.openFirewall` defaults to `false`: the host
|
||||
reaches the homeserver on loopback, and agent containers reach it
|
||||
at `chat.<swarm-domain>` via the gateway — so the firewall hole only
|
||||
matters for access from *outside* the host. Flip to `true` when
|
||||
`deploy.matrix.openFirewall` defaults to `false`: hive-c0re and agent
|
||||
containers on every hive reach the homeserver at `chat.<swarm-domain>`
|
||||
via the gateway, so the firewall hole only matters for direct access to
|
||||
`httpPort` from *outside* the host. Flip to `true` when
|
||||
announcing the homeserver to other hives or when an external matrix
|
||||
client needs to reach the client-server API directly.
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ You rarely switch it on yourself. `gateway.enable` defaults to off, and every mo
|
|||
| --- | --- | --- |
|
||||
| `<swarm>/` | swarm-ui dist (static), behind an authelia subrequest | `swarm-ui.nix`, `deploy.swarm-ui.enable` |
|
||||
| `auth.<swarm>/` | authelia (`9091`) | `swarm-authelia.nix`, `deploy.authelia.enable` |
|
||||
| `auth.<swarm>/bridge/*` | swarm-authelia-bridge (`9092`), prefix stripped; answers swarm-controller's client only | `swarm-authelia.nix`, `deploy.authelia.enable` |
|
||||
| `forge.<swarm>/` | forgejo (`3000`) | `hive-forge/`, `deploy.forgejo.enable` |
|
||||
| `chat.<swarm>/_matrix/*` | tuwunel (`8008`) | `hive-matrix.nix`, `swarm.matrix.gatewayHost != null` |
|
||||
| `chat.<swarm>/` | fluffychat-web static | `hive-matrix.nix`, `swarm.matrix.gatewayHost != null` |
|
||||
|
|
|
|||
|
|
@ -472,9 +472,9 @@ services.hyperhive = {
|
|||
host's routing table).
|
||||
- It opens UDP port 51820 (or `listenPort`) on the host firewall.
|
||||
- `swarm-wireguard.nix` reads each entry's `wireguardAddress` directly
|
||||
from `services.hyperhive.swarm.peerHives` to build `wg-hive`'s
|
||||
`allowedIPs`, so intra-swarm traffic can route over the mesh address
|
||||
rather than the public domain.
|
||||
from `services.hyperhive.swarm.hives`, minus this host's own hive, to
|
||||
build `wg-hive`'s `allowedIPs`, so intra-swarm traffic can route over
|
||||
the mesh address rather than the public domain.
|
||||
- It sets `persistentKeepalive = 25` by default; override or null to
|
||||
disable (not needed when both sides have public IPs and no NAT).
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ copies from. Every hive does this with its own identity, so holding the
|
|||
swarm root's private key stopped being what decides whether a hive can
|
||||
serve its swarm's names.
|
||||
|
||||
`services.hyperhive.swarm.serviceDomains` populates the role's
|
||||
`services.hyperhive.swarm.serviceDomains`, every swarm service name and the
|
||||
same list on every host, populates the role's
|
||||
`allowed_domains`, so asking for a name nobody configured is a refusal
|
||||
from the store naming that name — not a certificate quietly issued for
|
||||
it. A host's own SANs are narrower still: it asks only for the names it
|
||||
|
|
|
|||
|
|
@ -106,6 +106,14 @@ there is one IdP and one auth path.
|
|||
Agent subjects come from swarm-controller's agent-creation job, written
|
||||
into the users database by `swarm-authelia-bridge`; human ones come from
|
||||
`swarmctl user add` → [setup.md § 2](../getting-started/setup.md#2--your-sso-account).
|
||||
|
||||
The bridge listens on loopback on the authelia host, and the gateway
|
||||
publishes it as
|
||||
`https://<swarm.authelia.domain>/bridge/`, which is where
|
||||
`deploy.swarm-controller.authBridgeUrl` points by default on every host.
|
||||
It answers only swarm-controller's OIDC client
|
||||
(`swarm.controller.queueClientId`) and refuses every other token `403`.
|
||||
|
||||
On first boot this module seeds the users database with a disabled placeholder subject, so authelia has a non-empty store to start against before any real account exists (`swarm-authelia.nix:873`). Authelia generates session and storage keys in the container on
|
||||
first boot and never rotates them automatically; replacing one
|
||||
invalidates data already written (sessions, the encrypted store), so
|
||||
|
|
|
|||
|
|
@ -249,9 +249,10 @@ HTML instead of the failure that actually happened:
|
|||
- `/api/oidc/token`, `/.well-known/openid-configuration` — a client
|
||||
parsing an error page as its JSON document
|
||||
|
||||
The gateway routes authelia's `/api/` and `/.well-known/` prefixes
|
||||
**without** error interception. The split is by _audience_, not by an enumerated path
|
||||
list: a human gets the page, every machine caller gets the status.
|
||||
The gateway routes authelia's `/api/` and `/.well-known/` prefixes, and
|
||||
the bridge's `/bridge/`, **without** error interception. The split is by
|
||||
_audience_, not by an enumerated path list: a human gets the page, every
|
||||
machine caller gets the status.
|
||||
Enumerating endpoints individually would leave the next one added
|
||||
silently intercepted.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue