Skip to content

feat: DX overhaul — safe dev loop, deterministic VPN check, CI, docs#13

Merged
Behnam-RK merged 2 commits into
mainfrom
dx-overhaul
Jun 12, 2026
Merged

feat: DX overhaul — safe dev loop, deterministic VPN check, CI, docs#13
Behnam-RK merged 2 commits into
mainfrom
dx-overhaul

Conversation

@Behnam-RK

Copy link
Copy Markdown
Owner

What & why

Operating and extending dezhban meant copy-pasting diagnostic commands (route get, lsof, tcpdump, scutil) by hand — there was no way to test firewall rules without risking lockout, no config validation, no -v, no CI, no recovery runbook. A real VPN lockout this session (stale vpn.endpoints) made the gap concrete.

Mostly wiring existing seams. No new deps (stdlib flag only).

Phases

  1. Dev loopvalidate subcommand, global -v/--verbose, scripts/*.sh (dev, rules, doctor, install-local, reinstall, uninstall-local, panic), matching Makefile targets, dezhban.dev.json. Kills the copy-paste.
  2. print-rules — build-tagged pure firewall.RenderRules on all 3 OSes; see exact pf/nft/wfp text without applying it.
  3. Deterministic VPN check + doctor — swap the UDP-dial check (false-positives under a full-tunnel default route) for subnet-containment: flag an endpoint only when it sits inside a tunnel's own subnet. doctor reports tunnels/subnets/endpoints; doctor --discover shells out on macOS (scutil/netstat) to find the connected VPN's real server IP — automates this session's manual hunt.
  4. CI — matrix (vet/test on ubuntu/macos/windows) + build-all; guards the build-tag seam (a missing RenderRules breaks a non-host OS build).
  5. Docs — lockout-recovery runbook (TROUBLESHOOTING.md), full config reference (CONFIG.md), dezhban.vpn-guard.json sample.

Verification

  • go build / go vet / go test (56 pass) / gofmt -l — all clean
  • Cross-compiles darwin/linux/windows
  • validate, print-rules, doctor smoke-tested live
  • Endpoint inside a tunnel subnet → flagged MISCONFIGURED; public endpoint → passes even under a full tunnel

🤖 Generated with Claude Code

Behnam-RK and others added 2 commits June 12, 2026 17:58
Operating and extending dezhban meant copy-pasting diagnostic commands by
hand, with no way to test firewall rules without risking lockout and no
config validation. This adds a fast, root-free dev loop and a deterministic
endpoint sanity check that won't cry wolf under a full-tunnel VPN.

- validate / print-rules / doctor subcommands + global -v/--verbose
- build-tagged firewall.RenderRules (pure, exec-free) on all 3 OSes —
  inspect a block/guard ruleset without applying it
- swap UDP-dial endpoint check (false-positives under full-tunnel default
  route) for deterministic subnet-containment; doctor --discover shells out
  on macOS to find the connected VPN's real server IP
- scripts/*.sh (dev, rules, doctor, install-local, reinstall, panic) +
  matching Makefile targets; dev + vpn-guard sample configs
- CI matrix (vet/test on 3 OSes + build-all) guards the build-tag seam
- docs: lockout-recovery runbook + full config reference

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address PR #13 review:

- runner.runVPN now refuses to start (before touching the firewall) when a
  configured vpn.endpoint sits inside a tunnel's own subnet, instead of only
  warning. A warn scrolls past in a service log; the next FULL BLOCK then locks
  the host out — the exact incident that motivated the PR. Read errors stay
  non-fatal (can't classify ≠ misconfigured).
- prefixFromIPNet rejects a mask whose Size() returns (0,0) (non-contiguous /
  unrepresentable) rather than treating it as 0.0.0.0/0, which would make
  Contains match every endpoint and falsely flag them all as tunnel-internal.
- CI: run go test -race once on ubuntu (runner toggles posture from a ticker
  loop with a recovery probe); skipped on windows where -race needs gcc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Behnam-RK Behnam-RK merged commit 334b577 into main Jun 12, 2026
5 checks passed
@Behnam-RK Behnam-RK deleted the dx-overhaul branch June 12, 2026 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant