fix(cli): complete proxy bypass lists + warn before clobbering a proxy/PAC#113
Merged
Conversation
Re-applies a fix that was orphaned off PR #111 before its merge (the env-aware home_dir landed on the branch after the merge commit, so staging never got it). dirs::home_dir() resolves via the known-folder OS API on Windows and ignores the environment, so `~` expansion (default bundle_dir, config/device-id paths, bootstrap init dir) escaped both HOME and SOTH_HOME_DIR — the recurring start_forwards_allow_daemon_child_fallback_flag failure on the native Windows lane ("Bundle directory C:\Users\runneradmin\... missing"). Add an env-aware home_dir() that prefers a non-empty $HOME and falls back to dirs::home_dir(); route cli_config's path helpers and the command-graph bootstrap dir through it. Also fixes home-relocation via $HOME on Windows in the product, not just tests. Unchanged where HOME is unset (normal Windows) or equals the profile dir (Unix). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…y/PAC Tier 1.4/1.5/1.1/1.2 of the network-robustness audit (docs/common/2026-07-04/network-robustness-hardening-plan.md). Fixes OS-integration cases where soth silently broke connectivity. Bypass completeness (1.4/1.5): - Add link-local (169.254.*), CGNAT 100.64.0.0/10 — Tailscale's whole range incl. MagicDNS 100.100.100.100 and *.ts.net — and IPv6 private (fc00::/7, fe80::/10) to PROXY_BYPASS_DOMAINS. Previously only ::1 was bypassed for v6, and tailnet/overlay traffic routed through soth. - Derive the Linux no_proxy / KDE NoProxyFor and the Windows ProxyOverride from that single source instead of hardcoded subsets. This fixes two silent breakages: Linux env-var no_proxy omitted all RFC1918 (curl/pip/npm/apt proxied LAN + internal-registry traffic), and the Windows ProxyOverride omitted the entire captive-portal allow-list (NCSI probes + hotel/airport login pages went through soth, whose CA isn't trusted pre-login, and failed). Pre-existing proxy / PAC detection (1.1/1.2): - Before overwriting the OS proxy, detect_conflicting_proxy checks for a manual proxy pointing somewhere other than our loopback, or a PAC / auto-config URL (macOS -getautoproxyurl, GNOME mode=auto, Windows AutoConfigURL). On corp/managed networks where the only egress is that proxy, silently replacing it with soth (which dials direct) takes the user fully offline while status reports healthy. We warn loudly and log rather than clobber silently. Full upstream-proxy chaining is a follow-up; this is the audit's stated minimum. Best-effort throughout: any probe error resolves to "no conflict" so a failed read never blocks `soth on`. 119 soth-cli unit tests pass (new coverage: bypass list contains the private/link-local/CGNAT/v6/captive entries; joined form keeps RFC1918 + captive in sync). Windows/Linux cfg paths compile+run via the release-ci test-windows lane. Co-Authored-By: Claude Fable 5 <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.
Summary
Tier 1.4/1.5/1.1/1.2 of the network-robustness audit (
docs/common/2026-07-04/network-robustness-hardening-plan.md). Fixes OS-integration cases where soth silently broke connectivity. Companion: soth-mitm#71 (DNS fail-open, Tier 1.3).Bypass completeness (1.4 / 1.5)
PROXY_BYPASS_DOMAINS: link-local169.254.*, CGNAT100.64.0.0/10(Tailscale's whole range incl. MagicDNS100.100.100.100and*.ts.net), and IPv6 privatefc00::/7+fe80::/10. Only::1was bypassed for v6 before, so tailnet/overlay/v6-private traffic was being proxied.no_proxy/ KDENoProxyForand the WindowsProxyOverrideare now derived from that single source instead of hardcoded subsets. This fixes two silent breakages:no_proxyomitted all RFC1918 → curl/pip/npm/apt proxied LAN + internal-registry traffic through soth.ProxyOverrideomitted the entire captive-portal allow-list → NCSI probes and hotel/airport login pages went through soth (whose CA isn't trusted pre-login) and failed.Pre-existing proxy / PAC detection (1.1 / 1.2)
Before overwriting the OS proxy,
detect_conflicting_proxychecks for a manual proxy pointing somewhere other than our loopback, or a PAC/auto-config URL (macOS-getautoproxyurl, GNOMEmode=auto, WindowsAutoConfigURL). On corp/managed networks where the only egress is that proxy, silently replacing it with soth (which dials direct) takes the user fully offline whilesoth statusreports healthy. We now warn loudly and log rather than clobber silently. Full upstream-proxy chaining is a follow-up; this is the audit's stated minimum.Best-effort throughout: any probe read error resolves to "no conflict" so it never blocks
soth on.Testing
119 soth-cli unit tests pass, with new coverage: the bypass list contains the private/link-local/CGNAT/v6/captive entries, and the joined (Linux/Windows) form keeps RFC1918 + captive in sync. Windows/Linux cfg paths compile+run via the
release-citest-windowslane.Note
Includes one commit re-applying the env-aware
home_dir()fix that was orphaned off PR #111 before its merge (staging never got it, so the Windows test lane fails without it). It'll reconcile cleanly if #112 (which also carries it) merges first.🤖 Generated with Claude Code