GitHub clone 卡住、npm 安装超时、pip 下载失败或 Docker 拉取镜像报错,原因不一定是节点不可用。命令行程序、代理环境变量、Docker 后台服务和系统网络栈可能采用不同的连接路径;浏览器能打开网页,也不能证明这些请求已经进入 Clash。
本文以 mihomo 内核常见配置为例。Clash Verge、Clash Verge Rev 等客户端的菜单位置、内核版本和配置覆写方式可能不同;先确认当前内核支持 TUN,并查看运行配置中的实际端口。TUN 是通过虚拟网卡接管设备 IP 流量的方式,和只让应用主动使用的 HTTP/SOCKS 代理端口不是一回事。
开发者用Clash配置TUN模式:Git、npm与Docker命令代理实战指南
先分清 TUN 接管与终端显式代理
TUN 处理的是设备网络流量,终端代理设置处理的是应用发出的代理请求。启用 TUN 后,内核创建虚拟网卡并根据路由将符合条件的流量交给规则处理;Git、npm 等工具也可以通过代理环境变量或自身配置,主动连接本机 HTTP 代理端口。两种方式可以互补,但不应在不了解连接路径时层层叠加,否则容易出现代理循环、重复转发或流量走向难以判断。
- 系统代理:设置操作系统的 HTTP 代理地址和端口。遵循系统设置的应用可能使用它,命令行工具不一定会自动读取。
- TUN 模式:从网络层接管流量,适合不支持代理设置、使用原生网络接口的程序;实际效果受路由、DNS 和权限影响。
- 终端环境变量:通过
HTTP_PROXY、HTTPS_PROXY等变量告诉部分程序主动连接代理端口,不等同于开启 TUN。 - 应用专属配置:Git、npm、pip 可以各自保存代理设置;Docker 拉取镜像通常由守护进程或 Docker Desktop 后台组件发起。
如果只需要让开发工具访问代理,可先用环境变量或应用设置,方便确认效果和撤销。若还要接管不读取代理配置的程序,再考虑 TUN。不要把 127.0.0.1:7890 当作所有安装的固定端口:它只是示例,必须换成客户端当前监听的 HTTP 或 mixed 端口。
启用 TUN 前检查内核、权限与路由
打开客户端的「设置」「内核」或「网络」页面,确认运行的是支持 TUN 的 mihomo 版本,并在客户端提供的 TUN 开关中启用。某些客户端会安装或启动特权服务;首次启用时按系统提示授权。菜单名称和位置因版本而异,找不到对应选项时先查看使用文档,不要直接把另一款客户端的操作路径套过来。
如果使用自己维护的 mihomo 配置,可参考下面的字段结构。它用于说明关键选项,不是完整配置;应合并到现有 YAML 的顶层 tun 项,不要在已有配置中重复定义同名顶层字段。先确认当前内核版本支持这些字段,并保留原配置副本。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
enable控制是否启用 TUN;有些客户端会通过界面生成或覆写这个值。stack选择网络栈实现。示例中的mixed并非所有版本和系统都适用;遇到兼容问题应查看当前内核文档及日志。auto-route用于配置自动路由;auto-detect-interface帮助内核识别出口网卡。多网卡、虚拟机、VPN 或容器网络环境可能需要额外检查。dns-hijack用于处理匹配的 DNS 请求,不代表所有加密 DNS、应用内置 DNS 或 DoH 请求都会自动变成普通 DNS。
启用后先观察客户端的 TUN 状态和内核日志,再测试一个已知可用的目标。若局域网打印机、公司内网或本地开发服务不可达,检查规则和路由是否把私网地址送进代理;不要为了“全接管”盲目开启严格路由或排除所有网段。退出 TUN 后仍无法联网时,先正常关闭客户端并等待路由恢复;若仍异常,重启网络或系统,再检查是否有残留虚拟网卡或其他 VPN 服务。
给终端设置临时代理并确认请求路径
先查客户端当前 HTTP 或 mixed 端口,再在同一个终端会话中设置环境变量。以下以 macOS、Linux 的 Bash/Zsh 为例,端口 7890 仅为示例;Windows PowerShell 使用第二段命令。环境变量只影响相应进程及其子进程,不会改写 TUN 路由。
export HTTP_PROXY="http://127.0.0.1:7890"
export HTTPS_PROXY="http://127.0.0.1:7890"
export ALL_PROXY="socks5h://127.0.0.1:7891"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export all_proxy="$ALL_PROXY"
$env:HTTP_PROXY = "http://127.0.0.1:7890"
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:ALL_PROXY = "socks5h://127.0.0.1:7891"
第二段中的 SOCKS 端口 7891 同样只是示例;仅当客户端确实监听 SOCKS 代理时才使用。也可以只设置 HTTP/HTTPS 变量,避免误填未启用的 SOCKS 端口。变量名称的大小写兼容性因程序而异,所以示例同时设置大小写形式;如果命令行工具本身另有代理配置,应用专属配置可能优先。
用 curl 做一次对照测试。把目标换成自己有权访问且可以确认状态的 HTTPS 地址;若连接失败,查看客户端连接面板是否出现请求,再判断是本地端口、规则、节点还是 DNS 问题。
curl -I --max-time 15 https://example.com
确认环境变量不再需要时,在 Bash/Zsh 中执行 unset HTTP_PROXY HTTPS_PROXY ALL_PROXY http_proxy https_proxy all_proxy;PowerShell 中可用 Remove-Item Env:HTTP_PROXY,Env:HTTPS_PROXY,Env:ALL_PROXY -ErrorAction SilentlyContinue。当前终端关闭后,临时变量通常随会话结束。若写入 shell 启动文件,则要从对应文件中删掉并重新打开终端。
分别排查 Git、npm 与 pip
即便 TUN 已启用,应用本身设置的代理仍可能绕开预期规则或连接到错误端口。按一个工具、一个目标逐项测试,不要同时更换节点、代理模式和多个环境变量。下面的命令都使用示例端口,应按实际情况替换。
Git:区分 HTTPS 与 SSH 地址
对于 HTTPS 克隆,可先在当前仓库设置代理,验证成功后再决定是否设为全局:
git config --local http.proxy http://127.0.0.1:7890
git config --local --get http.proxy
git clone https://github.com/example/project.git
如果要撤销当前仓库的设置,执行 git config --local --unset http.proxy。用 --global 设置会影响当前用户的所有仓库,排查时通常先避免全局修改。HTTPS 代理配置不会自动解决 SSH 地址的连接问题;SSH 克隆走 SSH 协议和端口,需单独检查 SSH 配置、网络路径或使用 HTTPS 地址做对照。
npm:核对 registry 与代理字段
npm 可以从环境变量读取代理,也可以使用自身配置。先查看当前值,避免已有设置指向过期端口:
npm config get registry
npm config get proxy
npm config get https-proxy
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890
npm ping
若安装成功,记录改动范围;不需要持久配置时执行 npm config delete proxy 和 npm config delete https-proxy。网络失败也可能来自 registry 地址、证书或包源自身;检查 npm 输出中的目标域名及客户端连接记录,不要用关闭 TLS 校验来绕过证书错误。
pip:把代理作用域控制在需要的环境
可先用环境变量进行单次验证,或给当前用户配置 pip。命令中的代理地址仍需替换为真实监听端口:
python -m pip install --proxy http://127.0.0.1:7890 package-name
python -m pip config set global.proxy http://127.0.0.1:7890
python -m pip config list
全局配置会影响该用户之后运行的 pip 请求;完成排查后,可用 python -m pip config unset global.proxy 撤销。虚拟环境通常共享用户级 pip 配置,但具体读取优先级还会受到配置文件、命令参数和环境变量影响。若只有某个包失败,先查看完整错误:解析失败、TLS 校验失败、连接超时和包版本不存在应分别处理。
Docker 拉取失败:检查发起请求的后台服务
docker pull 通常由 Docker 守护进程或 Docker Desktop 后台组件连接镜像仓库。终端里设置了代理变量,不代表后台服务也继承了它;Docker CLI 与守护进程是不同进程。TUN 若已正确接管宿主机流量,守护进程的连接可能经由 TUN 路由,但仍要确认 DNS、规则和网络实现没有冲突。
- Docker Desktop:在应用设置中查看网络或代理选项,确认其使用系统代理、自定义代理还是直连。修改后按提示重启后台服务,再查看 Docker Desktop 日志。
- Linux Docker Engine:如果要给守护进程设置 HTTP/HTTPS 代理,应通过系统服务的环境配置方式设置,再重新加载 systemd 并重启 Docker 服务。不要只在交互式 shell 中导出变量,就认为守护进程已经读取。
- 容器内部请求:镜像拉取与容器运行后访问网络是两件事。容器内应用的代理变量、Docker 网络和宿主机 TUN 路由需要分别检查。
先用 docker pull 测试常用镜像仓库,再查看客户端连接记录和 Docker 服务日志。如果客户端完全没有对应连接,优先查守护进程是否能到达宿主机网络、后台是否使用了独立代理设置;若连接已出现但超时,再检查规则命中策略、DNS 解析、节点状态和仓库端响应。不要把 Docker Hub 限流、镜像名称拼写错误或仓库鉴权失败都归因于 Clash。
| 现象 | 优先检查 | 验证方法 |
|---|---|---|
| 所有命令都连接超时 | 端口、TUN 状态、DNS 与当前节点 | 确认本地端口监听,再看连接面板是否出现请求 |
| 浏览器正常,Git 或 npm 失败 | 程序是否读取系统代理、环境变量或专属配置 | 检查工具配置,并用 curl 对同一目标做对照 |
| HTTPS 克隆成功,SSH 克隆失败 | SSH 地址使用的协议与端口 | 换 HTTPS 地址验证,单独检查 SSH 网络路径 |
| Docker pull 失败,终端 curl 成功 | Docker 后台服务的代理与网络设置 | 查看 Desktop 或守护进程日志,而非只检查当前 shell |
| 能连接但局域网服务不可用 | 分流规则、私网路由及严格路由设置 | 先暂时关闭 TUN 做对照,再逐项调整路由 |
常见问题
开了 TUN,还要设置系统代理吗?
不一定。TUN 可以处理经路由接管的 IP 流量,系统代理则供主动遵循系统设置的应用使用。先用连接记录确认目标程序的流量路径;如果已由 TUN 正常接管,无须为了“让所有程序都代理”而重复设置。部分程序会自行读取或忽略系统代理,仍需独立验证。
TUN 显示已开启,为什么 Git 仍超时?
检查 TUN 是否真正启动、客户端是否获得所需权限、Git 使用的是 HTTPS 还是 SSH,以及目标域名命中的策略组。再确认 DNS 解析结果和节点连接情况。若客户端连接列表没有 Git 对应请求,可能是路由未接管、使用了不同网络接口,或 Git 在连接代理端口之前就失败。
给终端设置 HTTP_PROXY,Docker 就会使用吗?
不能据此判断。镜像拉取多由 Docker 守护进程或 Docker Desktop 后台服务发起,它们可能不继承当前终端的环境变量。应在相应后台服务或 Desktop 设置中检查代理,也可以确认 TUN 是否接管了该服务的网络流量。
日常开发应该优先用 TUN 还是应用代理?
只需让 Git、npm 或 pip 访问指定网络时,先用环境变量或应用配置,范围清晰、撤销方便。需要覆盖不支持代理设置的程序,或多个工具都必须经过相同路由时,再测试 TUN。无论采用哪种方式,都要通过连接记录验证实际出口,并保留可以恢复的配置副本。