Codex 源码解析 · 第 27 讲
Codex 源码解析系列 第 27 讲:Network Proxy 网络代理引擎——域名白名单与凭据经纪 基于 OpenAI Codex 源码 · 2026-10-21 💡 本讲一句话: Codex 给沙箱里的子进程配了一个"守门员代理"——所有出站流量必须经过它,域名白名单、DNS rebinding 防御、凭据虚拟化注入全在这一层完成;读完你能看懂一个生产级网络策略引擎的完整裁决链路。 一、为什么 Codex 要自己造一个代理 前几讲我们拆了 bwrap、Landlock、Windows 沙箱——它们管的是"进程能碰哪些文件、哪些系统调用"。但网络是另一条逃逸通道:子进程里跑一条 curl http://169.254.169.254/latest/meta-data/ (云元数据服务)或者把 API key POST 到任意第三方,文件沙箱完全拦不住。 Codex 的解法不是"禁止网络",而是 强制所有流量走一个 Codex 自己启动的 loopback 代理 ( codex-rs/network-proxy/ ,约 2.2 万行 Rust)。子进程的环境变量被改写成 HTTP_PROXY=http://127.0.0.1:<port> ,而沙箱层(bwrap/Landlock)只放行这几个 loopback 端口——想绕过代理直连?连接根本建不起来。 这个 crate 的模块清单本身就是一张能力地图: lib.rs (第 3-32 行)声明了 proxy / http_proxy / socks5 / network_policy / credential_broker / mitm / environment_policy / request_cancellation 等近 30 个模块——HTTP/1.1 代理、SOCKS5、域名策略、凭据经纪、MITM 头注入、请求取消,一个都不少。 先看子进程启动时环境是怎么被"接管"的—— proxy.rs 的 prepare_for_addrs() : 📄 codex-rs/network-proxy/src/proxy.rs (第 1051-1110 行) let runtime_settings = self.runtime_settings(); // 读取当前运行时设置快照(本地绑定开关、MITM CA 路径等) apply_proxy_env_overrides( // 把子进程环境里的 HTTP_PROXY/ALL_PROXY 等一律改写指向本 loopback 代理——用户设什么都被覆盖 &mut env, // 正在为子进程准备的环境变量表(原地修改) addrs.http_addr, // HTTP 代理地址(loopback:port) addrs.socks_addr, // SOCKS5 代理地址(若启用) self.socks_enabled, // 是否写入 socks 相关变量 runtime_settings.allow_local_binding, // 本地绑定开关——影响 NO_PROXY 的生成策略 runtime_settings.mitm_ca_trust_bundle.as_ref(), // MITM 开启时把子进程 CA 信任链指向 Codex 托管证书 ); let credential_environment_id = environment_id.or_else(|| { // 优先用调用方指定的环境 id,没有就退回本次执行作用域 self.execution_scope // 当前执行作用域(可能为 None) .as_ref() .map(|scope| scope.environment_id.as_str()) // 从作用域里取出环境 id }); self.state .virtualize_child_credentials_for_environment(&mut env, credential_environment_id); // 把子进程环境里的真实凭据换成假值——请求时由代理注回真值 if let Some(execut…
阅读全文:Codex 源码解析 第 27 讲