Codex 一直 Reconnecting?排查 DNS 污染与 Clash 配置
Codex 出现 Reconnecting...、stream disconnected before completion 和 error sending request 等错误时,可能涉及 DNS 干扰或 Clash 路由不正确。本文说明如何调查这种可能性、应用一项有针对性的 Clash Verge Rev 增强,并验证结果。
社区报告实际显示了什么
Reddit 用户报告过面向 chatgpt.com/backend-api/codex/responses 的任务被中断、反复尝试重新连接以及响应体错误。这些报告说明的是症状,而不是 DNS 诊断结论。请求中断,重连循环
另一则讨论描述了远程上下文压缩期间的失败。一位评论者建议调查代理,但该讨论并未确认经过验证的原因。压缩讨论
X 上的报告也提出了类似问题:9 月 9 日的一则帖子描述了持续的流失败,而 9 月 6 日的一则帖子报告了远程压缩期间的 SSE 空闲超时。两者都没有提供 DNS 对比。这些是有用的用户问题示例,但不能据此认定存在共同原因。X 流报告,X 压缩报告
| 症状 | 需要调查的内容 |
|---|---|
| 立即超时并带有解析器错误 | DNS、节点可达性,以及流量是否进入 Clash |
| ChatGPT 在浏览器中可用但 Codex 失败 | 代理、DNS、证书和出口的差异 |
| 输出已开始,然后流断开 | 长连接、网络变化和服务错误 |
| 只有长对话或压缩失败 | 与一个新的小任务对比;调查会话和服务器错误 |
| HTTP 401、403、429 或 5xx | 检查响应来源和响应体,确认是否为身份验证、策略、限制或服务故障 |
检查 OpenAI 服务状态,并记录时间和客户端版本。对于卡住的聊天,OpenAI 还建议检查是否有待处理的批准,并尝试一个更小、更聚焦的新聊天。桌面版和 CLI 版本可能不同。官方故障排查
一个本地案例:意外的 DNS 应答触发了 DIRECT
在一份使用 Clash Verge Rev 和 Mihomo 的 macOS 调查记录中,代理节点可以访问,但 chatgpt.com 命中了 GeoIP/CN 规则,并尝试直接连接,结果发生超时。与通过代理访问的加密 DNS 进行对比后发现,本地解析路径上的应答存在异常。
Request to chatgpt.com
→ anomalous DNS answer
→ no earlier matching OpenAI domain rule
→ GeoIP selects DIRECT
→ connection times out and Codex retries
这里有两个配置问题需要处理:解析路径和路由决策。这个记录案例不是基准,也不能证明其他 Codex 故障具有相同原因。仅凭异常应答本身,也无法识别应负责的中间方,或特别地认定为 DNS 缓存投毒。
在更改配置前先进行诊断
检查连接日志
搜索错误中的实际主机名,包括 chatgpt.com 或 openai.com。记录故障发生时匹配到的规则、连接链和错误。若本应使用代理的连接却选择了 DIRECT,则有必要检查规则顺序。Mihomo 按自上而下的顺序评估路由规则。路由文档
如果没有出现匹配的连接,先确认该客户端是否使用了 Clash。浏览器可用并不能证明另一个独立进程所使用的路径。
对比解析路径
在 macOS 上,检查系统解析器及其当前应答:
scutil --dns
dscacheutil -q host -a name chatgpt.com
如需进行加密对比,请将 7890 替换为你的 Clash HTTP/mixed 端口:
curl --noproxy '' --proxy http://127.0.0.1:7890 \
--connect-timeout 10 --max-time 20 \
-H 'accept: application/dns-json' \
'https://1.1.1.1/dns-query?name=chatgpt.com&type=A'
该请求使用 Cloudflare 的 DNS JSON 接口。检查连接面板:显式本地代理可以保证流量进入 Clash,但最终出口仍由 Clash 规则决定。
仅凭 IP 地址不同,并不能证明存在干扰。CDN 选择、缓存、地址族以及 Fake-IP 都可能解释这种差异。来自 Clash 的 Fake-IP 范围的合成地址并不天然可疑。应将异常应答与错误路由及故障相互关联,然后再与另一条已验证的网络路径进行对比。启用 TUN 后,即使是 dig @resolver 也可能被拦截;它并不会自动成为独立的上游测试。
应用一项有针对性的 Clash Verge Rev 增强
此模板要求使用带 Mihomo 的 Clash Verge Rev、已有订阅以及可正常工作的代理节点。它是一个订阅 Script,不是完整的独立配置文件。请先备份当前配置。如果你已经在使用脚本,请将变更集成到现有的 main(config) 函数中。在所有增强步骤完成后,检查最终的运行时配置。Clash Verge Rev Script 文档
将 CODEX_PROXY_GROUP 设置为一个现有分组,并在该分组中选择一个可用的代理节点。将 NODE_DNS 设置为一个在代理建立连接之前即可工作的 DoH 解析器,并且它能够正确解析节点主机名。AliDNS 示例用于在中国大陆网络环境中进行验证;如果不合适,请替换。它不会用于解析下方的 AI 域名。
// Clash Verge Rev subscription Script. Use with an existing Mihomo profile.
// Replace this with the exact name of a working proxy group in that profile.
const CODEX_PROXY_GROUP = "REPLACE_WITH_EXISTING_PROXY_GROUP";
// Example bootstrap resolver for a mainland-China network. Verify reachability
// and node-hostname answers on your network, or replace with your trusted DoH.
// It must work BEFORE the proxy is established. It does not resolve AI domains.
const NODE_DNS = ["https://223.5.5.5/dns-query#DIRECT"];
function main(config) {
const groups = config["proxy-groups"] || [];
if (!groups.some((group) => group.name === CODEX_PROXY_GROUP)) {
throw new Error("Set CODEX_PROXY_GROUP to an existing working proxy group.");
}
if (/[#&,\r\n]/.test(CODEX_PROXY_GROUP)) {
throw new Error("Use a proxy group name without #, &, commas or newlines.");
}
const domains = ["chatgpt.com", "openai.com", "oaistatic.com", "oaiusercontent.com"];
const doh = [
"https://1.1.1.1/dns-query#" + CODEX_PROXY_GROUP,
"https://8.8.8.8/dns-query#" + CODEX_PROXY_GROUP,
];
const dns = config.dns || {};
const policy = Object.assign({}, dns["nameserver-policy"] || {});
domains.forEach((domain) => { policy["+." + domain] = doh.slice(); });
dns.enable = true;
dns["nameserver-policy"] = policy;
dns["proxy-server-nameserver"] = NODE_DNS.slice();
if (!Array.isArray(dns.nameserver) || dns.nameserver.length === 0) {
dns.nameserver = NODE_DNS.slice();
}
config.dns = dns;
const oldRules = Array.isArray(config.rules) ? config.rules : [];
const aiRules = domains.map((domain) =>
"DOMAIN-SUFFIX," + domain + "," + CODEX_PROXY_GROUP
);
config.rules = aiRules.concat(oldRules.filter((rule) => !aiRules.includes(rule)));
return config;
}
该脚本会添加按域名划分的 DNS 策略,并将代理规则前置,同时保留其他规则和域名策略。它会更改节点主机名解析。这 4 个域名后缀只是起始范围,并非涵盖所有 Codex 功能、自定义提供方、MCP 服务或任务下载的完整列表。
Mihomo 支持按域名划分的 nameserver-policy,以及在 DNS 服务器地址上显式指定代理后缀。节点解析需要一条独立路径,以避免循环依赖。DNS 配置参考
该定向脚本会保留现有的 fallback 设置。在替换它们之前,请先单独审查更广泛的 DNS 依赖关系。同时检查是否存在陈旧的 hosts 映射,或冲突的、更具体的策略。
单独检查 TUN
对于不使用系统代理的进程,请在 Clash Verge Rev 中启用 TUN,并确认其正在运行。将以下字段合并到你现有的 TUN 对象中,同时保留其其他设置:
tun:
enable: true
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
这些规则涵盖了 53 端口上的 UDP 和 TCP DNS。Mihomo 记录了 macOS 和 Windows 上面向局域网的 DNS 限制;由应用自行管理的加密 DNS 也不受这些 53 端口规则控制。请验证解析器和接口行为,而不要假定这个开关覆盖了每一个请求。TUN 参考
分别验证配置、路由和 Codex
首先检查最终配置中的错误、分组引用和规则顺序。如果 Mihomo CLI 可用,mihomo -t -f <final-config-path> 可检查配置能否被解析。但这不能证明连通性。
接下来检查实际连接路由,并通过你真实的本地端口执行一次带证书校验的 HTTPS 探测:
curl --noproxy '' --proxy http://127.0.0.1:7890 \
--connect-timeout 10 --max-time 20 \
-o /dev/null -sS \
-w 'HTTP=%{http_code} TLS=%{time_appconnect}s TOTAL=%{time_total}s\n' \
https://chatgpt.com/
如果在证书验证成功后收到了目标服务的响应,则说明此次探测已建立 HTTP 交互。401 或 403 仍可能阻止访问。这并不能证明经过认证的 Codex 请求能够正常工作,而且如果禁用证书校验,此检查将失效。
最后,在最初失败的客户端中完成一个小任务。已安装并完成认证的 CLI 可以运行以下可选检查;它会发起一次真实的模型请求,并消耗账户配额:
codex exec --skip-git-repo-check --sandbox read-only \
'Reply with exactly: PONG. Do not use tools.'
CLI 成功只验证该次 CLI 请求;如果失败发生在桌面应用中,请单独测试桌面应用。在订阅更新、网络切换以及睡眠/唤醒之后,请重新检查。后续配置层或被重命名的分组仍可能破坏某项增强。
常见问题
仅将系统 DNS 改为 8.8.8.8 就够了吗?
不一定。仅有解析器地址本身并不能建立加密、代理路由或可达性。请一并验证解析器、传输方式和出口路径。
为什么在 Clash 运行时 Codex 仍然失败?
该进程可能绕过代理、匹配到直连规则,或依赖不可用的节点 DNS。问题也可能与 DNS 无关。在同时更改多项设置之前,先找出实际使用的连接路径。
如果它仍然断开连接怎么办?
如果 DNS、TLS 和路由均工作正常,请排查服务状态、会话大小、客户端版本、节点连接稳定性以及精确的错误响应内容。OpenAI 提供了反馈和日志位置说明;在分享日志之前,请先检查其中是否包含敏感信息。故障排查与日志
如何撤销更改?
禁用新增的 Script,并恢复已备份的配置文件、TUN 设置以及你更改过的任何系统 DNS 设置。后续可以使用独立的 proxy-providers 架构,将节点订阅与本地 DNS 和规则隔离开来,但这并不是这个定向修复所必需的。
安装和导入步骤请参见Clash Verge 设置。其他故障请参见Clash 故障排查。你可以使用现有的兼容订阅来执行这一诊断流程;测试 DNS 并不以前提是购买另一项服务。