Skip to content

Gate host-proxy inheritance in the macOS datapath behind an explicit flag #315

@AprilNEA

Description

@AprilNEA

Summary

The macOS datapath now implicitly inherits the host's system proxy for all VM TCP egress whenever one is detected at startup, with no config knob to opt out. This was effectively dormant before the splicetcp extraction and is now live (and broadened). Filing to decide whether the auto-inherit should stay the default, or be gated behind an explicit flag.

Current behavior

On datapath startup, proxy inheritance is wired unconditionally:

// virt/arcbox-net/src/darwin/datapath_loop.rs:212-213
let proxy_env = ProxyEnvironment::detect();
tcp_bridge.set_proxy_awareness(dns_log.clone(), proxy_env);
  • ProxyEnvironment::detect() (common/arcbox-fakeip/src/proxy_detect.rs:50) shells out to scutil --proxy, reads HTTP_PROXY/HTTPS_PROXY env vars, and probes 198.18.0.0/15 fake-ip utuns.
  • DefaultEgress::resolve_proxy_target() (common/splicetcp/src/egress.rs:74): once has_usable_proxy() is true (any of http/https/socks configured), every guest destination is tunnelled through that proxy (SOCKS5 > HTTPS CONNECT > HTTP CONNECT). Direct connect only when no proxy is configured or the destination matches the bypass list.

Why this is worth a decision

  1. Dormant → live, and broadened. The recent resolve_proxy_target fix (None => dst_ip.to_string() fallback, refactor(net): extract the proxy data plane into reusable crates + host-tunnel endpoint #311) means IP literals and DNS-log misses are now also routed through the host proxy, not just Fake-IP domains. So once the host has any system proxy configured, essentially all VM TCP egress is taken over by it.
  2. Implicit, no off-switch, point-in-time snapshot.
    • No config knob — purely driven by detect() at startup.
    • If the host toggles its proxy after the datapath starts, the VM won't follow until restart.
    • If the host proxy dies, VM egress breaks with it.
    • Anyone wanting VM-independent / direct egress (testing, or not wanting VM traffic to leak through a personal VPN) has no way to disable it.

This is a behavioral note, not a bug — for the "VM should egress like the host" model it's usually desirable. The question is whether it should be automatic and unconditional.

Proposed gate (small)

The seam already exists. set_dns_log() (common/splicetcp/src/tcp_bridge.rs:1155) lets us keep DNS domain recovery for logging/FlowMeta without installing the proxy-routing DefaultEgress. So the gate is ~the 4 lines at the call site:

if cfg.inherit_host_proxy {                       // new flag
    let proxy_env = ProxyEnvironment::detect();
    tcp_bridge.set_proxy_awareness(dns_log.clone(), proxy_env);
} else {
    tcp_bridge.set_dns_log(dns_log.clone());      // proxy routing off, domain recovery kept
}

Flag source: env var (ARCBOX_INHERIT_HOST_PROXY, quickest), a cfg field threaded into run() (cleaner), or both (env overrides config).

Semantics, pick one:

  • Default ON / opt-out — preserves current behavior, just adds a disable switch. No release note needed. (recommended)
  • Default OFF / opt-in — zero-surprise, but changes the current default; needs a release note.

Not an Aroxy blocker

For the record: Aroxy injects its own egress via set_egress_resolver (RouterEgress + set_dns_log) and never touches DefaultEgress, so host-proxy inheritance is entirely bypassed there. This is purely an arcbox VM-datapath default-policy concern.

Decision needed

  • (a) Keep auto-inherit as the default, document it, no code change.
  • (b) Add an opt-out flag (default ON), set_dns_log fallback when disabled.
  • (c) Switch to opt-in (default OFF) + release note.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions