Add opt-in transparent TCP routing for Linux sandboxes (#61372)

## Why

Native TCP clients need to reach managed network destinations without implementing proxy support themselves.

## What changed

- Add `--transparent-tcp` to the Linux sandbox command, using a bundled TCP stack, private TUN interface, and DNS stub to route native IPv4 and IPv6 connections through the attributed managed SOCKS proxy.
- Preserve original hostnames for proxy policy checks and cancel pending approval connections when their native sockets close.
- Expose `--linux-sandbox-transparent-tcp` and `--tcp-upstream-proxy` on `codex exec-server` for transparent routing and a mandatory HTTP CONNECT next hop without direct fallback.
- Require private network and PID namespaces, private procfs, system `bwrap`, and access to `/dev/net/tun`; reject incompatible launcher options and untrusted proxy ports.

## Testing

Add integration coverage for native hostname and IPv6 connections, SOCKS attribution, pending connection cancellation, policy denials, and filesystem and host-loopback isolation. Extend launcher and executor tests for option validation and managed-policy propagation.

GitOrigin-RevId: 96bd7726e5369efceb65320face56aa85ae3deb8
This commit is contained in:
viyatb-oai
2026-11-13 20:24:37 +00:00
committed by copyberry
parent 9e48702b3a
commit 7194b21776
40 changed files with 1637 additions and 188 deletions
+10
View File
@@ -41,6 +41,14 @@ pub struct ExecServerCommand {
#[arg(long, value_name = "MODE", default_value = "isolate", global = true)]
linux_sandbox_pid_namespace: codex_sandboxing::LinuxSandboxPidNamespace,
/// Route managed Linux sandbox TCP through the SOCKS proxy.
#[arg(long, global = true)]
linux_sandbox_transparent_tcp: bool,
/// Require this HTTP CONNECT proxy for raw TCP from the managed SOCKS listener.
#[arg(long, value_name = "HOST:PORT", global = true)]
tcp_upstream_proxy: Option<codex_exec_server::TcpUpstreamProxy>,
/// Allow permitted private IP destinations to use the configured upstream proxy.
/// If no valid upstream proxy applies to the request protocol, connect directly.
/// Loopback stays local. This flag does not require upstream routing.
@@ -203,7 +211,9 @@ impl ExecServerCommand {
arg0_paths.codex_linux_sandbox_exe.clone(),
)?
.with_linux_sandbox_pid_namespace(self.linux_sandbox_pid_namespace)
.with_linux_sandbox_transparent_tcp(self.linux_sandbox_transparent_tcp)
.with_proxy_private_ips_via_upstream(self.proxy_private_ips_via_upstream);
runtime_paths.tcp_upstream_proxy = self.tcp_upstream_proxy.take();
// Config loading below owns error handling (non-strict stdio can proceed
// without config). Never retain other startup flags in the executor.
if let Ok(overrides) = root_config_overrides.parse_overrides() {
@@ -1,6 +1,6 @@
---
source: exec-server-cli/src/exec_server_args_tests.rs
assertion_line: 318
assertion_line: 338
expression: help
---
[EXPERIMENTAL] Run the standalone exec-server service
@@ -33,6 +33,13 @@ Options:
[default: isolate]
--linux-sandbox-transparent-tcp
Route managed Linux sandbox TCP through the SOCKS proxy
--tcp-upstream-proxy <HOST:PORT>
Require this HTTP CONNECT proxy for raw TCP from the managed SOCKS
listener
--proxy-private-ips-via-upstream
Allow permitted private IP destinations to use the configured upstream
proxy. If no valid upstream proxy applies to the request protocol,