feat: DX overhaul — safe dev loop, deterministic VPN check, CI, docs#13
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 (stalevpn.endpoints) made the gap concrete.Mostly wiring existing seams. No new deps (stdlib
flagonly).Phases
validatesubcommand, global-v/--verbose,scripts/*.sh(dev, rules, doctor, install-local, reinstall, uninstall-local, panic), matching Makefile targets,dezhban.dev.json. Kills the copy-paste.print-rules— build-tagged purefirewall.RenderRuleson all 3 OSes; see exact pf/nft/wfp text without applying it.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.doctorreports tunnels/subnets/endpoints;doctor --discovershells out on macOS (scutil/netstat) to find the connected VPN's real server IP — automates this session's manual hunt.vet/teston ubuntu/macos/windows) +build-all; guards the build-tag seam (a missingRenderRulesbreaks a non-host OS build).TROUBLESHOOTING.md), full config reference (CONFIG.md),dezhban.vpn-guard.jsonsample.Verification
go build/go vet/go test(56 pass) /gofmt -l— all cleanvalidate,print-rules,doctorsmoke-tested live🤖 Generated with Claude Code