move the squid host options to deploy.hive-controller.squid
This commit is contained in:
parent
c9b5705ad8
commit
da16487800
16 changed files with 168 additions and 57 deletions
|
|
@ -225,7 +225,7 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
|
||||||
credential (HTTP Basic, the agent's name and its secret). `swarm-controller`
|
credential (HTTP Basic, the agent's name and its secret). `swarm-controller`
|
||||||
mints one per agent at `swarm/agents/<agent>/proxy-credential`, and never
|
mints one per agent at `swarm/agents/<agent>/proxy-credential`, and never
|
||||||
replaces it. `hive-c0re` hashes the credentials of this hive's agents, and
|
replaces it. `hive-c0re` hashes the credentials of this hive's agents, and
|
||||||
one more for the self-check, into `services.hyperhive.squid.usersFile`
|
one more for the self-check, into `services.hyperhive.deploy.hive-controller.squid.usersFile`
|
||||||
every 30 seconds. Squid's `basic_ncsa_auth` helper re-reads the file when it
|
every 30 seconds. Squid's `basic_ncsa_auth` helper re-reads the file when it
|
||||||
changes. A stopped agent stays in the file. Squid caches a good login for a
|
changes. A stopped agent stays in the file. Squid caches a good login for a
|
||||||
minute. Nothing rotates a credential: to replace one, delete its leaf in the
|
minute. Nothing rotates a credential: to replace one, delete its leaf in the
|
||||||
|
|
@ -238,7 +238,7 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
|
||||||
- **Agents and the proxy.** An agent uses the proxy only when its hive says
|
- **Agents and the proxy.** An agent uses the proxy only when its hive says
|
||||||
this host's squid is ready for it. `hive-c0re` puts two facts in every
|
this host's squid is ready for it. `hive-c0re` puts two facts in every
|
||||||
container's `/etc/hyperhive-hive-facts`, only on a hive that holds a store
|
container's `/etc/hyperhive-hive-facts`, only on a hive that holds a store
|
||||||
identity: `HIVE_SQUID_PROXY` (`services.hyperhive.squid.listen`, the bridge IP
|
identity: `HIVE_SQUID_PROXY` (`services.hyperhive.deploy.hive-controller.squid.listen`, the bridge IP
|
||||||
and port) and `HIVE_EGRESS_NO_PROXY` (the direct hosts below). A hive that
|
and port) and `HIVE_EGRESS_NO_PROXY` (the direct hosts below). A hive that
|
||||||
predates them writes neither, and its agents go direct.
|
predates them writes neither, and its agents go direct.
|
||||||
`hive-agent-proxy-credential.service` (`nix/agent-modules/egress-proxy.nix`)
|
`hive-agent-proxy-credential.service` (`nix/agent-modules/egress-proxy.nix`)
|
||||||
|
|
@ -272,7 +272,7 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
|
||||||
has no CIDR support, so the list holds the bridge as an address.
|
has no CIDR support, so the list holds the bridge as an address.
|
||||||
|
|
||||||
- **Two lists.** The credential decides the policy. `hive-c0re` writes a
|
- **Two lists.** The credential decides the policy. `hive-c0re` writes a
|
||||||
second file beside the users file, `services.hyperhive.squid.unrestrictedFile`
|
second file beside the users file, `services.hyperhive.deploy.hive-controller.squid.unrestrictedFile`
|
||||||
(`/var/lib/hive-squid/unrestricted`, `hive-core:squid`, `0640`): the names of
|
(`/var/lib/hive-squid/unrestricted`, `hive-core:squid`, `0640`): the names of
|
||||||
the users whose agent holds the `unrestricted_internet` flag in the
|
the users whose agent holds the `unrestricted_internet` flag in the
|
||||||
permissions the hive last read from the swarm, one per line, rewritten when
|
permissions the hive last read from the swarm, one per line, rewritten when
|
||||||
|
|
@ -289,7 +289,7 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
|
||||||
restricted. Agents must not start sending credentials until every hive runs
|
restricted. Agents must not start sending credentials until every hive runs
|
||||||
the `hive-c0re` that writes it, or a legacy agent loses general internet.
|
the `hive-c0re` that writes it, or a legacy agent loses general internet.
|
||||||
|
|
||||||
- **Base list.** `services.hyperhive.squid.baseAllowedDomains` is open to every
|
- **Base list.** `services.hyperhive.deploy.hive-controller.squid.baseAllowedDomains` is open to every
|
||||||
authenticated user, whatever its flag: what the agent harness needs off the
|
authenticated user, whatever its flag: what the agent harness needs off the
|
||||||
swarm. The default is the hosts Claude Code requires
|
swarm. The default is the hosts Claude Code requires
|
||||||
(<https://code.claude.com/docs/en/network-config>): `api.anthropic.com` for
|
(<https://code.claude.com/docs/en/network-config>): `api.anthropic.com` for
|
||||||
|
|
@ -300,8 +300,8 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
|
||||||
agent's own swarm entries (see _Swarm allow-list_ below). The list omits the plugin marketplace clone from `github.com`, since a failed add
|
agent's own swarm entries (see _Swarm allow-list_ below). The list omits the plugin marketplace clone from `github.com`, since a failed add
|
||||||
isn't fatal. The rules below still refuse an entry that resolves to a
|
isn't fatal. The rules below still refuse an entry that resolves to a
|
||||||
private address.
|
private address.
|
||||||
- **Allow-list.** `services.hyperhive.squid.allowedDomains` defaults to empty,
|
- **Allow-list.** `services.hyperhive.deploy.hive-controller.squid.allowedDomains` defaults to empty,
|
||||||
plus the self-check canary (`services.hyperhive.squid.selfcheck.canary`), so
|
plus the self-check canary (`services.hyperhive.deploy.hive-controller.squid.selfcheck.canary`), so
|
||||||
the canary widens the restricted list by that one name. The swarm's own
|
the canary widens the restricted list by that one name. The swarm's own
|
||||||
service names aren't on it: they resolve to the bridge or a private address,
|
service names aren't on it: they resolve to the bridge or a private address,
|
||||||
which the rules below refuse, and agents reach them directly. Each entry
|
which the rules below refuse, and agents reach them directly. Each entry
|
||||||
|
|
@ -313,8 +313,8 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
|
||||||
([allowed domains](../swarm/ui.md#allowed-domains)); the swarm controller
|
([allowed domains](../swarm/ui.md#allowed-domains)); the swarm controller
|
||||||
keeps them in one value of the `egress-allow` bucket, each for every agent
|
keeps them in one value of the `egress-allow` bucket, each for every agent
|
||||||
or for one agent. Every 30 seconds `hive-c0re` reads it and writes two files
|
or for one agent. Every 30 seconds `hive-c0re` reads it and writes two files
|
||||||
beside the users file, `services.hyperhive.squid.allowedFile`
|
beside the users file, `services.hyperhive.deploy.hive-controller.squid.allowedFile`
|
||||||
(`/var/lib/hive-squid/allowed`) and `services.hyperhive.squid.agentAllowFile`
|
(`/var/lib/hive-squid/allowed`) and `services.hyperhive.deploy.hive-controller.squid.agentAllowFile`
|
||||||
(`/var/lib/hive-squid/agent-allow.conf`), `hive-core:squid`, `0640`, and
|
(`/var/lib/hive-squid/agent-allow.conf`), `hive-core:squid`, `0640`, and
|
||||||
logs `squid allow list: 2 swarm, 3 agent entries` when they change. The
|
logs `squid allow list: 2 swarm, 3 agent entries` when they change. The
|
||||||
swarm-wide names join the allow ACL, so a restricted user reaches them. A
|
swarm-wide names join the allow ACL, so a restricted user reaches them. A
|
||||||
|
|
@ -387,12 +387,12 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
|
||||||
client's source address.
|
client's source address.
|
||||||
- **Self-check.** `squid-selfcheck.timer` runs `squid-selfcheck.service`
|
- **Self-check.** `squid-selfcheck.timer` runs `squid-selfcheck.service`
|
||||||
every minute from the bridge IP, logging in as `selfcheck.squid`: `CONNECT`
|
every minute from the bridge IP, logging in as `selfcheck.squid`: `CONNECT`
|
||||||
to `services.hyperhive.squid.selfcheck.canary` (default: `cache.nixos.org`,
|
to `services.hyperhive.deploy.hive-controller.squid.selfcheck.canary` (default: `cache.nixos.org`,
|
||||||
a public name that's also on the allow-list)
|
a public name that's also on the allow-list)
|
||||||
must answer 200, to `deny-canary.invalid` 403, and to the canary without a
|
must answer 200, to `deny-canary.invalid` 403, and to the canary without a
|
||||||
credential 407. It then logs in as `selfcheck-unrestricted.squid`, which has
|
credential 407. It then logs in as `selfcheck-unrestricted.squid`, which has
|
||||||
the same secret and is always on the unrestricted list, and a `CONNECT` to
|
the same secret and is always on the unrestricted list, and a `CONNECT` to
|
||||||
`services.hyperhive.squid.selfcheck.unrestrictedCanary` (default:
|
`services.hyperhive.deploy.hive-controller.squid.selfcheck.unrestrictedCanary` (default:
|
||||||
`example.com`, a name outside the allow-list) must answer 200. It writes one
|
`example.com`, a name outside the allow-list) must answer 200. It writes one
|
||||||
`squid-selfcheck ok=… allow_status=… deny_status=… anon_status=…
|
`squid-selfcheck ok=… allow_status=… deny_status=… anon_status=…
|
||||||
credential=present|absent unrestricted_canary=… unrestricted_status=…` line
|
credential=present|absent unrestricted_canary=… unrestricted_status=…` line
|
||||||
|
|
|
||||||
|
|
@ -149,16 +149,16 @@ pieces fit, and the reasoning behind them, is in [`credentials.md`](credentials.
|
||||||
|
|
||||||
### Hive-level — one of each per hive
|
### Hive-level — one of each per hive
|
||||||
|
|
||||||
| secret | generated by | lives at |
|
| secret | generated by | lives at |
|
||||||
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| hive leaf certs | `hive-tls.nix`, issued by the secret store's `pki` mount | `<deploy.hive-controller.tls.stateDir>/<name>.pem` |
|
| hive leaf certs | `hive-tls.nix`, issued by the secret store's `pki` mount | `<deploy.hive-controller.tls.stateDir>/<name>.pem` |
|
||||||
| the hive's own store identity | `glue-bao-tls.nix` on the store's host; placed by hand on every other host ([`ca.md`](ca.md#the-gateway-leaf-comes-from-the-secret-store)) | `deploy.hive-controller.tls.baoHiveIdentityCertFile` / `baoHiveIdentityKeyFile` |
|
| the hive's own store identity | `glue-bao-tls.nix` on the store's host; placed by hand on every other host ([`ca.md`](ca.md#the-gateway-leaf-comes-from-the-secret-store)) | `deploy.hive-controller.tls.baoHiveIdentityCertFile` / `baoHiveIdentityKeyFile` |
|
||||||
| the cache's public key and pull token, for hive-priv | `swarm-controller` copies them to `swarm/hives/<hive>/attic/{public-key,pull-token}` (see the cache-facts row above) | `hive-priv-cache-facts` (root) reads those two under the hive's own store identity every ten minutes and writes `/run/hyperhive-priv/attic/public-key` and `netrc` (tmpfs, root, each `0600`, directory `0700`); the cache's address comes from `services.hyperhive.swarm.attic.domain` and `cache`, not from the store. A store that holds no facts, or that doesn't answer, leaves the files as they stand, and a hive that never got them has `hive-priv` answer `not available`. |
|
| the cache's public key and pull token, for hive-priv | `swarm-controller` copies them to `swarm/hives/<hive>/attic/{public-key,pull-token}` (see the cache-facts row above) | `hive-priv-cache-facts` (root) reads those two under the hive's own store identity every ten minutes and writes `/run/hyperhive-priv/attic/public-key` and `netrc` (tmpfs, root, each `0600`, directory `0700`); the cache's address comes from `services.hyperhive.swarm.attic.domain` and `cache`, not from the store. A store that holds no facts, or that doesn't answer, leaves the files as they stand, and a hive that never got them has `hive-priv` answer `not available`. |
|
||||||
| the forge's copy of its OIDC secret | `swarm-bao-forge-oidc.service` reads it out of the swarm secret store under the forge publisher's leaf, wherever authelia runs | `/run/hive-forge-oidc/<id>.secret` on the host (tmpfs), bound into the forge container, handed to `forgejo-sso-source` through `LoadCredential` |
|
| the forge's copy of its OIDC secret | `swarm-bao-forge-oidc.service` reads it out of the swarm secret store under the forge publisher's leaf, wherever authelia runs | `/run/hive-forge-oidc/<id>.secret` on the host (tmpfs), bound into the forge container, handed to `forgejo-sso-source` through `LoadCredential` |
|
||||||
| the homeserver's copy of its OIDC secret | `swarm-bao-matrix-oidc.service` reads it out of the swarm secret store under matrix-ctl's leaf, wherever authelia runs | `/run/hive-matrix-oidc/<id>.secret` on the host (tmpfs), bound into the homeserver container, handed to tuwunel through `LoadCredential` |
|
| the homeserver's copy of its OIDC secret | `swarm-bao-matrix-oidc.service` reads it out of the swarm secret store under matrix-ctl's leaf, wherever authelia runs | `/run/hive-matrix-oidc/<id>.secret` on the host (tmpfs), bound into the homeserver container, handed to tuwunel through `LoadCredential` |
|
||||||
| this hive's forge read token | `swarm-controller`, into the secret store at `swarm/hives/<hive>/forge/token`, for the `hive-<hive>` account; a pass at start and every five minutes re-mints a missing or stale token | `hive-c0re` reads it under the hive's own store identity, and copies it (account on the first line, token on the second) to `/run/hyperhive/forge-hive-token` (tmpfs, `0600` `hive-core`) for nix's `git`, which `hive-priv` also runs. Each `internal/meta` read and each boot rewrites the copy when it differs; where they differ after a rotation, a build that starts before the next read fails to authenticate, and a retry reads the new token |
|
| this hive's forge read token | `swarm-controller`, into the secret store at `swarm/hives/<hive>/forge/token`, for the `hive-<hive>` account; a pass at start and every five minutes re-mints a missing or stale token | `hive-c0re` reads it under the hive's own store identity, and copies it (account on the first line, token on the second) to `/run/hyperhive/forge-hive-token` (tmpfs, `0600` `hive-core`) for nix's `git`, which `hive-priv` also runs. Each `internal/meta` read and each boot rewrites the copy when it differs; where they differ after a rotation, a build that starts before the next read fails to authenticate, and a retry reads the new token |
|
||||||
| squid's users file | `hive-c0re` (`workers::squid_users`), every 30 seconds, from the proxy credentials of its agents and the self-check | `services.hyperhive.squid.usersFile` (`/var/lib/hive-squid/users`, `hive-core:squid`, `0640`): `<user>:<hash>` lines, SHA-512 crypt hashes only, renamed into place when it changed. `unrestricted` beside it lists the users whose agent holds the swarm's `unrestricted_internet` flag, names only; it lists every agent the hive never read as off `systemd-tmpfiles` creates it empty so squid's helper never sees a missing file. A hive whose agents have no credential yet (an older controller) has an empty file: every login fails and the self-check reports `ok=false`; an agent without one sends none, so it goes direct |
|
| squid's users file | `hive-c0re` (`workers::squid_users`), every 30 seconds, from the proxy credentials of its agents and the self-check | `services.hyperhive.deploy.hive-controller.squid.usersFile` (`/var/lib/hive-squid/users`, `hive-core:squid`, `0640`): `<user>:<hash>` lines, SHA-512 crypt hashes only, renamed into place when it changed. `unrestricted` beside it lists the users whose agent holds the swarm's `unrestricted_internet` flag, names only; it lists every agent the hive never read as off `systemd-tmpfiles` creates it empty so squid's helper never sees a missing file. A hive whose agents have no credential yet (an older controller) has an empty file: every login fails and the self-check reports `ok=false`; an agent without one sends none, so it goes direct |
|
||||||
| the squid self-check's password | `swarm-controller` mints `swarm/hives/<hive>/squid-selfcheck`; `squid-selfcheck-credential` (root, every 10 minutes) reads it as the hive | `/run/credstore/hive-squid.selfcheck` (tmpfs, root, `0400`), imported by `squid-selfcheck.service` as a systemd credential and handed to `curl` on its stdin. Both self-check users (`selfcheck.squid` and the always-unrestricted `selfcheck-unrestricted.squid`) use it, so whoever holds it has unrestricted egress through this squid Missing, or different from the users file: the self-check logs `credential=absent` or a 407 and fails, and nothing else breaks |
|
| the squid self-check's password | `swarm-controller` mints `swarm/hives/<hive>/squid-selfcheck`; `squid-selfcheck-credential` (root, every 10 minutes) reads it as the hive | `/run/credstore/hive-squid.selfcheck` (tmpfs, root, `0400`), imported by `squid-selfcheck.service` as a systemd credential and handed to `curl` on its stdin. Both self-check users (`selfcheck.squid` and the always-unrestricted `selfcheck-unrestricted.squid`) use it, so whoever holds it has unrestricted egress through this squid Missing, or different from the users file: the self-check logs `credential=absent` or a 407 and fails, and nothing else breaks |
|
||||||
|
|
||||||
### Store identities, one per principal
|
### Store identities, one per principal
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
//! Squid reads both when it parses its configuration, so the path unit in
|
//! Squid reads both when it parses its configuration, so the path unit in
|
||||||
//! `nix/host-modules/hive-squid.nix` reloads it when either changes.
|
//! `nix/host-modules/hive-squid.nix` reloads it when either changes.
|
||||||
//!
|
//!
|
||||||
//! The names `services.hyperhive.squid.allowedDomains` lists ([`ENV_SEED_FILE`])
|
//! The names `services.hyperhive.deploy.hive-controller.squid.allowedDomains` lists ([`ENV_SEED_FILE`])
|
||||||
//! are always allowed: the swarm-wide names written are those plus the swarm's,
|
//! are always allowed: the swarm-wide names written are those plus the swarm's,
|
||||||
//! with the per-agent rules on top. Until the swarm has a list the files hold
|
//! with the per-agent rules on top. Until the swarm has a list the files hold
|
||||||
//! just those names. A file from the swarm's list starts with [`SWARM_MARKER`];
|
//! just those names. A file from the swarm's list starts with [`SWARM_MARKER`];
|
||||||
|
|
@ -46,14 +46,14 @@ pub const INTERVAL: Duration = Duration::from_secs(30);
|
||||||
const FAILURES_BEFORE_WARNING: u32 = 3;
|
const FAILURES_BEFORE_WARNING: u32 = 3;
|
||||||
|
|
||||||
/// The swarm-wide names file. Set by `nix/host-modules/hive-c0re` from
|
/// The swarm-wide names file. Set by `nix/host-modules/hive-c0re` from
|
||||||
/// `services.hyperhive.squid.allowedFile`.
|
/// `services.hyperhive.deploy.hive-controller.squid.allowedFile`.
|
||||||
pub const ENV_ALLOWED_FILE: &str = "HIVE_SQUID_ALLOWED_FILE";
|
pub const ENV_ALLOWED_FILE: &str = "HIVE_SQUID_ALLOWED_FILE";
|
||||||
|
|
||||||
/// The per-agent squid configuration file. Set from
|
/// The per-agent squid configuration file. Set from
|
||||||
/// `services.hyperhive.squid.agentAllowFile`.
|
/// `services.hyperhive.deploy.hive-controller.squid.agentAllowFile`.
|
||||||
pub const ENV_AGENT_ALLOW_FILE: &str = "HIVE_SQUID_AGENT_ALLOW_FILE";
|
pub const ENV_AGENT_ALLOW_FILE: &str = "HIVE_SQUID_AGENT_ALLOW_FILE";
|
||||||
|
|
||||||
/// The file of names `services.hyperhive.squid.allowedDomains` lists, one per
|
/// The file of names `services.hyperhive.deploy.hive-controller.squid.allowedDomains` lists, one per
|
||||||
/// line, which every rendering of the swarm-wide names includes.
|
/// line, which every rendering of the swarm-wide names includes.
|
||||||
pub const ENV_SEED_FILE: &str = "HIVE_SQUID_ALLOWED_SEED_FILE";
|
pub const ENV_SEED_FILE: &str = "HIVE_SQUID_ALLOWED_SEED_FILE";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,11 @@ pub const INTERVAL: Duration = Duration::from_secs(30);
|
||||||
const FAILURES_BEFORE_WARNING: u32 = 3;
|
const FAILURES_BEFORE_WARNING: u32 = 3;
|
||||||
|
|
||||||
/// The environment variable naming the file. Set by `nix/host-modules/hive-c0re`
|
/// The environment variable naming the file. Set by `nix/host-modules/hive-c0re`
|
||||||
/// from `services.hyperhive.squid.usersFile`; unset means this host runs no squid.
|
/// from `services.hyperhive.deploy.hive-controller.squid.usersFile`; unset means this host runs no squid.
|
||||||
pub const ENV_USERS_FILE: &str = "HIVE_SQUID_USERS_FILE";
|
pub const ENV_USERS_FILE: &str = "HIVE_SQUID_USERS_FILE";
|
||||||
|
|
||||||
/// The environment variable naming the unrestricted-users list. Set by
|
/// The environment variable naming the unrestricted-users list. Set by
|
||||||
/// `nix/host-modules/hive-c0re` from `services.hyperhive.squid.unrestrictedFile`.
|
/// `nix/host-modules/hive-c0re` from `services.hyperhive.deploy.hive-controller.squid.unrestrictedFile`.
|
||||||
pub const ENV_UNRESTRICTED_FILE: &str = "HIVE_SQUID_UNRESTRICTED_FILE";
|
pub const ENV_UNRESTRICTED_FILE: &str = "HIVE_SQUID_UNRESTRICTED_FILE";
|
||||||
|
|
||||||
/// Raw salt bytes: twelve of them encode to the sixteen characters `crypt()`
|
/// Raw salt bytes: twelve of them encode to the sixteen characters `crypt()`
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,45 @@ in
|
||||||
[ "services" "hyperhive" "c0re" "adminUsers" ]
|
[ "services" "hyperhive" "c0re" "adminUsers" ]
|
||||||
[ "services" "hyperhive" "deploy" "hive-controller" "adminUsers" ]
|
[ "services" "hyperhive" "deploy" "hive-controller" "adminUsers" ]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# The egress proxy runs only on a hive host, so its settings sit with the
|
||||||
|
# controller's. The read-only ones moved without a forward.
|
||||||
|
(lib.mkRenamedOptionModule
|
||||||
|
[ "services" "hyperhive" "squid" "allowedDomains" ]
|
||||||
|
[ "services" "hyperhive" "deploy" "hive-controller" "squid" "allowedDomains" ]
|
||||||
|
)
|
||||||
|
(lib.mkRenamedOptionModule
|
||||||
|
[ "services" "hyperhive" "squid" "baseAllowedDomains" ]
|
||||||
|
[ "services" "hyperhive" "deploy" "hive-controller" "squid" "baseAllowedDomains" ]
|
||||||
|
)
|
||||||
|
(lib.mkRenamedOptionModule
|
||||||
|
[ "services" "hyperhive" "squid" "usersFile" ]
|
||||||
|
[ "services" "hyperhive" "deploy" "hive-controller" "squid" "usersFile" ]
|
||||||
|
)
|
||||||
|
(lib.mkRenamedOptionModule
|
||||||
|
[ "services" "hyperhive" "squid" "selfcheck" "unrestrictedCanary" ]
|
||||||
|
[
|
||||||
|
"services"
|
||||||
|
"hyperhive"
|
||||||
|
"deploy"
|
||||||
|
"hive-controller"
|
||||||
|
"squid"
|
||||||
|
"selfcheck"
|
||||||
|
"unrestrictedCanary"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
(lib.mkRenamedOptionModule
|
||||||
|
[ "services" "hyperhive" "squid" "selfcheck" "canary" ]
|
||||||
|
[
|
||||||
|
"services"
|
||||||
|
"hyperhive"
|
||||||
|
"deploy"
|
||||||
|
"hive-controller"
|
||||||
|
"squid"
|
||||||
|
"selfcheck"
|
||||||
|
"canary"
|
||||||
|
]
|
||||||
|
)
|
||||||
(lib.mkRenamedOptionModule
|
(lib.mkRenamedOptionModule
|
||||||
[ "services" "hyperhive" "otel" "extraResourceAttributes" ]
|
[ "services" "hyperhive" "otel" "extraResourceAttributes" ]
|
||||||
[ "services" "hyperhive" "deploy" "hive-controller" "otel" "extraResourceAttributes" ]
|
[ "services" "hyperhive" "deploy" "hive-controller" "otel" "extraResourceAttributes" ]
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,7 @@ in
|
||||||
# `-` so a host without the squid users directory still starts the daemon.
|
# `-` so a host without the squid users directory still starts the daemon.
|
||||||
ReadWritePaths = [
|
ReadWritePaths = [
|
||||||
"/var/lib/hive-gateway/conf"
|
"/var/lib/hive-gateway/conf"
|
||||||
"-${builtins.dirOf config.services.hyperhive.squid.usersFile}"
|
"-${builtins.dirOf config.services.hyperhive.deploy.hive-controller.squid.usersFile}"
|
||||||
];
|
];
|
||||||
ProtectKernelTunables = true; # no sysctl writes
|
ProtectKernelTunables = true; # no sysctl writes
|
||||||
ProtectKernelLogs = true; # no /dev/kmsg access needed
|
ProtectKernelLogs = true; # no /dev/kmsg access needed
|
||||||
|
|
|
||||||
|
|
@ -290,21 +290,23 @@ in
|
||||||
# credentials for squid, and the list of the users whose agent holds the
|
# credentials for squid, and the list of the users whose agent holds the
|
||||||
# swarm's `unrestricted_internet` flag; it reads the credentials from the
|
# swarm's `unrestricted_internet` flag; it reads the credentials from the
|
||||||
# store under the identity above.
|
# store under the identity above.
|
||||||
HIVE_SQUID_USERS_FILE = config.services.hyperhive.squid.usersFile;
|
HIVE_SQUID_USERS_FILE = config.services.hyperhive.deploy.hive-controller.squid.usersFile;
|
||||||
HIVE_SQUID_UNRESTRICTED_FILE = config.services.hyperhive.squid.unrestrictedFile;
|
HIVE_SQUID_UNRESTRICTED_FILE =
|
||||||
|
config.services.hyperhive.deploy.hive-controller.squid.unrestrictedFile;
|
||||||
# The swarm's egress allow-list, which `workers::squid_allow` renders into
|
# The swarm's egress allow-list, which `workers::squid_allow` renders into
|
||||||
# the two files; the seed is the list the files hold until the swarm has one,
|
# the two files; the seed is the list the files hold until the swarm has one,
|
||||||
# and the always-allowed names are those it never repeats.
|
# and the always-allowed names are those it never repeats.
|
||||||
HIVE_SQUID_ALLOWED_FILE = config.services.hyperhive.squid.allowedFile;
|
HIVE_SQUID_ALLOWED_FILE = config.services.hyperhive.deploy.hive-controller.squid.allowedFile;
|
||||||
HIVE_SQUID_AGENT_ALLOW_FILE = config.services.hyperhive.squid.agentAllowFile;
|
HIVE_SQUID_AGENT_ALLOW_FILE = config.services.hyperhive.deploy.hive-controller.squid.agentAllowFile;
|
||||||
HIVE_SQUID_ALLOWED_SEED_FILE = config.services.hyperhive.squid.allowedSeedFile;
|
HIVE_SQUID_ALLOWED_SEED_FILE =
|
||||||
HIVE_SQUID_ALWAYS_ALLOWED = lib.concatStringsSep " " config.services.hyperhive.squid.alwaysAllowed;
|
config.services.hyperhive.deploy.hive-controller.squid.allowedSeedFile;
|
||||||
|
HIVE_SQUID_ALWAYS_ALLOWED = lib.concatStringsSep " " config.services.hyperhive.deploy.hive-controller.squid.alwaysAllowed;
|
||||||
# The egress proxy facts every container is handed (`HiveFacts` in
|
# The egress proxy facts every container is handed (`HiveFacts` in
|
||||||
# `hive-priv-sock`). They sit with the users file above because that is what
|
# `hive-priv-sock`). They sit with the users file above because that is what
|
||||||
# makes squid's credential check and per-agent policy real on this host: an
|
# makes squid's credential check and per-agent policy real on this host: an
|
||||||
# agent sends nothing through the proxy unless it reads both. Absent on a
|
# agent sends nothing through the proxy unless it reads both. Absent on a
|
||||||
# hive that predates them, so its agents go direct.
|
# hive that predates them, so its agents go direct.
|
||||||
HIVE_SQUID_PROXY = config.services.hyperhive.squid.listen;
|
HIVE_SQUID_PROXY = config.services.hyperhive.deploy.hive-controller.squid.listen;
|
||||||
HIVE_EGRESS_NO_PROXY = lib.concatStringsSep "," egressDirectHosts;
|
HIVE_EGRESS_NO_PROXY = lib.concatStringsSep "," egressDirectHosts;
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (haveBaoClientIdentity && baoDeploy.serverCaFile != null) {
|
// lib.optionalAttrs (haveBaoClientIdentity && baoDeploy.serverCaFile != null) {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ let
|
||||||
&& tls.baoHiveIdentityCertFile != null
|
&& tls.baoHiveIdentityCertFile != null
|
||||||
&& tls.baoHiveIdentityKeyFile != null;
|
&& tls.baoHiveIdentityKeyFile != null;
|
||||||
|
|
||||||
credentialFile = "/run/credstore/${hyperhiveCfg.squid.selfcheck.credentialName}";
|
credentialFile = "/run/credstore/${hyperhiveCfg.deploy.hive-controller.squid.selfcheck.credentialName}";
|
||||||
|
|
||||||
storeRetry = import ./lib/store-retry.nix { };
|
storeRetry = import ./lib/store-retry.nix { };
|
||||||
storeRefreshTimer = import ./lib/store-refresh-timer.nix { };
|
storeRefreshTimer = import ./lib/store-refresh-timer.nix { };
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
hyperhiveCfg = config.services.hyperhive;
|
hyperhiveCfg = config.services.hyperhive;
|
||||||
cfg = hyperhiveCfg.squid;
|
cfg = hyperhiveCfg.deploy.hive-controller.squid;
|
||||||
netCfg = hyperhiveCfg.network;
|
netCfg = hyperhiveCfg.network;
|
||||||
|
|
||||||
port = 3128;
|
port = 3128;
|
||||||
|
|
@ -232,7 +232,7 @@ let
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.hyperhive.squid = {
|
options.services.hyperhive.deploy.hive-controller.squid = {
|
||||||
listen = lib.mkOption {
|
listen = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = listen;
|
default = listen;
|
||||||
|
|
@ -492,7 +492,7 @@ in
|
||||||
{
|
{
|
||||||
assertion = !(builtins.elem cfg.selfcheck.unrestrictedCanary (allowed ++ base));
|
assertion = !(builtins.elem cfg.selfcheck.unrestrictedCanary (allowed ++ base));
|
||||||
message = ''
|
message = ''
|
||||||
services.hyperhive.squid.selfcheck.unrestrictedCanary must be a name outside
|
services.hyperhive.deploy.hive-controller.squid.selfcheck.unrestrictedCanary must be a name outside
|
||||||
allowedDomains and baseAllowedDomains, or the self-check cannot tell an unrestricted user from a
|
allowedDomains and baseAllowedDomains, or the self-check cannot tell an unrestricted user from a
|
||||||
restricted one.
|
restricted one.
|
||||||
'';
|
'';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# The default of `services.hyperhive.squid.baseAllowedDomains`, and the names
|
# The default of `services.hyperhive.deploy.hive-controller.squid.baseAllowedDomains`, and the names
|
||||||
# swarm-controller refuses as allow-list entries because squid already allows
|
# swarm-controller refuses as allow-list entries because squid already allows
|
||||||
# them to every authenticated user: the hosts Claude Code requires
|
# them to every authenticated user: the hosts Claude Code requires
|
||||||
# (<https://code.claude.com/docs/en/network-config>).
|
# (<https://code.claude.com/docs/en/network-config>).
|
||||||
|
|
|
||||||
|
|
@ -867,8 +867,8 @@ in
|
||||||
# The names squid allows every authenticated agent by default. The
|
# The names squid allows every authenticated agent by default. The
|
||||||
# allow-list route refuses them as entries
|
# allow-list route refuses them as entries
|
||||||
# (swarm-controller/src/egress_allow.rs). A hive that overrides
|
# (swarm-controller/src/egress_allow.rs). A hive that overrides
|
||||||
# `squid.baseAllowedDomains` is not reflected here; its hive-c0re
|
# `deploy.hive-controller.squid.baseAllowedDomains` is not reflected
|
||||||
# skips the entries its own list covers.
|
# here; its hive-c0re skips the entries its own list covers.
|
||||||
SWARM_CONTROLLER_SQUID_BASE_DOMAINS = lib.concatStringsSep " " (
|
SWARM_CONTROLLER_SQUID_BASE_DOMAINS = lib.concatStringsSep " " (
|
||||||
import ./lib/squid-base-domains.nix
|
import ./lib/squid-base-domains.nix
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ let
|
||||||
name = "the controller is handed the base list squid defaults to";
|
name = "the controller is handed the base list squid defaults to";
|
||||||
ok =
|
ok =
|
||||||
let
|
let
|
||||||
base = baoControllerHere.services.hyperhive.squid.baseAllowedDomains;
|
base = baoControllerHere.services.hyperhive.deploy.hive-controller.squid.baseAllowedDomains;
|
||||||
in
|
in
|
||||||
base != [ ]
|
base != [ ]
|
||||||
&&
|
&&
|
||||||
|
|
|
||||||
|
|
@ -1621,6 +1621,73 @@ let
|
||||||
&& (locs h.swarm.forge.domain)."/".proxyPass == "http://127.0.0.1:3000/"
|
&& (locs h.swarm.forge.domain)."/".proxyPass == "http://127.0.0.1:3000/"
|
||||||
&& !allLocal.containers.hive-matrix.config.services.matrix-tuwunel.settings.global.allow_encryption;
|
&& !allLocal.containers.hive-matrix.config.services.matrix-tuwunel.settings.global.allow_encryption;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
# Each old spelling lands on the new path, with its own rename warning;
|
||||||
|
# the squid.conf it renders equals the one the new spelling renders, and
|
||||||
|
# differs from the default's (the control that the values reach it).
|
||||||
|
name = "services.hyperhive.squid.* settings still apply, with a rename warning each";
|
||||||
|
ok =
|
||||||
|
let
|
||||||
|
old = hiveWithController {
|
||||||
|
squid = {
|
||||||
|
allowedDomains = [ "legacy.example" ];
|
||||||
|
baseAllowedDomains = [ "base.example" ];
|
||||||
|
usersFile = "/var/lib/legacy-squid/users";
|
||||||
|
selfcheck.unrestrictedCanary = "legacy-u.example";
|
||||||
|
selfcheck.canary = "legacy-c.example";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
new = hiveWithController {
|
||||||
|
deploy.hive-controller.squid = {
|
||||||
|
allowedDomains = [ "legacy.example" ];
|
||||||
|
baseAllowedDomains = [ "base.example" ];
|
||||||
|
usersFile = "/var/lib/legacy-squid/users";
|
||||||
|
selfcheck.unrestrictedCanary = "legacy-u.example";
|
||||||
|
selfcheck.canary = "legacy-c.example";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
sq = old.services.hyperhive.deploy.hive-controller.squid;
|
||||||
|
warned =
|
||||||
|
m: path:
|
||||||
|
lib.any (
|
||||||
|
w: lib.hasInfix "services.hyperhive.squid.${path}" w && lib.hasInfix "has been renamed" w
|
||||||
|
) m.warnings;
|
||||||
|
in
|
||||||
|
sq.allowedDomains == [ "legacy.example" ]
|
||||||
|
&& sq.baseAllowedDomains == [ "base.example" ]
|
||||||
|
&& sq.usersFile == "/var/lib/legacy-squid/users"
|
||||||
|
&& sq.allowedFile == "/var/lib/legacy-squid/allowed"
|
||||||
|
&& sq.selfcheck.unrestrictedCanary == "legacy-u.example"
|
||||||
|
&& sq.selfcheck.canary == "legacy-c.example"
|
||||||
|
&& lib.all (warned old) [
|
||||||
|
"allowedDomains"
|
||||||
|
"baseAllowedDomains"
|
||||||
|
"usersFile"
|
||||||
|
"selfcheck.unrestrictedCanary"
|
||||||
|
"selfcheck.canary"
|
||||||
|
]
|
||||||
|
&& !(warned bare "allowedDomains")
|
||||||
|
&& old.systemd.services.hive-c0re.environment.HIVE_SQUID_USERS_FILE == "/var/lib/legacy-squid/users"
|
||||||
|
&& old.services.squid.configText == new.services.squid.configText
|
||||||
|
&& lib.hasInfix "legacy-c.example" old.services.squid.configText
|
||||||
|
&& !(lib.hasInfix "legacy-c.example" bare.services.squid.configText);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# The default render, pinned so moving the options changes none of it:
|
||||||
|
# the listen address squid binds and hive-c0re hands out, and the users
|
||||||
|
# file hive-c0re writes.
|
||||||
|
name = "squid's default listen address and users file reach squid.conf and hive-c0re unchanged";
|
||||||
|
ok =
|
||||||
|
let
|
||||||
|
e = bare.systemd.services.hive-c0re.environment;
|
||||||
|
conf = bare.services.squid.configText;
|
||||||
|
in
|
||||||
|
e.HIVE_SQUID_PROXY == "${bare.services.hyperhive.network.bridgeIp}:3128"
|
||||||
|
&& e.HIVE_SQUID_USERS_FILE == "/var/lib/hive-squid/users"
|
||||||
|
&& lib.hasInfix "http_port ${e.HIVE_SQUID_PROXY}" conf
|
||||||
|
&& lib.hasInfix "basic_ncsa_auth /var/lib/hive-squid/users" conf
|
||||||
|
&& lib.hasInfix "acl allowed_dst dstdomain cache.nixos.org" conf;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
# A hive's rendered identity, pinned so moving the option changes none of
|
# A hive's rendered identity, pinned so moving the option changes none of
|
||||||
# it: the coordinator's name and client, the dashboard name, the CN of the
|
# it: the coordinator's name and client, the dashboard name, the CN of the
|
||||||
|
|
|
||||||
|
|
@ -507,7 +507,7 @@ let
|
||||||
unrestricted = at "http_access allow unrestricted";
|
unrestricted = at "http_access allow unrestricted";
|
||||||
authed = at "http_access deny !authed";
|
authed = at "http_access deny !authed";
|
||||||
# The generated per-agent `http_access allow` rules sit in this file.
|
# The generated per-agent `http_access allow` rules sit in this file.
|
||||||
agentRules = at "include ${hiveOtel.services.hyperhive.squid.agentAllowFile}";
|
agentRules = at "include ${hiveOtel.services.hyperhive.deploy.hive-controller.squid.agentAllowFile}";
|
||||||
firstAllow = lib.min agentRules (lib.min base (lib.min unrestricted allow));
|
firstAllow = lib.min agentRules (lib.min base (lib.min unrestricted allow));
|
||||||
in
|
in
|
||||||
allow != null
|
allow != null
|
||||||
|
|
@ -550,9 +550,10 @@ let
|
||||||
acl = lib.findFirst (l: lib.hasPrefix "acl allowed_dst dstdomain " l) "" (map lib.trim lines);
|
acl = lib.findFirst (l: lib.hasPrefix "acl allowed_dst dstdomain " l) "" (map lib.trim lines);
|
||||||
baseAcl = lib.findFirst (l: lib.hasPrefix "acl base_dst dstdomain " l) "" (map lib.trim lines);
|
baseAcl = lib.findFirst (l: lib.hasPrefix "acl base_dst dstdomain " l) "" (map lib.trim lines);
|
||||||
in
|
in
|
||||||
acl == "acl allowed_dst dstdomain ${hiveOtel.services.hyperhive.squid.selfcheck.canary}"
|
acl
|
||||||
|
== "acl allowed_dst dstdomain ${hiveOtel.services.hyperhive.deploy.hive-controller.squid.selfcheck.canary}"
|
||||||
&& baseAcl == "acl base_dst dstdomain api.anthropic.com claude.ai platform.claude.com"
|
&& baseAcl == "acl base_dst dstdomain api.anthropic.com claude.ai platform.claude.com"
|
||||||
&& hiveOtel.services.hyperhive.squid.selfcheck.canary == "cache.nixos.org"
|
&& hiveOtel.services.hyperhive.deploy.hive-controller.squid.selfcheck.canary == "cache.nixos.org"
|
||||||
&& !(builtins.elem hiveOtel.services.hyperhive.swarm.forge.domain (lib.splitString " " acl));
|
&& !(builtins.elem hiveOtel.services.hyperhive.swarm.forge.domain (lib.splitString " " acl));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
@ -592,7 +593,7 @@ let
|
||||||
conf = hiveOtel.services.squid.configText;
|
conf = hiveOtel.services.squid.configText;
|
||||||
lines = lib.splitString "\n" conf;
|
lines = lib.splitString "\n" conf;
|
||||||
at = l: lib.lists.findFirstIndex (x: x == l) null lines;
|
at = l: lib.lists.findFirstIndex (x: x == l) null lines;
|
||||||
list = hiveOtel.services.hyperhive.squid.unrestrictedFile;
|
list = hiveOtel.services.hyperhive.deploy.hive-controller.squid.unrestrictedFile;
|
||||||
in
|
in
|
||||||
at "http_access allow unrestricted" != null
|
at "http_access allow unrestricted" != null
|
||||||
&& at "http_access deny !allowed_dst" != null
|
&& at "http_access deny !allowed_dst" != null
|
||||||
|
|
@ -609,15 +610,15 @@ let
|
||||||
name = "squid is reloaded when its unrestricted-users list changes";
|
name = "squid is reloaded when its unrestricted-users list changes";
|
||||||
ok =
|
ok =
|
||||||
let
|
let
|
||||||
list = hiveOtel.services.hyperhive.squid.unrestrictedFile;
|
list = hiveOtel.services.hyperhive.deploy.hive-controller.squid.unrestrictedFile;
|
||||||
rules = hiveOtel.systemd.tmpfiles.rules;
|
rules = hiveOtel.systemd.tmpfiles.rules;
|
||||||
path = hiveOtel.systemd.paths.squid-unrestricted-reload;
|
path = hiveOtel.systemd.paths.squid-unrestricted-reload;
|
||||||
svc = hiveOtel.systemd.services.squid-unrestricted-reload.serviceConfig;
|
svc = hiveOtel.systemd.services.squid-unrestricted-reload.serviceConfig;
|
||||||
in
|
in
|
||||||
path.pathConfig.PathChanged == [
|
path.pathConfig.PathChanged == [
|
||||||
list
|
list
|
||||||
hiveOtel.services.hyperhive.squid.allowedFile
|
hiveOtel.services.hyperhive.deploy.hive-controller.squid.allowedFile
|
||||||
hiveOtel.services.hyperhive.squid.agentAllowFile
|
hiveOtel.services.hyperhive.deploy.hive-controller.squid.agentAllowFile
|
||||||
]
|
]
|
||||||
&& hiveOtel.systemd.services.squid-unrestricted-reload.startLimitIntervalSec == 0
|
&& hiveOtel.systemd.services.squid-unrestricted-reload.startLimitIntervalSec == 0
|
||||||
&& builtins.elem "paths.target" path.wantedBy
|
&& builtins.elem "paths.target" path.wantedBy
|
||||||
|
|
@ -635,7 +636,7 @@ let
|
||||||
name = "squid reads the swarm's allow-list from a file seeded with the hive's own names";
|
name = "squid reads the swarm's allow-list from a file seeded with the hive's own names";
|
||||||
ok =
|
ok =
|
||||||
let
|
let
|
||||||
sq = hiveOtelAllLocal.services.hyperhive.squid;
|
sq = hiveOtelAllLocal.services.hyperhive.deploy.hive-controller.squid;
|
||||||
lines = lib.splitString "\n" hiveOtelAllLocal.services.squid.configText;
|
lines = lib.splitString "\n" hiveOtelAllLocal.services.squid.configText;
|
||||||
rules = hiveOtelAllLocal.systemd.tmpfiles.rules;
|
rules = hiveOtelAllLocal.systemd.tmpfiles.rules;
|
||||||
env = hiveOtelAllLocal.systemd.services.hive-c0re.environment;
|
env = hiveOtelAllLocal.systemd.services.hive-c0re.environment;
|
||||||
|
|
@ -675,7 +676,7 @@ let
|
||||||
let
|
let
|
||||||
conf = hiveOtel.services.squid.configText;
|
conf = hiveOtel.services.squid.configText;
|
||||||
lines = lib.splitString "\n" conf;
|
lines = lib.splitString "\n" conf;
|
||||||
users = hiveOtel.services.hyperhive.squid.usersFile;
|
users = hiveOtel.services.hyperhive.deploy.hive-controller.squid.usersFile;
|
||||||
rules = hiveOtel.systemd.tmpfiles.rules;
|
rules = hiveOtel.systemd.tmpfiles.rules;
|
||||||
sc = hiveOtel.systemd.services.squid-selfcheck.serviceConfig;
|
sc = hiveOtel.systemd.services.squid-selfcheck.serviceConfig;
|
||||||
in
|
in
|
||||||
|
|
@ -686,7 +687,9 @@ let
|
||||||
&& users == "/var/lib/hive-squid/users"
|
&& users == "/var/lib/hive-squid/users"
|
||||||
&& builtins.elem "d /var/lib/hive-squid 2750 hive-core squid - -" rules
|
&& builtins.elem "d /var/lib/hive-squid 2750 hive-core squid - -" rules
|
||||||
&& builtins.elem "f ${users} 0640 hive-core squid - -" rules
|
&& builtins.elem "f ${users} 0640 hive-core squid - -" rules
|
||||||
&& sc.ImportCredential == hiveOtel.services.hyperhive.squid.selfcheck.credentialName
|
&&
|
||||||
|
sc.ImportCredential
|
||||||
|
== hiveOtel.services.hyperhive.deploy.hive-controller.squid.selfcheck.credentialName
|
||||||
&& hiveOtelAllLocal.systemd.services.hive-c0re.environment.HIVE_SQUID_USERS_FILE == users;
|
&& hiveOtelAllLocal.systemd.services.hive-c0re.environment.HIVE_SQUID_USERS_FILE == users;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -175,13 +175,13 @@ pkgs.testers.runNixOSTest {
|
||||||
networking.firewall.interfaces.eth1.allowedTCPPorts = [ 443 ];
|
networking.firewall.interfaces.eth1.allowedTCPPorts = [ 443 ];
|
||||||
# Renders the users file the way hive-c0re does.
|
# Renders the users file the way hive-c0re does.
|
||||||
environment.systemPackages = [ pkgs.mkpasswd ];
|
environment.systemPackages = [ pkgs.mkpasswd ];
|
||||||
services.hyperhive.squid.selfcheck.unrestrictedCanary = "other.t.local";
|
services.hyperhive.deploy.hive-controller.squid.selfcheck.unrestrictedCanary = "other.t.local";
|
||||||
services.hyperhive.squid.selfcheck.canary = "cache.t.local";
|
services.hyperhive.deploy.hive-controller.squid.selfcheck.canary = "cache.t.local";
|
||||||
services.hyperhive.squid.baseAllowedDomains = [
|
services.hyperhive.deploy.hive-controller.squid.baseAllowedDomains = [
|
||||||
"api.t.local"
|
"api.t.local"
|
||||||
"basebridge.t.local"
|
"basebridge.t.local"
|
||||||
];
|
];
|
||||||
services.hyperhive.squid.allowedDomains = [
|
services.hyperhive.deploy.hive-controller.squid.allowedDomains = [
|
||||||
"forge.t.local"
|
"forge.t.local"
|
||||||
"loop.t.local"
|
"loop.t.local"
|
||||||
"bridge.t.local"
|
"bridge.t.local"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
//! reads it and renders the entries for the agents it runs: a swarm-wide entry
|
//! reads it and renders the entries for the agents it runs: a swarm-wide entry
|
||||||
//! joins the proxy's allow list for everyone, an entry with an agent is that
|
//! joins the proxy's allow list for everyone, an entry with an agent is that
|
||||||
//! agent's alone. A hive always allows the names its own nix configuration
|
//! agent's alone. A hive always allows the names its own nix configuration
|
||||||
//! lists (`services.hyperhive.squid.allowedDomains`) as well, so these entries
|
//! lists (`services.hyperhive.deploy.hive-controller.squid.allowedDomains`) as well, so these entries
|
||||||
//! only add to them.
|
//! only add to them.
|
||||||
//!
|
//!
|
||||||
//! Each name goes into the proxy's configuration, so it is checked here with
|
//! Each name goes into the proxy's configuration, so it is checked here with
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue