wgtunnel: v4-pin + re-resolve watchdog; FELHOM_WG Critical flips (S4 agent half)
v4-pin (doc 06 §4.2): renderConf takes a pre-resolved IPv4 literal and writes Endpoint=<ip>:<port> — never the DNS name, never AAAA. Resolver seam (A records only, LookupNetIP "ip4"); multiple A → lowest (deterministic fleet-wide); renderConf stays pure. Resolved IP cached: steady-state Apply = zero DNS + zero execs. DNS failure keeps the last conf (never a teardown). Watchdog (loop-only, so Apply's zero-exec steady state is untouched): handshake age > wg_tunnel.stale_after_seconds (default 180) → re-resolve; IP changed → re-render + restart (endpoint re-IP recovery); IP same → no churn (throttled warn). Staleness read reuses wg show latest-handshakes (never dump). Capability: wg-conf-install/enable/restart/handshake-read flipped Critical=true (backups ride the tunnel from S4); apt-install + disable stay non-critical. TestWGCapabilityCriticality pins the set. Tests + red-proofs a/b/d all fire. No new sudoers grant; no wire/JSON change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -1,3 +1,30 @@
|
||||
## v0.66.0 — S4 agent half: endpoint v4-pin + re-resolve watchdog + FELHOM_WG Critical flips (2026-07-04)
|
||||
|
||||
The two agent items S4 needs before offsite backups ride the tunnel (the tenancy + storage weight is
|
||||
runbook-side). No new sudoers grants; no wire/JSON change.
|
||||
|
||||
- **`internal/wgtunnel` — v4-pin (doc 06 §4.2).** `renderConf` now takes the **pre-resolved IPv4
|
||||
literal** and writes `Endpoint = <ip>:<port>` — never the DNS name, never an AAAA. A new `Resolver`
|
||||
seam (`net.DefaultResolver.LookupNetIP(ctx, "ip4", …)` — A records only) resolves in the Manager;
|
||||
multiple A records → the numerically **lowest** (deterministic fleet-wide). renderConf stays pure
|
||||
(no DNS/IO inside). The resolved IP is cached: **steady-state Apply hits the cache — zero DNS, zero
|
||||
execs** (the load-bearing negative). DNS failure on (re)resolve → keep the last-applied conf + throttled
|
||||
ERROR — **never a teardown** (teardown stays revocation-only).
|
||||
- **`internal/wgtunnel` — re-resolve watchdog (doc 06 §4.2, the slice-3 promise).** New
|
||||
`Manager.Watchdog` (loop-driven only, so Apply's zero-exec steady state is untouched): when the
|
||||
handshake age exceeds `wg_tunnel.stale_after_seconds` (default **180**) it re-resolves; **IP changed
|
||||
→ re-render + restart** (endpoint re-IP recovery); IP unchanged → no churn, one throttled warn
|
||||
(endpoint merely down). The staleness read is the existing `wg show … latest-handshakes` (never
|
||||
`dump`).
|
||||
- **`internal/config`** — `WGTunnelConfig.StaleAfterSeconds` (default 180 via `WithDefaults`).
|
||||
- **`internal/capability` — FELHOM_WG Critical flips (S4).** Backups ride the tunnel now, so
|
||||
`wg-conf-install`, `wg-enable`, `wg-restart`, `wg-handshake-read` are **Critical=true**
|
||||
(operator-alert-worthy on degradation); `wg-tools-install` (one-time) + `wg-disable` (deliberate
|
||||
revocation) stay non-critical. `TestWGCapabilityCriticality` pins the exact set (red-proofed).
|
||||
- Tests: v4-pin golden (A literal, AAAA/dns_name refused), watchdog (healthy=no-DNS negative,
|
||||
stale+re-IP restarts, stale+same-IP no-churn+throttle, resolver-failure keeps conf, initial-resolve-
|
||||
failure no-teardown+recovery). Red-proofs a/b/d all fire.
|
||||
|
||||
## v0.65.0 — S3.1 offsite-tunnel client MTU 1420 → 1280 (resolve the CGNAT-smoke MTU open decision) (2026-07-04)
|
||||
|
||||
One-constant fix closing `06 §4.3`'s OPEN DECISION. The 2026-07-04 CGNAT smoke test found the
|
||||
|
||||
Reference in New Issue
Block a user