开发者必备:用Clash TUN打通Git与npm终端代理工作流
先分清 TUN 与终端代理变量的分工
运行 git clone、npm install 或 pip install 时,命令行程序不一定会读取 Windows、macOS 或 Linux 的系统代理设置。浏览器能打开目标网站,只能说明浏览器的请求路径可用,不能证明终端进程也会自动使用同一个代理。
mihomo 的 TUN 模式通过虚拟网卡和路由接管 IP 流量,适合处理没有代理选项、没有读取系统代理,或直接发起 TCP、UDP 连接的程序。HTTP 代理环境变量则是另一条入口:程序主动连接本机代理端口,再由 mihomo 按规则转发。两种方式可以配合,但职责不同;排查时建议先分别测试,避免同时修改路由、环境变量和应用配置。
| 工作方式 | 适用情况 | 需要留意 |
|---|---|---|
| TUN 接管 | 程序忽略系统代理,直接连接远端地址 | 依赖虚拟网卡、路由、权限及客户端内核支持 |
HTTP_PROXY 等变量 | Git、npm、pip 等支持代理设置的命令行程序 | 变量只影响读取它的进程,不能代替 TUN |
| 应用或守护进程单独设置 | Docker Engine、特定容器或独立构建服务 | 配置位置可能不在当前终端会话中 |
| Git SSH 代理设置 | 远程地址使用 git@host:group/repo.git | HTTP 代理变量通常不会自动代理 SSH 的 TCP 连接 |
开启 TUN,并核对 mihomo 配置
本文示例面向运行 mihomo 内核的客户端,例如提供 mihomo 支持的 Clash Verge Rev。旧版 Clash 内核、不同客户端版本和不同操作系统的字段支持不完全相同。开始前记录客户端与内核版本,并备份配置。桌面客户端可能通过设置页管理 TUN,或在启动内核时生成相关字段;如果客户端接管这些设置,应优先使用界面,不要再添加相互冲突的第二份配置。
以下是 mihomo 的 TUN 配置片段,用于核对配置结构,不是可直接替换的完整订阅。把它合并到当前配置的同名顶层字段中,避免重复出现两个 tun 或 dns 区块。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
auto-route 用于自动配置路由接管,auto-detect-interface 帮助内核选择出站网卡;具体行为仍取决于系统和客户端的集成方式。Windows 上通常需要安装或启用客户端提供的服务组件,并在系统授权提示中确认程序来源。Linux 上可能需要相应的网络管理权限;macOS 上则应按客户端提供的系统扩展或网络权限流程操作。服务安装成功与 TUN 已经正确接管流量是两件事,仍需实际验证。
- 先关闭其他 VPN、虚拟网卡代理或第二个 TUN 客户端,减少默认路由和 DNS 配置冲突。
- 在 Clash 客户端中启用 TUN,等待内核重载完成;检查界面与日志中是否出现启动失败或权限错误。
- 打开连接面板,观察终端发起请求时是否出现目标连接、命中规则和实际出站。
- 确认普通网页与开发目标都能访问后,再决定是否需要额外设置代理环境变量。
规则模式下,TUN 负责把连接送进内核,rules 决定连接走 DIRECT、策略组还是其他出站。可以在现有规则中为开发目标增加明确规则,但策略组名称必须使用配置里真实存在的名称。以下仅示意规则格式,不能不检查顺序就覆盖订阅原有规则:
rules:
- DOMAIN-SUFFIX,github.com,节点选择
- DOMAIN-SUFFIX,registry.npmjs.org,节点选择
- MATCH,原有兜底策略
规则按列表顺序匹配,新增项应放在可能提前匹配这些域名的宽泛规则之前。若规则集已经处理了代码托管平台或 npm 域名,先检查连接面板的实际命中结果,不必重复添加。Git 使用 SSH 地址时,连接目标通常是 TCP 22 端口,未必带有可供域名规则使用的 TLS 主机名信息;不能假设 DOMAIN-SUFFIX 一定能识别所有 SSH 连接。可优先使用 HTTPS 远程地址,或针对 SSH 单独验证 TUN 的 DNS 映射、进程规则和实际连接记录。
给 Git、npm 与 pip 配置显式代理
如果终端工具支持 HTTP 代理,显式配置本机代理端口通常更容易诊断。先在客户端查看当前有效的混合端口;下面用 7890 举例,它不是所有配置的固定值。启用 mixed-port 时,同一端口通常接受 HTTP 与 SOCKS 代理连接;若配置只有单独的 port 或 socks-port,应按实际监听类型调整。
在 macOS 或 Linux 的 Bash、Zsh 中,可以先为当前终端会话设置环境变量。将端口替换为客户端显示的实际值:
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
curl -I --connect-timeout 10 https://example.com/
这里的 HTTPS_PROXY 常见写法仍是 http://,因为它表示先连接本地 HTTP 代理,再由代理建立 HTTPS 隧道;它不是把本地代理协议自动改成 HTTPS。curl 返回响应只能证明这次显式代理请求完成,仍应在 mihomo 连接面板确认实际命中的规则与出站。PowerShell 可使用 $env:HTTPS_PROXY='http://127.0.0.1:7890' 设置当前会话变量;关闭终端后,该会话设置通常不会保留。
Git 支持通过环境变量或自身配置使用 HTTP 代理。若希望只在当前终端测试,先设置上述环境变量并执行 git ls-remote 或一次小型克隆;若要长期保存,可使用 Git 配置:
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 http.proxy
git config --global --get https.proxy
Git 的 HTTP 代理设置只适用于 HTTP(S) 远程地址。先运行 git remote -v 查看仓库地址:以 https:// 开头的地址可用上述配置测试;以 git@ 开头的 SSH 地址不会因为设置 http.proxy 就自动转换成 HTTP 代理。若不再需要 Git 的全局代理,使用 git config --global --unset http.proxy 和 git config --global --unset https.proxy 清除,避免以后在不同网络下出现意外代理行为。
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
排查时先查看 npm config get registry,并确认请求的 registry 域名在连接面板中的命中结果。自定义镜像、企业私有 registry、依赖中的 Git 地址可能走不同域名或协议。不要把带认证信息的 registry 地址或令牌复制到公开日志。测试结束后,若只打算使用 TUN,可清除 npm 的持久代理设置:npm config delete proxy 与 npm config delete https-proxy。
pip 常见做法是在当前命令中传入代理,避免不必要地修改全局配置:
python -m pip --proxy http://127.0.0.1:7890 install 包名
也可以在当前终端设置 HTTPS_PROXY,但不同 Python 版本、pip 版本和自定义下载器的行为可能不同,应以实际命令输出和连接记录为准。公司内部包源可能要求证书、认证或专用网络;不要为了绕过证书错误而随意使用关闭 TLS 校验的参数。
Docker daemon 与容器流量要单独检查
docker pull 看起来是在终端执行,实际下载镜像通常由 Docker daemon 或 Docker Desktop 背后的虚拟机网络完成。当前终端里设置了 HTTPS_PROXY,不代表守护进程一定会继承这些变量。Docker Desktop、Linux 原生 Docker Engine、远程 Docker context 的网络边界也不同;先用 docker context show 确认命令连接的是本机还是远程引擎。
若 curl 经本机代理成功而 docker pull 超时,先判断失败发生在 daemon、代理镜像站还是容器网络。桌面端应查看 Docker Desktop 的代理设置;Linux Engine 则根据发行版的 systemd 服务配置为 Docker daemon 设置代理环境,并在修改后重载服务。配置方式会随安装环境而异,不建议直接把某一发行版的 systemd 文件照搬到所有系统。
- 分别测试终端中的显式代理请求、
docker pull与容器内部请求,不能用其中一个成功推断其余路径也已接通。 - 在 mihomo 连接面板核对镜像仓库域名、规则命中和出站。镜像拉取可能访问多个认证、存储或 CDN 域名。
- 如果只在容器内失败,检查 Docker 网络、DNS、容器代理变量及目标服务访问策略;主机 TUN 的行为不一定等同于容器自己的出站配置。
- 若构建使用远程 Docker daemon,代理应配置在实际执行构建和拉取镜像的那台主机上。
对接管范围有要求时,优先采用 Docker 官方界面或守护进程支持的代理配置,并用最小测试确认生效。不要为了让一次拉取成功就向公网开放 Clash 监听端口,也不要把代理认证密码直接写入公开的镜像构建文件或提交到代码仓库。
按顺序定位:从本机端口到目标出站
遇到依赖下载失败时,建议每次只改一个变量,并记录命令、时间、错误信息和连接面板结果。先验证本机代理端口,再判断应用是否使用代理,最后才调整分流规则。端口通、代理请求失败与目标站认证失败,是不同阶段的问题。
- 确认监听端口:核对客户端配置中的实际端口,并检查终端所用地址是否为
127.0.0.1。端口不监听时,修改 Git 或 npm 规则无法解决连接被拒绝。 - 验证显式代理:用
curl --proxy http://127.0.0.1:端口 https://example.com/做一次请求。若失败,查看客户端日志、当前节点和目标规则。 - 验证应用请求:分别运行 Git、npm、pip 或 Docker 的最小请求。Git 的远程协议、npm 的 registry 和 Docker daemon 可能使用不同连接路径。
- 查看连接记录:确认目标域名、命中规则、策略组和最终节点。显示
DIRECT时先检查规则顺序;显示代理出站但连接失败时,再检查节点和目标服务。 - 对照 TUN 与显式代理:暂时移除应用级代理配置,单独测试 TUN;再恢复代理变量做对照。不要同时切换节点、DNS、规则和 TUN 参数。
- 完成清理:删除临时环境变量或不再需要的 Git、npm 持久配置,确认终端新进程读取的是预期设置。
| 现象 | 优先检查 | 避免的误判 |
|---|---|---|
| 连接本机端口被拒绝 | 客户端运行状态、监听端口和协议 | 不是先改远端域名规则 |
curl 成功,Git 失败 | 远程地址是 HTTPS 还是 SSH、Git 独立配置 | 不代表 Git 一定读取系统代理 |
| npm 报 registry 超时 | registry 地址、代理设置和规则命中 | 不代表所有 npm 依赖都使用同一域名 |
docker pull 失败 | Docker context、daemon 或 Docker Desktop 代理 | 终端变量不等于 daemon 已配置 |
连接显示 DIRECT | 规则顺序、域名解析及匹配结果 | 切换节点不会改变 DIRECT 规则 |
如果仍无法定位,收集脱敏后的客户端内核日志、失败命令、目标域名、当前规则模式以及连接面板中对应请求的出站信息。分享前删除订阅 URL、节点密码、访问令牌、私有仓库地址和包含个人路径的日志。不要把完整环境变量输出到公开问题中,因为其中可能含有认证凭据。
常见问题
开了 TUN,为什么 Git clone 还是失败?
先确认失败的远程地址是 HTTPS 还是 SSH,并在连接面板查找对应请求。HTTPS 通常更容易通过 HTTP 代理变量或常规域名规则验证;SSH 使用独立的 TCP 连接,http.proxy 不会自动代理它。还要检查 TUN 是否启动、域名解析是否进入 mihomo,以及规则是否把目标交给了预期出站。
使用 TUN 后还需要设置 HTTP_PROXY 吗?
不一定。TUN 的目标是接管 IP 流量,支持代理变量的工具也可以显式连接本机代理。为了排查路径,先只启用其中一种方式;如果希望应用明确使用代理,设置环境变量也可作为补充。确认本机端口与规则后,注意避免应用代理配置与 TUN 规则相互叠加造成误判。
为什么 curl 能下载,Docker 却拉取失败?
两者可能不在同一个网络进程边界内。curl 运行于当前终端,Docker 镜像拉取通常由 daemon 或 Docker Desktop 虚拟机发起。检查 Docker context、桌面端代理或 Linux daemon 配置,并在连接面板中查看镜像仓库实际访问的域名。
可以把所有开发域名都强制走代理吗?
不建议仅凭工具名称把所有连接都改成代理出站。私有 Git 服务、公司制品库和局域网镜像可能要求直连;公共 registry 也可能跳转到不同存储域名。按连接记录添加最小范围规则,并确认规则顺序、策略组名称和 DNS 结果,再检查实际出站。