差别
这里会显示出您选择的修订版和当前版本之间的差别。
| tmpcodexcheck [2026/10/23 17:37] – 创建 - 外部编辑 127.0.0.1 | tmpcodexcheck [2026/10/24 00:35] (当前版本) – 移除 - 外部编辑 (未知日期) 127.0.0.1 | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | ===== Codex 桌面版单应用代理配置(只让 Codex 走代理)===== | ||
| - | |||
| - | 国内网络下,Codex / ChatGPT 桌面版登录经常会报这一句: | ||
| - | |||
| - | Token exchange failed: token endpoint returned status 403 Forbidden: Country, region, or territory not supported | ||
| - | |||
| - | 奇怪的是,浏览器能正常打开 chatgpt.com,代理客户端也开着,偏偏 Codex 登录就 403。 | ||
| - | |||
| - | 原因是:Codex 的核心 app-server 是 Rust 写的,它**只认环境变量** '' | ||
| - | |||
| - | 本文的做法:**不碰系统代理、不写用户环境变量、不开 TUN**,起一个独立的 mihomo 实例,再用一个启动器把代理只注入 Codex 这一个进程树。影响面只有一个程序,删掉快捷方式就回滚。 | ||
| - | |||
| - | (以下配置均为脱敏示例,节点栏位请替换成自己的。) | ||
| - | |||
| - | === 一、先确认是不是这个坑 === | ||
| - | |||
| - | | 现象 | 说明 | | ||
| - | |---|---| | ||
| - | | 浏览器能开 chatgpt.com | 代理本身没问题,问题在" | ||
| - | | Codex 登录报 403,且带 request id | 请求直连出去了,被地区拦 | | ||
| - | | 报错含 Country, region, or territory not supported | 基本可以确诊 | | ||
| - | | 换了节点、重装 Codex 都没用 | 因为流量压根没进代理 | | ||
| - | |||
| - | 判读口诀:用 '' | ||
| - | |||
| - | * '' | ||
| - | * '' | ||
| - | * '' | ||
| - | |||
| - | === 二、四种方案对比 === | ||
| - | |||
| - | | 方案 | 影响范围 | 缺点 | | ||
| - | |---|---|---| | ||
| - | | '' | ||
| - | | Windows 系统代理 | 全局 | 全局生效,且 Codex 的 app-server 根本不读它 | | ||
| - | | TUN 模式 + 进程名规则 | 按进程 | 需要管理员,规则常被机场订阅覆盖,排错难 | | ||
| - | | **独立实例 + 启动器(本文)** | 一个进程树 | 需要自己维护一个 config.yaml | | ||
| - | |||
| - | === 三、原理:为什么" | ||
| - | |||
| - | 实测结论(Windows 11 + MSIX 安装的 Codex): | ||
| - | |||
| - | * 用 '' | ||
| - | * 直接运行包内的 '' | ||
| - | |||
| - | 所以启动器必须做三件事: | ||
| - | |||
| - | - 起自己的 mihomo 实例(独占一个端口) | ||
| - | - 给当前 PowerShell 进程设 '' | ||
| - | - 直接 '' | ||
| - | |||
| - | === 四、端口规划 === | ||
| - | |||
| - | 同一台机器可能同时跑好几个 mihomo,**端口和 DNS 端口都不能撞**。 | ||
| - | |||
| - | | 实例 | mixed-port | DNS | 控制口 | | ||
| - | |---|---|---|---| | ||
| - | | 其他全局客户端 | 7890 | — | 9090 | | ||
| - | | Codex(本文) | 7898 | 1055 | 59098 | | ||
| - | | Claude 桌面版 | 7899 | 1054 | 59099 | | ||
| - | |||
| - | 探测端口是否被占('' | ||
| - | |||
| - | <code powershell> | ||
| - | foreach ($p in 7890, | ||
| - | $c = New-Object System.Net.Sockets.TcpClient | ||
| - | $iar = $c.BeginConnect(' | ||
| - | $ok = $iar.AsyncWaitHandle.WaitOne(300) -and $c.Connected | ||
| - | $c.Close() | ||
| - | " | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | === 五、配置文件 === | ||
| - | |||
| - | 目录结构(放在用户目录下): | ||
| - | |||
| - | < | ||
| - | ~/ | ||
| - | ├─ mihomo-codex.exe | ||
| - | ├─ config.yaml | ||
| - | ├─ launch-codex.ps1 | ||
| - | ├─ launch-codex.vbs | ||
| - | └─ launcher.log | ||
| - | </ | ||
| - | |||
| - | 内核**必须改名**:很多客户端(含 Claude 桌面版的守护脚本)会用 '' | ||
| - | |||
| - | ==5.1 最小可用配置== | ||
| - | |||
| - | <code yaml> | ||
| - | mixed-port: 7898 | ||
| - | allow-lan: false | ||
| - | mode: rule | ||
| - | log-level: warning | ||
| - | external-controller: | ||
| - | tcp-concurrent: | ||
| - | find-process-mode: | ||
| - | |||
| - | profile: | ||
| - | store-selected: | ||
| - | store-fake-ip: | ||
| - | |||
| - | dns: | ||
| - | enable: true | ||
| - | listen: 0.0.0.0: | ||
| - | enhanced-mode: | ||
| - | fake-ip-range: | ||
| - | default-nameserver: | ||
| - | nameserver: [223.5.5.5, 119.29.29.29] | ||
| - | proxy-server-nameserver: | ||
| - | |||
| - | proxies: | ||
| - | - name: node-vless | ||
| - | type: vless | ||
| - | server: 127.0.0.1 | ||
| - | port: 443 | ||
| - | uuid: 00000000-0000-0000-0000-000000000000 | ||
| - | tls: true | ||
| - | servername: example.com | ||
| - | client-fingerprint: | ||
| - | flow: xtls-rprx-vision | ||
| - | reality-opts: | ||
| - | public-key: KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio | ||
| - | short-id: 01234567 | ||
| - | skip-cert-verify: | ||
| - | udp: true | ||
| - | |||
| - | proxy-groups: | ||
| - | - name: APP | ||
| - | type: url-test | ||
| - | proxies: [node-vless] | ||
| - | url: http:// | ||
| - | interval: 180 | ||
| - | tolerance: 50 | ||
| - | |||
| - | rules: | ||
| - | - MATCH,APP | ||
| - | </ | ||
| - | |||
| - | 要点: | ||
| - | |||
| - | * '' | ||
| - | * '' | ||
| - | * '' | ||
| - | |||
| - | ==5.2 三种配节点方式== | ||
| - | |||
| - | **方式一:手填单个节点** | ||
| - | |||
| - | 直接改 '' | ||
| - | |||
| - | **方式二:订阅链接(长期用这个)** | ||
| - | |||
| - | <code yaml> | ||
| - | proxy-providers: | ||
| - | sub: | ||
| - | type: http | ||
| - | url: https:// | ||
| - | interval: 3600 | ||
| - | path: ./ | ||
| - | health-check: | ||
| - | enable: true | ||
| - | url: http:// | ||
| - | interval: 300 | ||
| - | |||
| - | proxy-groups: | ||
| - | - name: APP | ||
| - | type: url-test | ||
| - | use: [sub] | ||
| - | url: http:// | ||
| - | interval: 180 | ||
| - | </ | ||
| - | |||
| - | 手动触发更新(不用等 interval): | ||
| - | |||
| - | <code powershell> | ||
| - | Invoke-RestMethod -Method Put -Uri ' | ||
| - | </ | ||
| - | |||
| - | 注意:订阅必须是 **Clash YAML** 格式。base64 或 '' | ||
| - | |||
| - | **方式三:从现成客户端搬** | ||
| - | |||
| - | 已在用 Clash / mihomo 系客户端(Clash Verge、FlClash 等)的,可以直接拷它的 '' | ||
| - | |||
| - | ==5.3 一个容易踩的格式坑== | ||
| - | |||
| - | REALITY 公钥要求是 **32 字节的 base64url,43 个字符,不带等号**。带 '' | ||
| - | |||
| - | === 六、启动器 === | ||
| - | |||
| - | <code powershell> | ||
| - | $ErrorActionPreference = ' | ||
| - | |||
| - | $ProxyDir | ||
| - | $CoreExe | ||
| - | $ProxyPort = 7898 | ||
| - | $PkgName | ||
| - | $AppExeRel = ' | ||
| - | $Aumid | ||
| - | |||
| - | $Proxy = " | ||
| - | |||
| - | function Test-Port($p) { | ||
| - | try { | ||
| - | $c = New-Object System.Net.Sockets.TcpClient | ||
| - | $iar = $c.BeginConnect(' | ||
| - | $ok = $iar.AsyncWaitHandle.WaitOne(400) -and $c.Connected | ||
| - | $c.Close(); return $ok | ||
| - | } catch { return $false } | ||
| - | } | ||
| - | |||
| - | # 1) 自己的内核没起就先起 | ||
| - | if (-not (Test-Port $ProxyPort)) { | ||
| - | Start-Process -FilePath $CoreExe -ArgumentList ' | ||
| - | for ($i = 0; $i -lt 40; $i++) { | ||
| - | Start-Sleep -Milliseconds 500 | ||
| - | if (Test-Port $ProxyPort) { break } | ||
| - | } | ||
| - | } | ||
| - | |||
| - | # 2) 定位 exe(MSIX 包目录每次更新都会变,必须动态取) | ||
| - | $exe = $null | ||
| - | $pkg = Get-AppxPackage -Name $PkgName | Select-Object -First 1 | ||
| - | if ($pkg) { | ||
| - | $c = Join-Path $pkg.InstallLocation $AppExeRel | ||
| - | if (Test-Path -LiteralPath $c) { $exe = $c } | ||
| - | } | ||
| - | |||
| - | # 3) 关掉旧实例,新进程树才会继承新变量 | ||
| - | Get-Process ChatGPT -ErrorAction SilentlyContinue | Stop-Process -Force | ||
| - | Start-Sleep -Seconds 2 | ||
| - | |||
| - | # 4) 只给本进程树注入代理,然后直接运行 exe | ||
| - | if ($exe) { | ||
| - | $env: | ||
| - | $env: | ||
| - | $env: | ||
| - | $env: | ||
| - | # --lang=zh-CN 固定界面/ | ||
| - | Start-Process -FilePath $exe -ArgumentList @((' | ||
| - | } else { | ||
| - | # 兜底:exe 找不到就用 AUMID 激活(没有代理,但至少能开) | ||
| - | Start-Process (' | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | **两个坑**: | ||
| - | |||
| - | * 脚本注释和字符串**只能用 ASCII**。PowerShell 5.1 会把无 BOM 的 UTF-8 当 ANSI 读,中文注释会导致解析报错('' | ||
| - | * 必须 '' | ||
| - | |||
| - | 静默包装 '' | ||
| - | |||
| - | <code vbscript> | ||
| - | Set sh = CreateObject(" | ||
| - | ps1 = sh.ExpandEnvironmentStrings(" | ||
| - | sh.Run " | ||
| - | </ | ||
| - | |||
| - | 建快捷方式(桌面 + 开始菜单): | ||
| - | |||
| - | <code powershell> | ||
| - | $dir = Join-Path $env: | ||
| - | $pkg = Get-AppxPackage -Name ' | ||
| - | $ws = New-Object -ComObject WScript.Shell | ||
| - | foreach ($t in @(" | ||
| - | " | ||
| - | $l = $ws.CreateShortcut($t) | ||
| - | $l.TargetPath | ||
| - | $l.Arguments | ||
| - | $l.WorkingDirectory = $dir | ||
| - | $l.IconLocation | ||
| - | $l.Save() | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | 以后**只用这个快捷方式启动**。原来的磁贴启动不带代理,症状就是 403 或一直转圈。 | ||
| - | |||
| - | === 七、验证四步 === | ||
| - | |||
| - | <code powershell> | ||
| - | $d = Join-Path $env: | ||
| - | |||
| - | # 1) 配置语法与节点自检(只校验,不监听) | ||
| - | & " | ||
| - | |||
| - | # 2) 走它测出口地区(最直接的一步) | ||
| - | curl.exe -s -x http:// | ||
| - | |||
| - | # 3) 用快捷方式起一次 Codex,然后确认子进程拿到了变量 | ||
| - | Get-Process codex | Select-Object Id, StartTime | ||
| - | |||
| - | # 4) 看它到底连去哪(有没有绕过代理) | ||
| - | Get-NetTCPConnection -OwningProcess (Get-Process codex).Id | | ||
| - | Select-Object RemoteAddress, | ||
| - | </ | ||
| - | |||
| - | 正常结果:第 2 步输出里有 '' | ||
| - | |||
| - | 想省事可以把上面这些做成一个自检脚本,跑完打印 8 项 PASS/ | ||
| - | |||
| - | === 八、常见问题 === | ||
| - | |||
| - | | 症状 | 原因 | 处理 | | ||
| - | |---|---|---| | ||
| - | | 内核起来几秒就退出 | 端口或 DNS 端口被占 | 先跑 -t;换端口,DNS 也要换 | | ||
| - | | curl 走代理返回 000 | 节点参数错,或节点被墙 | 换节点;检查 servername 与 sni 是否写混 | | ||
| - | | curl 通,Codex 登录还是 403 | 用了磁贴启动,走了直连 | 只用代理快捷方式启动 | | ||
| - | | curl 通,Codex 一直转圈 | app-server 没拿到环境变量 | 查 codex 进程的 HTTPS_PROXY | | ||
| - | | 有连接绕过代理 | 少了 ''< | ||
| - | | 改了端口启动器没反应 | 只改了 config.yaml | config.yaml 与启动器两处同步改 | | ||
| - | | 订阅不更新 | 订阅链接失效或需 UA | 手动 Put 触发一次看报错 | | ||
| - | | 菜单栏一会儿中文一会儿英文 | 只配了 '' | ||
| - | |||
| - | === 九、固定中文菜单与界面语言 === | ||
| - | |||
| - | 现象:同一个代理快捷方式启动,界面有时中文、有时英文。 | ||
| - | |||
| - | 原因:Codex 桌面版的语言由**两套互相独立**的机制决定,只改一处就会飘。 | ||
| - | |||
| - | | 层 | 决定什么 | 从哪里读 | | ||
| - | |---|---|---| | ||
| - | | Electron 的 '' | ||
| - | | '' | ||
| - | |||
| - | **做法一:启动器追加语言参数(关键)** | ||
| - | |||
| - | 把启动器第 4 步的 '' | ||
| - | |||
| - | <code powershell> | ||
| - | Start-Process -FilePath $exe -ArgumentList @((' | ||
| - | </ | ||
| - | |||
| - | ''< | ||
| - | |||
| - | **做法二:配置文件也写死(防止应用内文案回退)** | ||
| - | |||
| - | 在 '' | ||
| - | |||
| - | <code toml> | ||
| - | [desktop] | ||
| - | localeOverride = " | ||
| - | </ | ||
| - | |||
| - | '' | ||
| - | |||
| - | 两条一起用才稳: | ||
| - | |||
| - | * 只加 ''< | ||
| - | * 只写 '' | ||
| - | * 两条都写:菜单栏与界面正文统一中文 | ||
| - | |||
| - | 验证:完全退出 Codex(托盘图标也要退),用代理快捷方式重新启动,菜单栏应为 **文件 编辑 视图 帮助**,左侧栏为 **新聊天 / 项目**。 | ||
| - | |||
| - | 补充说明: | ||
| - | |||
| - | * 26.1016.8622.0 起设置里多了 **Settings → General → Language**,选「简体中文」等效于写 '' | ||
| - | * 应用内文案是否加载还受服务端开关(Statsig 的 '' | ||
| - | * 想换回英文:删掉启动器里的 ''< | ||
| - | |||
| - | === 十、回滚 === | ||
| - | |||
| - | * 停内核:'' | ||
| - | * 删掉那两个快捷方式,Codex 就回到原样(磁贴启动、走直连) | ||
| - | * 全程没有改过系统代理,也没有写过用户环境变量,所以不需要额外清理 | ||
| - | |||
| - | === 相关 === | ||
| - | |||
| - | * [[随笔: | ||
| - | * [[随笔: | ||
| - | |||
| - | ---- | ||
| - | |||
| - | 本文整理自 2026 年 10 月 Windows 11 上的实操验证(Codex 版本 26.1016.8622.0,mihomo v1.19.32)。文中节点、域名、凭据均为示意值,请替换为自己的。整理录入:2026-10-23。 | ||