send agent traffic through squid once its hive announces it
This commit is contained in:
parent
86e9f49fe6
commit
b551eb02ff
2 changed files with 885 additions and 27 deletions
|
|
@ -15,6 +15,30 @@ let
|
|||
# sharing a host with the store. Deriving this from
|
||||
# `deploy.bao.enable` would be the co-location assumption itself.
|
||||
haveBaoClientIdentity = baoDeploy.clientCertFile != null && baoDeploy.clientKeyFile != null;
|
||||
|
||||
# What an agent reaches directly and never through squid. Squid refuses every
|
||||
# destination that resolves to the bridge, and the hive's resolver answers the
|
||||
# bridge address for the gateway's names, so each of these must skip it. A bare
|
||||
# name matches itself and its subdomains in curl, Node and reqwest.
|
||||
egressDirectHosts = lib.unique (
|
||||
lib.filter (n: n != null && n != "") (
|
||||
[
|
||||
# Node's NO_PROXY has no CIDR support, so the bridge is listed as the address.
|
||||
config.services.hyperhive.network.bridgeIp
|
||||
# The hive's own zone, which dnsmasq answers with the bridge IP.
|
||||
config.services.hyperhive.domain
|
||||
# The mTLS store and the queue: not in `serviceDomains`.
|
||||
config.services.hyperhive.swarm.bao.domain
|
||||
config.services.hyperhive.swarm.nats.domain
|
||||
]
|
||||
# The swarm's apex (the swarm UI and the controller) and its forge, matrix,
|
||||
# attic, logs, metrics and otel services, wherever they sit. The store and
|
||||
# queue names are not in it, hence their lines above.
|
||||
++ config.services.hyperhive.swarm.serviceDomains
|
||||
# Every name this host's gateway answers with the bridge IP.
|
||||
++ config.services.hyperhive.gateway.localNames
|
||||
)
|
||||
);
|
||||
in
|
||||
{
|
||||
# nix (the prebuild `nix build`, flake-check, and meta eval) writes
|
||||
|
|
@ -277,6 +301,13 @@ in
|
|||
# store under the identity above.
|
||||
HIVE_SQUID_USERS_FILE = config.services.hyperhive.squid.usersFile;
|
||||
HIVE_SQUID_UNRESTRICTED_FILE = config.services.hyperhive.squid.unrestrictedFile;
|
||||
# The egress proxy facts every container is handed (`HiveFacts` in
|
||||
# `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
|
||||
# agent sends nothing through the proxy unless it reads both. Absent on a
|
||||
# hive that predates them, so its agents go direct.
|
||||
HIVE_SQUID_PROXY = config.services.hyperhive.squid.listen;
|
||||
HIVE_EGRESS_NO_PROXY = lib.concatStringsSep "," egressDirectHosts;
|
||||
}
|
||||
// lib.optionalAttrs (haveBaoClientIdentity && baoDeploy.serverCaFile != null) {
|
||||
# Absent means the system trust store — right for a deployment with a real
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
# must carry a per-agent proxy credential, checked against the users file
|
||||
# hive-c0re renders. A credential's agent either has the swarm's
|
||||
# `unrestricted_internet` flag, and may then reach any destination the deny
|
||||
# rules leave, or reaches only the listed names. No agent sends a credential
|
||||
# yet; the exporter, journal forwarding and the self-check below are how a
|
||||
# deploy shows it works.
|
||||
# rules leave, or reaches only the listed names. An agent sends its credential
|
||||
# once it has fetched it (../agent-modules/egress-proxy.nix); the exporter,
|
||||
# journal forwarding and the self-check below show the proxy works.
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
|
|
@ -19,6 +19,7 @@ let
|
|||
netCfg = hyperhiveCfg.network;
|
||||
|
||||
port = 3128;
|
||||
listen = "${netCfg.bridgeIp}:${toString port}";
|
||||
proxyUrl = "http://${netCfg.bridgeIp}:${toString port}";
|
||||
exporterListen = "127.0.0.1:9301";
|
||||
denyCanary = "deny-canary.invalid";
|
||||
|
|
@ -67,7 +68,7 @@ let
|
|||
# port, and every other user to the listed names. The `dst` denies cost an
|
||||
# unlisted name a lookup on the host's resolver before it is refused.
|
||||
squidConf = ''
|
||||
http_port ${netCfg.bridgeIp}:${toString port}
|
||||
http_port ${listen}
|
||||
pid_filename /run/squid/squid.pid
|
||||
cache_log stdio:/var/log/squid/cache.log
|
||||
coredump_dir /var/cache/squid
|
||||
|
|
@ -197,6 +198,19 @@ let
|
|||
in
|
||||
{
|
||||
options.services.hyperhive.squid = {
|
||||
listen = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = listen;
|
||||
readOnly = true;
|
||||
defaultText = lib.literalMD "`<network.bridgeIp>:3128`";
|
||||
description = ''
|
||||
The address squid listens on, as `<bridge IP>:<port>`. Read-only.
|
||||
hive-c0re hands it to every container as the `HIVE_SQUID_PROXY` fact,
|
||||
which is what tells an agent that this host's squid checks its proxy
|
||||
credential and applies its `unrestricted_internet` flag.
|
||||
'';
|
||||
};
|
||||
|
||||
allowedDomains = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = hyperhiveCfg.swarm.serviceDomains;
|
||||
|
|
|
|||
Loading…
Reference in a new issue