Review of the anti-probing hardening found no code defects; the fixes
are documentation:
- docs/security.md: authoritative threat model, the three camouflage
layers, unknown-SNI certificate fallback rules (whitelist source,
error surfacing, capability propagation, concrete first entry), the
client_hello fingerprint knob, rejected directions (QUIC, h2) with
evidence, and residual accepted signals.
- Promote the plan doc to a non-authoritative historical record per
AGENTS.md docs rules; index security.md from docs/README.md and
ARCHITECTURE.md.
- config/sowerd.toml: document cert.domains; the first entry answers
unknown-SNI handshakes.
A handshake failure on unknown SNI is an active-probing signal: real
sites present their default vhost certificate. Whitelisted names keep
the plain autocert path with errors surfaced as-is; unknown or empty
SNI falls back to the primary domain's certificate, carrying the
client hello over so autocert derives the same ECDSA/RSA cache key.
The h2-on-fallback companion idea was investigated and rejected:
httputil.ReverseProxy has no RFC 8441 support and x/net gates
extended CONNECT behind GODEBUG only, which would break WingGate WSS.
ARCHITECTURE.md and README.md now describe editable config fields,
in-place restart, rule hit/miss stats, and session persistence; the
admin console plan is marked implemented.
- StateStore persists rule deltas and whitelisted config overrides atomically
- Config display/edit API with optimistic concurrency (revision)
- Traffic charts with time-axis linking across all views
- Split server.go into auth/rules/traffic/config by responsibility
- internal/admin: session-cookie auth server, rule CRUD API, bounded
per-domain traffic stats with pre-parse byte accounting
- cmd/sower: wrap proxied connections and DNS queries into stats, serve the
admin console on its own listener
- web/: Svelte 5 + Vite admin console with shadcn-svelte UI and an advanced
breadcrumb header (section/context dropdowns, favorites), embedded via
go:embed and committed to web/dist
- Makefile: sower build depends on the frontend build (bun); sowerd does not
- docs: ARCHITECTURE, README, and plan updated for the admin surface