rebreak-monorepo/ops/mdm/adguard-handshake-watcher/rebreak-handshake-watcher.service
chahinebrini db7875fb34 feat(ops/mdm): AdGuard ClientID handshake — nginx + watcher
End-to-end DoH-to-backend wiring for Mac auto-activation:

  Mac → dns.rebreak.org/dns-query/<token> → nginx → AdGuard
  → querylog.json (CP field) → watcher.py → POST /handshake → backend

- ops/nginx/dns.rebreak.org.conf: vhost with `location ^~ /dns-query`
  prefix-match (not exact). proxy_pass without trailing slash preserves
  the full path so AdGuard parses the ClientID natively.
- watcher.py: NDJSON tail with inode-based rotation safety, per-token
  60s in-memory cooldown, urllib (no external deps), graceful 401/404/5xx
- rebreak-handshake-watcher.service: systemd unit, EnvironmentFile with
  chmod 600 (HANDSHAKE_SECRET never in git), NoNewPrivileges + PrivateTmp
- DOH_CLIENTID_HANDSHAKE.md: architecture + flow diagram + risk table
- RUNBOOK.md: status/logs/restart commands + deploy ordering

Not yet deployed. Verify-checklist before `nginx -s reload`:
  1. confirm AdGuard DoH port (config assumes 127.0.0.1:3000)
  2. confirm TLS cert exists for dns.rebreak.org
  3. snapshot current nginx config
  4. `nginx -t` dry-run
  5. functional curl + grep CP in querylog before starting watcher
2026-05-15 22:41:38 +02:00

43 lines
1.4 KiB
Desktop File

[Unit]
Description=ReBreak AdGuard Handshake Watcher
Documentation=https://github.com/chahinebrini/rebreak-monorepo
# Start after network and AdGuard's docker container are up.
After=network-online.target docker.service
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/rebreak-handshake-watcher
# ── Secrets via Infisical ────────────────────────────────────────────────────
# HANDSHAKE_SECRET must be injected at runtime.
# On this server, load it from Infisical via a wrapper or
# write it into /etc/rebreak-handshake-watcher.env (chmod 600, root only)
# during deploy. The .env file is gitignored — never committed.
#
# Format of /etc/rebreak-handshake-watcher.env:
# HANDSHAKE_SECRET=<32hex from Infisical>
# BACKEND_URL=https://staging.rebreak.org
# QUERYLOG_PATH=/opt/adguardhome/data/querylog.json
#
EnvironmentFile=/etc/rebreak-handshake-watcher.env
ExecStart=/usr/bin/python3 /opt/rebreak-handshake-watcher/watcher.py
# Restart on any exit (crash, SIGKILL, etc.) after 5s
Restart=always
RestartSec=5s
# Logging goes to journald automatically (no extra config needed)
StandardOutput=journal
StandardError=journal
SyslogIdentifier=rebreak-handshake-watcher
# Harden: no new privileges, read-only filesystem except for runtime state
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target