Files
Audiobuzz 4c1db3f765 fleet-manager: front the admin UI with Traefik (443 + Route 53 ACME), retire acme side-car
Management-plane ingress: a host-networked Traefik terminates the LE cert on :443
(Route 53 DNS-01, public-resolver propagation check) and forwards plaintext to
the manager running FLEET_MGR_ADMIN_BEHIND_PROXY=true on loopback :9500. Only the
admin plane rides Traefik — the agent gRPC/mTLS plane (:9600) stays direct (Traefik
can't terminate fleet-CA mTLS; hosts reach it via OPNsense L3 routing). This is the
k8s ingress-controller + cert-manager role in miniature.

- traefik/dynamic/fleet-manager.yml: file-provider router (Host rule -> manager),
  passHostHeader so the WebAuthn RP origin matches.
- compose: traefik service (static config as CLI flags so ${ACME_EMAIL} interpolates)
  + traefik-acme volume; manager switched to behind-proxy defaults, RP_ORIGIN now
  the port-less https origin.
- Retire the acme side-car (Traefik owns ACME now): remove the service + acme-state
  volume; renew-loop.sh kept + relabelled as the self-TLS-mode cert helper.
- :443 only (admin UI is https-only) so it can't collide with a boot-LAN nginx :80.
2026-07-05 00:57:04 +00:00

27 lines
1019 B
YAML

# Traefik dynamic config (file provider) — route the admin UI hostname to the
# fleet-manager, which runs in behind-proxy mode (plaintext on loopback :9500,
# passkey auth ON; Traefik terminates the LE cert).
#
# ONLY the admin plane rides Traefik. The agent gRPC/mTLS plane (:9600) is NOT
# here — Traefik can't terminate the fleet-CA client-cert mTLS; hosts reach it
# directly (host VLAN -> OPNsense L3 -> manager:9600). See DEPLOY.md.
#
# Change the Host() rule to your admin-UI hostname (== FLEET_MGR_RP_ID). File
# config isn't env-interpolated, so this is set per-deployment.
http:
routers:
fleet-admin:
rule: "Host(`diskless-server.bitasylum.org`)"
entryPoints:
- websecure
service: fleet-admin
tls:
certResolver: le
services:
fleet-admin:
loadBalancer:
servers:
- url: "http://127.0.0.1:9500" # manager, behind-proxy plaintext (loopback)
passHostHeader: true # preserve Host so WebAuthn RP origin matches