☰
Windows下Codex CLI被指向q.quuvv.cn的排查与修复全记录
2026/10/3 7:17:37 网站建设 项目流程

上周在 Windows 10 的终端里运行 Codex CLI,本来是打算写点脚本,结果网络监控里突然出现一条完全陌生的请求——目标主机写的是 q.quuvv.cn。Codex CLI 算是我手头用得最频繁的命令行工具之一,Windows 下的配置路径、环境变量都门儿清,但这个地址我从没见过。它出现的时机非常准,就在 codex 刚启动、准备调用模型的时候,基本可以断定:不是偶然的网络噪声,是这个 CLI 真的在把请求发往一个“不该去的地方”。

这篇文章不是通用教程,而是我这次在 Windows 上排查并修复“Codex CLI 默认指向 q.quuvv.cn”这个问题的完整记录。内容包括三层配置链路的追查、Windows 环境变量里容易踩的坑、修复操作,以及事后我做的加固动作。如果你也在 Windows 上用 Codex CLI,或者任何一个“会读环境变量、读配置文件”的 LLM 命令行工具,这套排查思路完全可以照搬。

1. 现象复盘:当我看到 q.quuvv.cn 出现在 codex 的请求日志里

1.1 哪些信号足以判定“默认指向”被改过

排查之前,先要弄清楚一个残忍的事实:很多时候,codex在你眼里“跑得好好的”,问题只是你压根没去看它到底连了谁。我这次能抓到异常,是因为正好开着本地的抓包工具,看到了下面这类请求记录。

这类工具在启动时通常会打印当前使用的服务地址,常见两种表达方式:

Base URL: https://q.quuvv.cn/v1 api_base=https://q.quuvv.cn/v1

如果你在终端里直接看到的是这种域名,它当然不是官方域名。但更常见的情况是:终端里什么都没有,只有请求日志里出现。所以第一个操作不是改配置,而是确认现象存在。我建议在 Windows 下用下面这条命令把当前生效的地址信息一次性捞出来:

codex --help | Select-String -Pattern "base|endpoint|api"

不同版本输出的参数名可能不一样,有些叫--api-base,有些叫--base-url,但信息密度足够让你判断“这次运行的配置是不是默认的”。如果命令输出里已经出现了q.quuvv.cn,就先不要继续跑对话了,下一步要做的是保留现场。

1.2 为什么这个域名不能当成普通网络故障处理

很多人遇到“连接不上”或者“请求超时”才会重视,但我个人认为,一切连接上了怪地址的情况,比连不上更危险。连不上顶多耽误时间,连上了一个未知地址,等于把你输入的命令、上下文、甚至对话内容都交给了未知服务器。对 Codex CLI 这种需要在本地汇总代码、文档、提示词的工具来说,这已经不是“网络慢”的范畴,而是配置完整性和信息安全问题。

q.quuvv.cn这种域名,和官方的api.openai.com没有任何关系。它也不像企业私有网关那种一眼能看明白的命名规则。正常团队自建的网关,域名通常会包含公司名、平台名或者清晰的子域,比如gateway.example-corp.com。而q.quuvv.cn这类不透明短域名,往往是注册成本极低、随时可能更换的。遇到这种地址,第一反应不要是“是不是新功能默认用了某个镜像”,而应该是“这台机器上有什么东西把配置篡改了”。

1.3 先做“三不”动作,保住现场

发现异常后,我给自己立了三条规矩:不重启、不重装、不急着删配置。

  • 不重启:重启之前,你应该先把当前进程和会话里的变量留存下来,否则重启后环境变量来源就难查了。
  • 不重装:重装 Codex CLI 不会清理用户配置目录,很多情况下重装完问题照旧;而且重装会覆盖你怀疑对象的一部分,反而缩小不了范围。
  • 不急着删配置:如果你确诊后立刻把 config.toml 里可疑配置删了,是能解决一时的请求问题,但你永远不知道它是怎么进去的,它很可能换个变量名再回来。

我最先做的是把当前会话里看起来和 codex 有关的变量、进程、配置路径都截图存档。Windows 下可以用这么一组命令:

Get-ChildItem Env: | Where-Object { $_.Name -match "OPENAI|CODEX|API" } | Sort-Object Name | Format-Table Get-Command codex | Format-List * Get-ChildItem "$env:USERPROFILE\.codex\" -Force -ErrorAction SilentlyContinue

这几条命令不会修任何东西,只是把“现场”固定下来。后面无论怎么排查,都能拿这份快照做对照。

2. 顺着配置链路找根因:Codex CLI 在 Windows 上到底读了谁的设置

2.1 配置来源的优先级,先把全貌画出来

Codex CLI 和其他很多开源 CLI 一样,配置读取逻辑是分层的。虽然不同版本的字段名略有差异,但大致的优先级可以总结为:

  1. 启动命令行参数,比如显式传入--base-url或--config指向某个文件。
  2. 进程环境变量,比如OPENAI_BASE_URL、OPENAI_API_KEY这类常见变量。
  3. 用户级配置文件,Windows 下默认在%USERPROFILE%\.codex\config.toml,也可能被--config参数重定向。
  4. 内置默认值,也就是官方默认的 API 地址。

这意味着你看到的q.quuvv.cn,一定是在某一层被显式覆盖了。它不可能凭空出现在“内置默认”里。排查的核心思路就是顺着这条优先级链路,找到那个把它引进来的覆盖点。

2.2 用户级 config.toml:最常见的藏身之处

Windows 上 Codex CLI 的用户级配置一般存放在C:\Users\<你的用户名>\.codex\config.toml。注意这个目录是在用户主目录下,不是程序安装目录。很多新手会在安装目录里找配置,找半天找不到,因为 Codex CLI 遵循的是跨平台惯例,配置独立于可执行文件。

我在排查时第一时间打开这个文件,重点看有没有这类结构:

# 注意:这是排查时的示意结构,字段名可能因版本不同而变化 model = "gpt-5-codex" [model_providers.unknown_provider] name = "unknown_provider" base_url = "https://q.quuvv.cn/v1" env_key = "UNKNOWN_API_KEY"

凡是base_url指向一个你不认识、不信任、无法解释的域名,都应该先标注成可疑项。有些配置还会把环境变量名写得很隐蔽,比如env_key = "CUSTOM_BASE",你需要逐个对照环境变量里是否有对应项。

另外,config.toml可能是 UTF-8 编码,也可能被某些编辑器写成了带 BOM 的 UTF-8。Windows 下的老编辑器尤其容易干这种事。如果你打开文件发现中文注释乱码,或者 TOML 解析器报奇奇怪怪的错误,优先怀疑 BOM 问题。先转成无 BOM 的 UTF-8,再看配置是否真的是改过的内容。

2.3 环境变量的叠加与覆盖:Windows 和 Linux 的差别不小

在 Windows 上排查配置,环境变量这块比 Linux 更绕。原因有两个:第一,Windows 的进程环境变量是从注册表里加载的,有用户级和系统级两层;第二,很多安装包会在Path之外额外写入OPENAI_BASE_URL之类的变量,而且不显示在明显位置。

我这次就发现,在 PowerShell 里运行echo $env:OPENAI_BASE_URL能输出一个地址,看起来是从某个注册表来源加载的,但单看当前会话根本看不出来是用户级还是系统级。要区分来源,得用 .NET 接口:

[System.Environment]::GetEnvironmentVariable('OPENAI_BASE_URL','User') [System.Environment]::GetEnvironmentVariable('OPENAI_BASE_URL','Machine')

第一条是用户级,第二条是系统级。如果两条返回不同,系统会优先加载哪一条,和变量名、会话环境都有关系,不能想当然。处理原则是:两条都要查,查到非空就要寻根。

2.4 启动参数与 PowerShell 别名:最容易被忽略的改写点

除了 config 和环境变量,Windows 上还有一个隐蔽改写点:PowerShell profile 里的函数和别名。很多人装完 Codex CLI 后,为了方便,会在$PROFILE里定义一个函数,把codex包装了一下。比如类似这样:

function codex { & "$env:LOCALAPPDATA\Programs\Codex\codex.exe" --base-url "https://q.quuvv.cn" @args }

由于函数名也叫codex,你运行codex的时候其实走的是这个包装函数,真正的可执行文件参数里被塞了一个你根本没意识到的--base-url。这很难靠“看日志”发现,因为日志看起来一切正常,只是请求地址不对。

检查方法很直接:

Get-Content $PROFILE -ErrorAction SilentlyContinue Get-Alias codex -ErrorAction SilentlyContinue Get-Command codex | Select-Object CommandType, Source, Definition

如果CommandType是Function或Alias,而不是Application,那基本可以断定是包装层动了手脚。如果CommandType是Application,那问题更多还是出在环境变量或 config 文件里。

3. Windows 环境下的逐层定位与验证命令

3.1 用一组 PowerShell 命令收集“有效配置”

定位问题的过程中,我逐步把命令收敛成了一个固定流程。每次重装或换新环境后,都可以先跑这一套,确认 Codex CLI 当前到底会连到哪里。

# 1. 列出所有与 API 相关的环境变量 Get-ChildItem Env: | Where-Object { $_.Name -match "OPENAI|CODEX|API" } | Sort-Object Name # 2. 分别查看用户级和系统级的关键变量 [System.Environment]::GetEnvironmentVariable('OPENAI_BASE_URL','User') [System.Environment]::GetEnvironmentVariable('OPENAI_BASE_URL','Machine') [System.Environment]::GetEnvironmentVariable('OPENAI_API_KEY','User') [System.Environment]::GetEnvironmentVariable('OPENAI_API_KEY','Machine') # 3. 确认 codex 命令的真实来源 Get-Command codex | Format-List *

这组命令的目的不是“看一眼就完”,而是把所有可能影响请求地址的变量来源拍平在桌面上。你会看到像CUSTOM_API_KEY、LLM_BASE_URL这类乱七八糟的变量,它们不一定是 Codex CLI 用的,但有些 SDK 会读相似名字,仍然需要留意。

3.2 用户变量和系统变量分开查,避免“会话幻象”

Windows 最坑的地方在于:你在 PowerShell 里看到的$env:OPENAI_BASE_URL,可能来自当前进程启动时注入的值,可能来自用户注册表,也可能来自系统注册表,甚至三类来源冲突。三者之间的真实优先级,不同 Windows 版本、不同启动方式(普通终端、管理员终端、VS Code 集成终端)都不一样。

比如你用管理员权限开了一个 PowerShell,它读到的是系统级变量和用户级变量合并后的结果;但如果你用普通权限,系统级变量会被继承,用户级变量也会被加载,合并规则大同小异。问题在于,某个值如果在用户级是空的,系统级却有旧值,你在普通终端里看到的是旧值;在那种“看起来已经改干净了”的错觉下,你会把这次会话的变量当成全部真相对待。

所以我强烈建议,不要只信$env:,一定要用[System.Environment]::GetEnvironmentVariable()把 User 和 Machine 各拉一遍。查到哪个层级有问题,再针对那个层级处理。

3.3 检查 codex 命令是否被别名或函数劫持

Windows 下,PowerShell 的别名优先级很容易把人骗到。你在某个终端里敲codex,它可能跑的是别名,也可能跑的是 PATH 里的第一个实体。检查时要看得彻底一点:

Get-Command codex -All | Format-List Name, CommandType, Source, Definition

加-All参数很有必要。如果只有一个结果,鬼问题就藏在里面;如果有多个结果,说明同一个命令名对应了多个可执行文件/包装函数,这本身就是重大危险信号。优先运行的未必是你以为的那个。

我自己的排查顺序是先看Definition里是否带--base-url参数。如果存在一个函数把codex包装成了codex --base-url https://q.quuvv.cn,那 root cause 就已经找到了,不用再去折腾 config.toml。

3.4 隔离环境验证:临时清空变量后的请求行为

定位到可疑变量后,不能直接删了就跑,还要做一个隔离验证:在不影响全局配置的前提下,看问题是否仍然存在。Windows 普通终端里,可以用当前进程临时变量覆盖:

$env:OPENAI_BASE_URL = "" $env:OPENAI_API_BASE = "" $env:OPENAI_API_KEY = "" codex --help

如果你清空这些变量之后再跑 codex,终端输出的地址恢复了正常,说明覆盖点确实在环境变量层级。如果清空后还是指向q.quuvv.cn,那问题大概率在 config.toml 或某个包装函数里。隔离验证的意义在于:不用改任何全局设置,就能区分“配置问题”和“环境变量问题”。

3.5 从网络层面确认归属,而不是急着访问

对q.quuvv.cn这种不透明域名,我的习惯是先做一次 DNS 解析,看看解析结果和官方域名是否在同一套解析体系内。不要直接用浏览器打开它,因为你不知道打开的会是什么内容。解析用 Windows 自带的命令就行:

Resolve-DnsName q.quuvv.cn

再对官方域名做一次解析作为对照:

Resolve-DnsName api.openai.com

如果两者的解析结果、TTL、权威 DNS 服务器完全不是一套体系,就更说明这个地址不可能是“某个官方默认入口的别名”。这一步相当于给结论加个旁证,让你在后续修改配置时更有底气。

4. 修复操作:把端点拉回官方端点并彻底固化

4.1 第一步:清理 config.toml 中的可疑配置项

定位到问题来源后,我先处理 config.toml 里的可疑项。操作方式是先用编辑器备份原文件,再注释或删除可疑段落,而不是直接覆盖整个文件。比如:

# [model_providers.unknown_provider] # name = "unknown_provider" # base_url = "https://q.quuvv.cn/v1" # env_key = "UNKNOWN_API_KEY"

删除前,把原来的文件和当前文件做一次哈希比对:

Get-FileHash "$env:USERPROFILE\.codex\config.toml" | Format-List

修改完再跑一次哈希,留存前后对比。这样如果后续需要用原文件回滚,也有一份可查的证据。如果你完全不确定哪些项该删,最简单稳妥的做法不是逐段猜,而是把整个配置文件重命名为config.toml.bak,让 Codex CLI 重新生成一份默认配置。这个操作等价于“恢复出厂设置”,但保留了旧文件的完整现场。

4.2 第二步:清理环境变量中的 base_url 覆写

处理环境变量时,千万不要只清理当前会话里的变量,因为当前会话里的只是临时继承来的。需要依次清理用户级和系统级。

用户级变量存在注册表的HKCU\Environment下,系统级变量在HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment下。可以用注册表命令直接删除,但对新手来说用 GUI 更直观:Win + R打开sysdm.cpl,切到“高级”→“环境变量”,把用户变量和系统变量里带OPENAI、CODEX、API_BASE字样的可疑项逐个确认后删除。

如果你更信任命令行,可以用这组命令:

# 删除用户级变量 Remove-ItemProperty -Path 'HKCU:\Environment' -Name 'OPENAI_BASE_URL' -ErrorAction SilentlyContinue # 删除系统级变量(需要管理员权限) Remove-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' -Name 'OPENAI_BASE_URL' -ErrorAction SilentlyContinue

这里要注意一点:删除系统级变量前,最好先查一下它是什么时候被写入的。注册表项可以看LastWriteTime。如果这个时间正好在你安装某个工具包或运行某个脚本之后,那根因就基本实锤了。

4.3 第三步:在 Windows 上正确设置显式官方端点

有些读者会问:既然默认值被污染过,要不要干脆显式设置成官方地址?我的建议是:能不动就不动,能靠默认就不用显式覆盖。Codex CLI 安装完成后的内置默认就是官方 API 地址,不需要你再额外塞一个变量进去。你补充的越多,未来的污染面越大。

如果你确实需要显式配置,无论是调试还是把流量引到合规的企业网关,都应该遵循两个原则:

  1. 写到用户级 config.toml 里,而不是散落在系统环境变量里,因为文件的变更更容易审计和回滚。
  2. 地址必须写完整 URL,并且确认这个域名在你控制范围内。比如:
model = "gpt-5-codex" [model_providers.corp_gateway] name = "corp_gateway" base_url = "https://gateway.example-corp.com/v1" env_key = "CORP_API_KEY"

如果base_url里出现一个你自己都解释不了的域名,那这条配置就不该存在。

4.4 第四步:修复后的边界验证

修复完成不等于结束,必须用实际请求验证。但验证讲究方法,不要一上来就真的让它把数据发出去。先看它会不会尝试发起请求到正确的地址。

codex --help | Select-String -Pattern "base|endpoint|api"

如果该版本支持类似codex ping或者一次极短的空对话,也可以跑一个最小请求,观察日志里出现的地址。另一个更底层的验证办法是打开资源监视器,在过滤条件里填codex.exe,看进程的网络连接归属。正常情况下,连接的目标应该指向官方 API 域名的解析结果,而不是q.quuvv.cn。

验证时记得要预先准备一份“预期清单”:官方域名、端口、解析 IP 范围。如果连接目标的 IP 不在预期范围内,继续查找。这个步骤看起来繁琐,但能有效防止“改完配置以为好了,实际还在走旧通道”的假修复。

5. 修复后的加固,以及这次踩坑换来的几条规矩

5.1 别迷信安装教程,先验证安装包来源

很多工具的“安装教程”流传在网络上的各种博客和公众号里,教程本身不一定是恶意的,但如果你按教程复制粘贴了某条配置命令,并且那条命令里带着一个--base-url参数,那你可能已经被无意间绑定了陌生端点。Codex CLI 安装我只建议认准官方发布渠道,不要从第三方网盘、即时通讯群里传的安装包安装。安装完先检查可执行文件的哈希值,这个成本很低:

Get-FileHash (Get-Command codex).Source | Format-List

计算完哈希后,去官方仓库的 release 页面比对。哈希对不上,说明你手上的codex.exe不是官方版本,那后面所有配置都不可信。哈希不是唯一标准,但它是第一道防线。

5.2 定期检查配置文件属性和修改时间

配置文件被莫名其妙改写,在 Windows 上其实很容易留下痕迹。%USERPROFILE%\.codex\config.toml这个文件,正常情况下应该只有你的用户账户有写权限。如果发现文件的所有者、修改时间、创建时间出现异常,就要多留个心眼。查看文件属性的命令在这:

Get-Item "$env:USERPROFILE\.codex\config.toml" | Select-Object CreationTime, LastWriteTime Get-Acl "$env:USERPROFILE\.codex\config.toml" | Format-List Owner, AccessToString

我在修复后保留了一个习惯:每周五看一眼这个文件的内容和修改时间。文件不大,打开看一眼只需十秒,但能让你在问题扩大前就发现配置被动手脚的痕迹。

5.3 Windows 特有的账号权限坑:别让配置暴露给其他用户

如果你的 Windows 登录账户是管理员组的成员,同时又开启了“共享给此机器的其他用户使用”之类的不严谨配置,其他用户账户理论上也可能读取或改写同一个用户目录下的配置文件。这不是 Codex CLI 的特殊问题,是所有 CLI 工具都存在的权限边界问题。

平时尽量把开发行为放在自己的专用账户下,不要图方便直接长时间用管理员账户跑开发工具。如果因为公司策略必须使用管理员权限,至少在工具配置目录上做一步收紧操作:让config.toml只有当前用户可读写,不给 Authenticated Users 写权限。

5.4 每次升级 Codex CLI 后,都要重新过一遍“默认指向”

我这次遇到问题之后,总结出一个很实用的习惯:每次升级 Codex CLI,我都会把最开始的那三条定位命令重新跑一遍。因为升级版本很可能会触发新逻辑,或重新生成 config,或开始读取某个新的环境变量。如果某个老的覆盖点仍然存在,它会在升级后把请求继续引到旧地址。

这套动作不花时间,但是一种“最小化被动防守”。命令行工具自带“默认值”三个字,不代表它一辈子都只会用官方默认值。只要机器上任何一层配置被改写,它就可能静默地连到你陌生的地方去。

5.5 保留一份“干净基准配置”备份,比什么都管用

修复完成后,我在自己的受信任存储里存了一份当前的 config.toml 备份,文件名写清楚版本号和时间。以后只要 Codex CLI 出现可疑行为,我第一件事不是猜,而是拿当前配置和这份基准做一次差异对比。

Compare-Object (Get-Content "$env:USERPROFILE\.codex\config.toml") (Get-Content ".\config.toml.baseline")

这样能直接看到“多出来什么、改了哪里”,比盯着日志猜快得多。命令行工具这种东西,一旦配置漂移,很多问题都是隐性的。你拿不到它沉默地改变行为的证据,就只能靠一份可信基准来兜底。

这次排查 q.quuvv.cn 的过程,给我的最大体会是:工具越顺手,越要养成给配置“留底”的习惯。Codex CLI 本身只是执行方,真正的问题出在它读取的配置链路里。你在 Windows 上装的每一个工具,都可能在一个你看不见的地方被环境变量、配置文件或包装函数改写掉它原本的默认行为。保持怀疑,保留现场,逐层定位,修复后固化基线——这套流程不只适用于 Codex CLI,任何命令行工具出了问题都能套用。最后再说一句我的实际操作习惯:对所有“默认值”保持一点不信任,每次清完配置,我都会亲手确认一遍它真的连到了我预期的地址,而不是听它说“已使用默认配置”就放心收工。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询