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:
@@ -451,7 +451,13 @@ func GenerateSandboxProfile(params MacOSSandboxParams) string {
|
||||
(global-name "com.apple.system.logger")
|
||||
(global-name "com.apple.system.notification_center")
|
||||
(global-name "com.apple.trustd.agent")
|
||||
(global-name "com.apple.system.opendirectoryd.libinfo")
|
||||
`)
|
||||
// macOS DNS resolution goes through mDNSResponder via Mach IPC — blocking
|
||||
// opendirectoryd.libinfo or configd does NOT cause a fallback to direct UDP
|
||||
// DNS. getaddrinfo() simply fails with EAI_NONAME. So we must allow these
|
||||
// services in all modes. In daemon mode, DNS for proxy-aware apps (curl, git)
|
||||
// is handled via ALL_PROXY=socks5h:// env var instead.
|
||||
profile.WriteString(` (global-name "com.apple.system.opendirectoryd.libinfo")
|
||||
(global-name "com.apple.system.opendirectoryd.membership")
|
||||
(global-name "com.apple.bsd.dirhelper")
|
||||
(global-name "com.apple.securityd.xpc")
|
||||
@@ -733,19 +739,27 @@ func WrapCommandMacOS(cfg *config.Config, command string, exposedPorts []int, da
|
||||
|
||||
if daemonMode {
|
||||
// In daemon mode: run as the real user but with EGID=_greywall via sudo.
|
||||
// pf routes all traffic from group _greywall through utun → tun2socks → proxy.
|
||||
// pf routes all TCP from group _greywall through utun → tun2socks → proxy.
|
||||
// Using -u #<uid> preserves the user's identity (home dir, SSH keys, etc.)
|
||||
// while -g _greywall sets the effective GID for pf matching.
|
||||
//
|
||||
// Do NOT inject HTTP_PROXY/HTTPS_PROXY env vars in daemon mode: tun2socks
|
||||
// provides transparent proxying at the IP level, so apps don't need proxy
|
||||
// env vars. Setting them to socks5h:// breaks apps (like Bun/Node.js) that
|
||||
// read HTTP_PROXY but don't support SOCKS5 protocol.
|
||||
// DNS on macOS goes through mDNSResponder (Mach IPC), which runs outside
|
||||
// the _greywall group, so pf can't intercept DNS. Instead, we set
|
||||
// ALL_PROXY=socks5h:// so proxy-aware apps (curl, git, etc.) resolve DNS
|
||||
// through the SOCKS5 proxy. The "h" suffix means "resolve hostname at proxy".
|
||||
//
|
||||
// We only set ALL_PROXY (not HTTP_PROXY/HTTPS_PROXY) because apps like
|
||||
// Bun/Node.js read HTTP_PROXY but don't support SOCKS5 protocol.
|
||||
//
|
||||
// sudo resets the environment, so we use `env` after sudo to re-inject
|
||||
// terminal vars (TERM, COLORTERM, etc.) needed for TUI apps.
|
||||
uid := fmt.Sprintf("#%d", os.Getuid())
|
||||
sandboxEnvs := GenerateProxyEnvVars("")
|
||||
// Convert socks5:// → socks5h:// for hostname resolution through proxy.
|
||||
socks5hURL := strings.Replace(cfg.Network.ProxyURL, "socks5://", "socks5h://", 1)
|
||||
if socks5hURL != "" {
|
||||
sandboxEnvs = append(sandboxEnvs, "ALL_PROXY="+socks5hURL, "all_proxy="+socks5hURL)
|
||||
}
|
||||
termEnvs := getTerminalEnvVars()
|
||||
parts = append(parts, "sudo", "-u", uid, "-g", daemonSession.SandboxGroup, "env")
|
||||
parts = append(parts, sandboxEnvs...)
|
||||
|
||||
Reference in New Issue
Block a user