diff --git a/docs/runbooks/post-install.md b/docs/runbooks/post-install.md new file mode 100644 index 0000000..8a127b2 --- /dev/null +++ b/docs/runbooks/post-install.md @@ -0,0 +1,116 @@ +# Post-install: ops-agent bereikbaar maken vanuit de dashboard-container + +Na `sudo bash deploy/ops-agent/setup.sh` draait de agent met de defaults uit +`deploy/ops-agent/ops-agent.service`: + +``` +Environment=OPS_AGENT_HOST=127.0.0.1 +``` + +Dat is veilig (alleen host-loopback) maar **niet bereikbaar vanuit de +ops-dashboard Docker-container**: 127.0.0.1 in de container = de container +zelf, niet de host. Containers op de compose-bridge zien de host alleen via de +bridge-gateway (`172.18.0.1`). De agent moet dáár ook op luisteren, en je +firewall moet de docker-subnet doorlaten naar poort 3099. + +Drie stappen, allemaal as root. + +## 1. Bind agent op alle interfaces + +Drop-in: + +```bash +sudo mkdir -p /etc/systemd/system/ops-agent.service.d +sudo tee /etc/systemd/system/ops-agent.service.d/override.conf >/dev/null <<'EOF' +[Service] +Environment=OPS_AGENT_HOST=0.0.0.0 +EOF +sudo systemctl daemon-reload +sudo systemctl restart ops-agent +``` + +Verifieer: `ss -tnlp | grep 3099` moet `0.0.0.0:3099` tonen. + +> Strakker alternatief: `OPS_AGENT_HOST=172.18.0.1` (alleen op bridge-IP). Werkt +> alleen als je UFW-rule óók die specifieke source toelaat en je de bridge-IP +> niet wijzigt bij compose-recreate. + +## 2. Firewall doorlaten + +Default UFW-policy is `deny incoming`. Voeg een regel toe voor het docker-subnet: + +```bash +sudo ufw allow from 172.18.0.0/16 to any port 3099 proto tcp comment 'ops-agent' +``` + +Zonder deze regel droppen kernel-iptables packets vanaf de container, **ook al +luistert de agent op 0.0.0.0**. Symptoom: vanuit de container TCP-timeout naar +`172.18.0.1:3099` terwijl L3 ping wel werkt. + +> Zorg dat poort 3099 níét in je perimeter-firewall (cloud-firewall, externe +> router) open staat — de UFW-rule scoped al op het docker-subnet, maar als de +> agent op `0.0.0.0` bindt en je perimeter het toestaat, is hij vanaf het hele +> internet bereikbaar (al beschermd door HMAC-secret). + +## 3. Sync shared secret met dashboard + +`setup.sh` genereert `/etc/ops-agent/secret` met een random waarde. De +ops-dashboard heeft die waarde nodig in `.env` als `OPS_AGENT_SECRET`. Twee +paden: + +**A. Overneem wat setup.sh genereerde** (eenvoudig, sterk): + +```bash +sudo cat /etc/ops-agent/secret # noteer +# vul in: OPS_AGENT_SECRET= in /srv/.../ops-dashboard/.env +``` + +**B. Forceer een eigen waarde** (handig als je hem al in `.env` had staan): + +```bash +SECRET=$(grep '^OPS_AGENT_SECRET=' /srv/scrum4me/ops-dashboard/.env | cut -d= -f2- | tr -d '"') +printf '%s' "$SECRET" | sudo tee /etc/ops-agent/secret >/dev/null +sudo chown root:ops-agent /etc/ops-agent/secret +sudo chmod 0640 /etc/ops-agent/secret +sudo systemctl restart ops-agent +``` + +## 4. Update dashboard .env + restart + +```bash +# in /srv/.../ops-dashboard/.env +OPS_AGENT_URL=http://172.18.0.1:3099 +``` + +En herstart de container: + +```bash +cd /srv/scrum4me/compose +docker compose up -d --force-recreate ops-dashboard +``` + +## Verificatie + +```bash +# Vanaf host (HMAC ontbreekt, dus 401 = OK) +curl -sI http://172.18.0.1:3099/ | head -2 +# HTTP/1.1 401 Unauthorized + +# Vanaf container (zelfde verwachting) +docker exec scrum4me-ops-dashboard sh -c 'wget -qO- --timeout=3 -S http://172.18.0.1:3099/ 2>&1 | head -2' + +# UI smoke-test — open https:///docker +# zou container-tabel renderen zonder "agent 502: fetch failed" +``` + +## Symptomen-tabel + +| Symptoom in dashboard | Oorzaak | Stap | +|---|---|---| +| `fetch failed` op elke module-page | Container kan agent niet bereiken | 1 of 2 | +| `agent 502 Unauthorized` met HMAC-error in agent-logs | Secret-mismatch | 3 | +| Module-pagina rendert maar lege/oude data | OPS_AGENT_URL onbereikbaar of cache | 4 | + +Logs: +- agent: `journalctl -u ops-agent -f` +- dashboard: `docker logs -f scrum4me-ops-dashboard`