开发者为什么需要一套完整代理工作流
开发者使用 Clash 时,真正需要解决的通常不是“浏览器能不能打开网页”,而是多个工具是否同时具备稳定、可观察、可回退的网络路径。浏览器可能读取系统代理,Git 会读取自己的配置或环境变量,npm、pip、Go Modules 和 Docker 又各自有不同的连接方式;Cursor、VS Code 扩展以及其他 AI 编程工具,还可能通过独立进程访问 API、下载模型或同步插件。只打开系统代理,并不能证明这些请求都会进入 Clash。
一套可维护的方案应先明确三层关系:Clash 或 mihomo 内核负责监听端口、解析 DNS 和执行规则;系统代理或 TUN 模式负责把应用流量交给内核;Git、包管理器和开发工具自身的代理设置,则决定它们是否主动使用 HTTP 或 SOCKS5 端口。三层配置互相独立时,最常见的现象就是浏览器正常、终端失败,或者终端可以执行 Git 命令,但 Docker 拉取镜像仍然超时。
| 开发场景 | 常见连接方式 | 建议的接管路径 | 主要检查点 |
|---|---|---|---|
| 浏览器访问代码托管平台 | HTTP、HTTPS 系统代理 | 系统代理或 TUN | 系统代理地址、规则命中、DNS 结果 |
| Git clone、fetch、push | HTTPS 或 SSH | Git 代理配置、环境变量或 TUN | 远端协议、Git 全局配置、SSH 端口 |
| npm、pip、Go Modules | HTTPS 请求 | 环境变量、工具配置或 TUN | 注册表地址、证书、代理变量 |
| Docker Hub 拉取镜像 | Docker daemon 发起请求 | Docker 服务代理或 TUN | daemon 与终端是否为同一网络环境 |
| Cursor 与编辑器扩展 | 应用进程或后台服务 | 应用代理设置、系统代理或 TUN | 应用重启、扩展进程、证书和规则 |
先理解系统代理与 TUN 模式的边界
系统代理通常通过操作系统的 HTTP、HTTPS 或 SOCKS 设置影响应用。Chrome、Edge、许多 Electron 应用和部分图形工具会读取这些设置,但命令行程序不一定遵循。应用如果自己创建 TCP 连接、使用自带网络库,或者明确关闭系统代理,就可能完全绕过系统代理。此时即使客户端界面显示“系统代理已开启”,Clash 日志也不会出现对应域名。
TUN 模式则通过创建虚拟网卡,把更广泛的 IP 流量导入 mihomo,再由内核执行路由和规则匹配。它适合接管不支持代理设置的程序,也适合处理开发工具中的后台连接。不过 TUN 不是“自动修复一切网络问题”的开关:权限不足、虚拟网卡冲突、DNS 设置不一致、IPv6 路由异常,以及 Docker 虚拟网络,都可能让结果变得复杂。
| 模式 | 覆盖范围 | 优势 | 可能的问题 |
|---|---|---|---|
| 系统代理 | 遵循系统代理的应用 | 配置简单,排查路径清晰,开销较低 | 终端、daemon 和独立网络库可能绕过 |
| 显式 HTTP 代理 | 支持代理参数的单个工具 | 可精确控制,便于脚本和 CI 使用 | 需要为不同工具分别配置 |
| 显式 SOCKS5 代理 | 支持 SOCKS 的工具和客户端 | 适合通用 TCP 连接 | 部分工具不识别 SOCKS URL,DNS 行为也可能不同 |
| TUN 模式 | 更广泛的 IP 流量 | 可覆盖不读取代理设置的应用 | 需要管理员权限,可能与 VPN、虚拟机和 Docker 冲突 |
TUN 模式的基础设置
在客户端的「设置」或「服务」页面开启 TUN 后,通常需要允许客户端安装或启用虚拟网卡,并授予管理员权限。配置文件中常见的相关字段如下,字段名称和可用值会随 mihomo 版本变化,修改前应以当前内核支持为准:
tun:
enable: true
stack: mixed
auto-route: true
strict-route: true
auto-detect-interface: true
dns:
enable: true
enhanced-mode: fake-ip
auto-route 用于自动添加路由,auto-detect-interface 让内核尝试选择当前出网接口,strict-route 可减少部分流量绕过 TUN 的情况。不同网络环境未必适合直接启用所有选项。例如电脑上同时运行企业 VPN、虚拟机或 WSL 时,严格路由可能导致内网地址无法访问,应先记录原有网络行为,再逐项调整。
TUN 与系统代理可以同时开启,但排查时不建议一开始就叠加。更稳妥的顺序是先关闭 TUN,仅使用系统代理测试浏览器和一个终端命令;确认端口与规则正常后,再开启 TUN,观察连接页是否出现新的进程和目标地址。这样可以区分“应用没有读取系统代理”和“TUN 路由本身异常”这两类问题。
终端、Git 与包管理器的配置方法
开发环境建议把代理分成临时环境变量和持久化工具配置两类。临时变量适合测试,关闭终端窗口后通常不会继续影响其他程序;持久化配置适合长期使用,但容易遗忘,日后关闭 Clash 后可能导致工具仍然尝试访问已经不存在的本地端口。
为终端设置 HTTP 与 SOCKS 变量
在支持 POSIX shell 的终端中,可以使用以下方式临时设置代理:
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5://127.0.0.1:7891
export NO_PROXY=localhost,127.0.0.1,::1,.local
Windows PowerShell 可以写成:
$env:HTTP_PROXY = "http://127.0.0.1:7890"
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:ALL_PROXY = "socks5://127.0.0.1:7891"
$env:NO_PROXY = "localhost,127.0.0.1,::1,.local"
并不是所有程序都会读取大小写完全相同的变量名。为了兼容不同实现,脚本环境中常同时设置大写和小写形式,但不要把包含账号、密码或订阅令牌的敏感内容写入公共日志。NO_PROXY 则用于排除本机服务、公司内网和局域网域名;如果把整个内网网段错误地放进代理,可能导致开发服务器、数据库和 Kubernetes API 无法访问。
Git 的 HTTPS 与 SSH 代理
Git 使用 HTTPS 远端时,可以让 Git 直接使用本机 HTTP 代理:
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
git config --global --get-regexp 'http.*proxy'
如果不再需要持久化代理,应显式删除,而不是只关闭 Clash:
git config --global --unset http.proxy
git config --global --unset https.proxy
SSH 远端,例如 [email protected]:org/project.git,不会读取 Git 的 HTTP 代理配置。可以通过 SSH 的 ProxyCommand 把连接交给支持 SOCKS5 的工具,或者改用 HTTPS 远端。使用前应先确认本机存在可用的 SOCKS5 端口,并注意企业内网的 SSH 访问策略。
Host github.com
HostName github.com
Port 22
ProxyCommand connect -S 127.0.0.1:7891 %h %p
出现 Git 失败时,先执行 git remote -v 判断远端协议,再检查 git config --show-origin --get-regexp 'http.*proxy'。如果使用 HTTPS,错误常见于代理端口、TLS 或规则;如果使用 SSH,则应查看 SSH 握手、端口和 ProxyCommand,而不是反复修改 HTTP 代理。
npm、pip 与 Go Modules
npm 可以使用自己的配置项:
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890
npm config get proxy
npm config get https-proxy
如果公司或团队使用内部 registry,不要为了访问公共站点而覆盖内部地址。应先查看 npm config get registry,必要时只对当前项目设置配置文件。下载失败时还要区分网络错误与证书错误:ECONNRESET、ETIMEDOUT 往往指向连接路径,证书链错误则可能来自中间代理、企业证书或 Node.js 信任库。
pip 通常可以继承 HTTPS_PROXY,也可以在单次命令中指定:
python -m pip install requests \
--proxy http://127.0.0.1:7890
Go Modules 会受到环境变量、GOPROXY 和私有模块设置共同影响。公共模块可以检查:
go env GOPROXY
go env GOPRIVATE
go env HTTPS_PROXY
不要把内部模块域名交给公共代理。可以使用 GOPRIVATE=corp.example 排除私有路径,并在 NO_PROXY 中加入内部域名。规则设计上,代码托管平台、公共 registry 和内部 Git 服务往往需要不同的策略组,不能简单地把所有开发流量统一代理或统一直连。
Docker、Cursor 与 AI 编程工具的特殊处理
Docker daemon 不等于当前终端
执行 docker pull 时,实际发起请求的可能是 Docker daemon,而不是当前 shell。即使终端中设置了 HTTPS_PROXY,daemon 也可能完全看不到这些变量。Docker Desktop 需要在应用设置中检查代理选项;Linux 上的 Docker Engine 则通常需要为 systemd 服务配置环境文件,并在修改后重载服务。
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.local"
Docker 容器内部的代理与 daemon 拉取镜像又是两件事。前者影响构建步骤和运行中的程序,后者影响镜像下载。构建时可以通过构建参数传递代理,但不要把带认证信息的代理 URL 固化进镜像层或公开 Dockerfile。完成测试后执行 docker info,查看客户端和服务端信息是否正常,再用一个小型公共镜像验证,不要一开始就拉取数 GB 的基础镜像。
Cursor、VS Code 与扩展进程
Cursor、VS Code 以及其他基于 Electron 的工具通常有独立的代理设置,同时还可能启动扩展宿主进程、语言服务器和远程开发组件。主窗口可以访问网页,不代表扩展下载、代码索引或 AI 请求也使用相同路径。应在应用设置中搜索 proxy,确认代理模式是跟随系统还是使用明确地址,并重启应用使连接池和后台进程重新建立。
如果使用 TUN,通常不需要为每个编辑器重复填写端口,但仍需观察 Clash 的连接页。访问 AI 服务或扩展市场时,连接详情应能看到对应域名、进程名称和命中的策略组。完全没有记录,说明请求可能被应用代理设置、企业安全软件或独立网络进程拦截;有记录但失败,则继续检查规则、DNS、TLS 和节点可用性。
AI 编程工具往往需要多个域名:登录服务、API 服务、更新服务、扩展市场和遥测端点可能并不相同。不要只测试一个主页就断定功能正常,也不要为了让一个 API 可用而把所有编辑器流量切换到全局代理。更好的做法是保留规则模式,为明确的服务域名设置稳定策略组,同时让本地项目、内网地址和本机模型服务走 DIRECT。
开发场景的规则设计建议
规则应从具体、稳定的域名开始,再处理地理分类和兜底。下面只是结构示例,实际策略组名称必须与配置中的定义完全一致:
rules:
- DOMAIN-SUFFIX,github.com,Developer
- DOMAIN-SUFFIX,githubusercontent.com,Developer
- DOMAIN-SUFFIX,npmjs.org,Developer
- DOMAIN-SUFFIX,docker.io,Developer
- DOMAIN-SUFFIX,openai.com,AI
- DOMAIN-SUFFIX,local,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- GEOIP,LAN,DIRECT
- MATCH,节点选择
规则按从上到下的顺序匹配,第一条命中后就不会继续向下判断。将 GEOIP,LAN,DIRECT 或本地网段规则放在兜底之前,可以减少本地开发服务被误送到远端节点的情况。Docker、Kubernetes、数据库和公司内网使用的域名应根据实际网络补充到 NO_PROXY 与 Clash 规则中,两者最好保持一致。
用可重复测试验证整条链路
完成配置后,不要只打开一个网页。建议按照“端口—内核—规则—应用”的顺序验证,每次只改变一个变量。首先确认本地端口正在监听,然后让 curl 使用明确代理访问测试地址,再执行 Git、npm 或 Docker 命令,最后检查 Cursor 等图形工具的连接记录。
curl -I -x http://127.0.0.1:7890 https://example.com
curl --socks5-hostname 127.0.0.1:7891 https://example.com
git ls-remote https://github.com/example/project.git
npm view npm version
HTTP 代理测试通过,只能说明 Clash 的监听端口和当前节点至少可以完成一次请求;SOCKS5 测试通过,则进一步证明 SOCKS 入口可用。若 curl 成功而 Git 失败,应检查 Git 自身配置;若 Git 成功而 Docker 失败,优先检查 daemon;若显式代理成功但 TUN 失败,则应回到虚拟网卡、路由和 DNS 设置。
| 现象 | 日志表现 | 优先排查方向 |
|---|---|---|
| curl 显式代理成功,直接访问失败 | 显式命令有连接,直接命令无记录 | 环境变量、系统代理或应用是否读取代理 |
| 终端成功,Docker pull 失败 | Clash 没有看到 daemon 的请求 | Docker Desktop 或 Docker Engine 的服务代理 |
| TUN 开启后内网服务失效 | 内网域名被代理或 DNS 返回异常 | LAN 规则、NO_PROXY、strict-route 与 DNS |
| Git HTTPS 成功,SSH 失败 | 只有 SSH 连接超时或拒绝 | SSH 端口、ProxyCommand 和远端协议 |
| 编辑器主页正常,AI 功能失败 | 部分 API 域名超时或规则命中 DIRECT | 应用代理、后台进程和服务域名规则 |
开发者代理常见问题
系统代理和 TUN 要同时开启吗?
不一定。系统代理适合浏览器和明确支持代理的程序,TUN 适合接管不读取系统代理的应用。首次排查建议先只启用系统代理,确认端口、节点和规则正常后再测试 TUN。日常使用时可以根据是否存在绕过系统代理的工具决定是否同时开启,但要留意重复接管、路由冲突和内网访问异常。
为什么浏览器能访问,Git 仍然失败?
浏览器通常读取系统代理,而 Git 可能使用 HTTPS、SSH 或独立的全局代理配置。先用 git remote -v确认远端协议,再分别检查 Git 的 http.proxy、https.proxy 和 SSH 配置。若 Git 配置中还保留着已经关闭的 127.0.0.1 端口,删除旧配置或重新设置为当前端口。
为什么终端变量生效,Docker 仍然无法拉取镜像?
Docker daemon 通常是独立服务,不会自动继承当前终端的环境变量。Docker Desktop 应检查应用级网络设置,Linux Docker Engine 则应检查服务级代理环境,并在修改后重载和重启 daemon。还要区分镜像拉取、镜像构建和容器运行三个阶段,它们可能需要分别配置代理。
Cursor 等 AI 工具应该使用 TUN 还是单独填写代理?
如果工具能够稳定读取系统代理,优先保持配置简单,让系统代理或 TUN 统一接管;如果只有部分功能失败,再检查应用自身代理设置和后台扩展进程。测试时应观察 Clash 连接页中的实际域名,而不是只根据编辑器主窗口是否显示在线判断。对明确的 AI 服务域名设置专用策略组,通常比长期使用全局模式更容易维护。