diff --git a/docs/TODO.md b/docs/TODO.md index eb7d908..8858a7e 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1447,12 +1447,17 @@ the design forks resolved: 3. **Distroless perms.** The nonroot manager (uid 65532) can't read `pki/agent/*` if created `0600` by the host user → `open …/server.crt: permission denied`. `chown 65532` the agent PKI (as with the fleet-data volume). - 4. **Wrong manager IP / split-horizon DNS.** `diskless-server.bitasylum.org` - resolved to the serving host's OUTBOUND IP (`no route to host` from the fleet - LAN). Bench workaround: `FLEET_AGENT_MANAGER=:9600` + - `FLEET_AGENT_SERVER_NAME=` (dial the IP, verify the cert's SAN). - PROD FIX (not code): fleet dnsmasq `--address=//` so the - baked default resolves on the host VLAN. + 4. **Manager wasn't a fleet name.** The agent's baked default pointed at the + PUBLIC admin-UI name (`diskless-server.bitasylum.org`), which resolves to the + serving host's OUTBOUND IP → `no route to host` from the fleet LAN. FIX: the + agent plane is now just another `*.fleet.lab` — `manager.fleet.lab` (`MGMT_HOST` + in serving/.env), served by the fleet dnsmasq to `SERVER_IP` exactly like + boot/nvme/audit (`--address=/${MGMT_HOST}/${SERVER_IP}`), baked as + `FLEET_AGENT_MANAGER` and set as the agent server cert SAN (`AGENT_SANS`). No + per-host override, no server-name hack. (The public `diskless-server…` name + stays the ADMIN-UI name on Traefik/:443 — a separate plane.) The transient + bench workaround was `FLEET_AGENT_MANAGER= + FLEET_AGENT_SERVER_NAME=`; + no longer needed. 5. **Host not in the manager's inventory** → `PermissionDenied` (surfaced as a bare `EOF` on the agent before the fix). A host enrolled OUT OF BAND (bench broker / migrated fleet) has no inventory row. FIX: `fleet-manager diff --git a/files/agent/agent.env b/files/agent/agent.env index 4d3578a..0f762a6 100644 --- a/files/agent/agent.env +++ b/files/agent/agent.env @@ -6,10 +6,13 @@ # environment by replacing this file (it is part of the immutable image, so a # change means a rebuild + re-sign, like any other baked config). -# The fleet-manager agent plane (gRPC/mTLS). A DNS name, NOT a per-host value. -# Reached from the authenticated host VLAN via the OPNsense L3 hop to the mgmt -# plane (not the boot nginx). Set to your manager's real name:port. -FLEET_AGENT_MANAGER=diskless-server.bitasylum.org:9600 +# The fleet-manager agent plane (gRPC/mTLS). A fleet DNS name (NOT per-host), +# resolved by the serving dnsmasq like boot/nvme/audit — MGMT_HOST in serving/.env +# points it at the manager's fleet-LAN address (this serving host now; a routable +# mgmt address once the manager moves behind OPNsense L3 / k8s). Must match the +# agent server cert SAN (server-pki.sh AGENT_SANS). This is the AGENT plane, NOT +# the public admin-UI name (that's Traefik/Let's Encrypt on :443). +FLEET_AGENT_MANAGER=manager.fleet.lab:9600 # Fleet CA that verifies the manager's server cert. This is the SAME step-ca root # that signs the host TPM certs + the RADIUS server cert, so we reuse the in-place diff --git a/files/agent/main.go b/files/agent/main.go index 96f45d8..dcfe9a0 100644 --- a/files/agent/main.go +++ b/files/agent/main.go @@ -198,7 +198,7 @@ func logDown(down *fleetpb.ManagerDown) { // ---- config ---------------------------------------------------------------- func loadConfig() config { - manager := env("FLEET_AGENT_MANAGER", "diskless-server.bitasylum.org:9600") + manager := env("FLEET_AGENT_MANAGER", "manager.fleet.lab:9600") cfg := config{ manager: manager, serverName: env("FLEET_AGENT_SERVER_NAME", hostOf(manager)), diff --git a/serving/.env.example b/serving/.env.example index d5b256f..189ebb2 100644 --- a/serving/.env.example +++ b/serving/.env.example @@ -72,6 +72,13 @@ NVME_HOST=nvme.fleet.lab # Remote audit collector name. Host-generic — bake into the image's rsyslog # forward rule so every host offloads auditd here; resolved to this serving host. AUDIT_HOST=audit.fleet.lab +# Fleet-manager AGENT plane name. Baked into the image (files/agent/agent.env +# FLEET_AGENT_MANAGER) so every enrolled host dials the control plane here; +# resolved per-environment to the manager's fleet-LAN address (this serving host +# now; a routable mgmt address once the manager moves to k8s). Just another +# *.fleet.lab like the boot/nvme/audit names. Must match the agent server cert SAN +# (server-pki.sh AGENT_SANS). +MGMT_HOST=manager.fleet.lab # --- NVMe/TCP target ------------------------------------------------------- # Per-version subsystem NQN base. The long-lived target serves each rootfs diff --git a/serving/docker-compose.yml b/serving/docker-compose.yml index 84c9ff8..7ddc435 100644 --- a/serving/docker-compose.yml +++ b/serving/docker-compose.yml @@ -104,6 +104,9 @@ services: # Host-generic remote audit collector name (baked into the image config so # every host offloads auditd here; resolved per-environment to this host). - --address=/${AUDIT_HOST}/${SERVER_IP} + # Fleet-manager AGENT plane (:9600) — baked into the image so enrolled hosts + # dial the control plane by name; resolved here like the other fleet names. + - --address=/${MGMT_HOST}/${SERVER_IP} # Kiosk is LOCAL-ONLY (loads boot.fleet.lab), so sinkhole Chromium's # call-home to 0.0.0.0 — telemetry can't leave the lab even if the browser # tries. Defense-in-depth behind the in-image Chromium policy/flags; in diff --git a/serving/fleet-manager/server-pki.sh b/serving/fleet-manager/server-pki.sh index a813b68..b8672c7 100755 --- a/serving/fleet-manager/server-pki.sh +++ b/serving/fleet-manager/server-pki.sh @@ -17,7 +17,7 @@ # Usage: server-pki.sh # env overrides: # OUT=./pki/agent output dir -# AGENT_SANS=diskless-server.bitasylum.org,10.0.0.1 SANs hosts dial (DNS/IP, comma-sep) +# AGENT_SANS=manager.fleet.lab,10.0.0.1 SANs hosts dial (DNS/IP, comma-sep) # FLEET_CA_URL=https://ca.fleet.lab:8443 # FLEET_CA_ROOT=../dot1x-bench/pki/root_ca.crt # STEP_PROVISIONER=enrol @@ -26,7 +26,7 @@ set -euo pipefail OUT=${OUT:-./pki/agent} -AGENT_SANS=${AGENT_SANS:-diskless-server.bitasylum.org} +AGENT_SANS=${AGENT_SANS:-manager.fleet.lab} FLEET_CA_URL=${FLEET_CA_URL:-https://ca.fleet.lab:8443} FLEET_CA_ROOT=${FLEET_CA_ROOT:-../dot1x-bench/pki/root_ca.crt} FLEET_CA_INTERMEDIATE=${FLEET_CA_INTERMEDIATE:-../dot1x-bench/pki/intermediate_ca.crt}