fix: use socks5h:// for macOS daemon DNS resolution through proxy
macOS getaddrinfo() uses mDNSResponder via Mach IPC and does NOT fall back to direct UDP DNS when those services are blocked — it simply fails with EAI_NONAME. This made DNS resolution fail for all sandboxed processes in daemon mode. Switch to setting ALL_PROXY=socks5h:// env var so proxy-aware apps (curl, git, etc.) resolve hostnames through the SOCKS5 proxy. The "h" suffix means "resolve hostname at proxy side". Only ALL_PROXY is set (not HTTP_PROXY) to avoid breaking apps like Bun/Node.js. Other changes: - Revert opendirectoryd.libinfo and configd mach service blocks - Exclude loopback (127.0.0.0/8) from pf TCP route-to to prevent double-proxying when ALL_PROXY connects directly to local proxy - Always create DNS relay with default upstream (127.0.0.1:42053) - Use always-on logging in DNS relay (not debug-only) - Force IPv4 (udp4) for DNS relay upstream connections - Log tunnel cleanup errors instead of silently discarding them
This commit is contained in:
@@ -15,10 +15,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tunIP = "198.18.0.1"
|
||||
dnsRelayIP = "127.0.0.2"
|
||||
dnsRelayPort = "15353" // high port to avoid conflicts with system DNS (mDNSResponder, Docker/Lima)
|
||||
pfAnchorName = "co.greyhaven.greywall"
|
||||
tunIP = "198.18.0.1"
|
||||
dnsRelayIP = "127.0.0.2"
|
||||
dnsRelayPort = "15353" // high port; pf rdr rewrites port 53 → this port
|
||||
defaultDNSTarget = "127.0.0.1:42053" // proxy's DNS resolver (UDP), used when dnsAddr is not configured
|
||||
pfAnchorName = "co.greyhaven.greywall"
|
||||
|
||||
// tun2socksStopGracePeriod is the time to wait for tun2socks to exit
|
||||
// after SIGTERM before sending SIGKILL.
|
||||
@@ -158,19 +159,15 @@ func (t *TunManager) LoadPFRules(sandboxGroup string) error {
|
||||
return fmt.Errorf("failed to ensure pf anchor: %w", err)
|
||||
}
|
||||
|
||||
// Build the anchor rules. pf requires strict ordering:
|
||||
// translation (rdr) before filtering (pass).
|
||||
// Note: macOS pf does not support "group" in rdr rules, so DNS
|
||||
// redirection uses a two-step approach:
|
||||
// 1. rdr on lo0 — redirects DNS arriving on loopback to our relay
|
||||
// 2. pass out route-to lo0 — sends sandbox group's DNS to loopback
|
||||
// 3. pass out route-to utun — sends sandbox group's TCP through tunnel
|
||||
// Build pf anchor rules for the sandbox group:
|
||||
// 1. Route all non-loopback TCP through the utun → tun2socks → SOCKS proxy.
|
||||
// Loopback (127.0.0.0/8) is excluded so that ALL_PROXY=socks5h://
|
||||
// connections to the local proxy don't get double-proxied.
|
||||
// 2. (DNS is handled via ALL_PROXY=socks5h:// env var, not via pf,
|
||||
// because macOS getaddrinfo uses mDNSResponder via Mach IPC and
|
||||
// blocking those services doesn't cause a UDP DNS fallback.)
|
||||
rules := fmt.Sprintf(
|
||||
"rdr on lo0 proto udp from any to any port 53 -> %s port %s\n"+
|
||||
"pass out on !lo0 route-to (lo0 127.0.0.1) proto udp from any to any port 53 group %s\n"+
|
||||
"pass out route-to (%s %s) proto tcp from any to any group %s\n",
|
||||
dnsRelayIP, dnsRelayPort,
|
||||
sandboxGroup,
|
||||
"pass out route-to (%s %s) proto tcp from any to !127.0.0.0/8 group %s\n",
|
||||
t.tunDevice, tunIP, sandboxGroup,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user