机场博客JICHANGBOKE.ORG

有的软件不走代理,怎么把它拉回来

作者 塔台君发布 约 4 分钟读完

系统代理只是把地址和端口写在操作系统的一个位置上,读不读由软件自己决定,它还带不了 UDP 流量。软件自己的设置里能填代理就先填,命令行用环境变量带,其余的开 TUN 模式,由客户端建一张虚拟网卡接管整机流量。

浏览器能开 YouTube,同一台机器上 Steam 的商店页转圈,git clone 卡在 0%,某个游戏的登录服务器连不上。代理没坏,是这几个软件压根没把请求交给它。

先确认它是真的没走代理

别急着改设置,先看一眼证据。Clash Verge Rev 的连接页会把当前每条连接列出来,带着目标地址、命中的规则和发起连接的进程名。让那个软件重新发起一次网络请求,去连接页里搜它的进程名。列表里没有它,说明流量根本没进内核。列表里有它但规则那一栏是 DIRECT,那是分流的事,不是本文要处理的。

手机和 iPhone 上的客户端也有类似的页面,名字多叫连接或者活动。

系统代理靠的是软件自觉

系统代理做的事只有一件,把代理服务器的地址和端口写进操作系统约定的那个位置,通常是 127.0.0.1 加客户端的本地端口,Clash Verge Rev 默认 7897,v2rayN 默认 10808。

Clash Verge Rev 的官方文档把这里讲得很直白,需要联网的应用会自发地去读这部分信息,然后原话补了一句,这是行业约定而非强制,遵不遵守取决于开发者。浏览器和大部分桌面软件会读,命令行工具、游戏、一些自带网络库的客户端软件不读。

同一份文档还写了系统代理的第二个限制,它没法代理 UDP 流量,游戏的数据包就属于这一类。所以有些软件界面上看着连上了,实际功能不通,问题出在这一层。系统代理那条术语里写了同样的两条边界。

微软商店的应用还多一道沙盒

UWP 应用是系统代理下面一种特殊情况。Clash Verge Rev 的 Windows 常见问题写明,Windows 的 UWP 应用存在沙盒机制,正常情况下访问不了 localhost,也就够不着本机那个代理端口,不管它读不读系统代理设置都一样。

官方给的办法是打开设置页的 Clash 设置分组,点 UWP 工具,在弹出的窗口里勾选需要走代理的应用,再点保存。开 TUN 模式也能绕开这道限制。

软件自己能填代理的,先填它

这一步成本最低,改完立刻生效,也不影响系统上别的程序。

Clash Verge Rev 的 macOS 常见问题里就记了一个真实例子。App Store 版本的 Telegram 默认不遵守系统代理,官方给的办法是在应用内手动设置代理,端口填 7897,或者改用官网的版本。很多软件都是这个路子,设置里翻到网络那一栏,填 HTTP 代理 127.0.0.1 和端口就行。

Git 和包管理器有自己的配置项。

git config --global http.proxy http://127.0.0.1:7897
git config --global https.proxy http://127.0.0.1:7897
npm config set proxy http://127.0.0.1:7897
npm config set https-proxy http://127.0.0.1:7897

端口换成你客户端里显示的那个。不想让它们长期走代理,把 config 换成 --unset 再执行一次就撤销了。

命令行要自己把代理带上

终端里的 curl、wget、pip 这些不读系统代理,认的是环境变量。下面三段按系统挑一段用,端口换成自己的。

Windows 的命令提示符。

set http_proxy=http://127.0.0.1:7897
set https_proxy=http://127.0.0.1:7897

Windows 的 PowerShell。

$env:http_proxy = "http://127.0.0.1:7897"
$env:https_proxy = "http://127.0.0.1:7897"

macOS 和 Linux 的终端。

export http_proxy=http://127.0.0.1:7897
export https_proxy=http://127.0.0.1:7897
export all_proxy=socks5://127.0.0.1:7897

这三段都只对当前这个终端窗口有效,关掉就没了。Clash Verge Rev 把这件事做成了功能,官方 FAQ 写明在设置页的复制环境变量类型里选好 PowerShell、Bash 或者 CMD,再右键系统托盘里的图标,选复制环境变量,粘贴到终端里执行即可。

填完验证一下,这条命令会返回一串纯文本。

curl -s https://www.cloudflare.com/cdn-cgi/trace

ip=loc= 两行。loc 是你节点落地的国家代码,说明这条命令走了代理。loc=CNip 是你家宽带的地址,说明环境变量没生效。

剩下的交给 TUN 模式

上面几样都够不着的软件,就用 TUN 模式。它的做法是建一张虚拟网卡,改写系统路由把流量引过去,Clash Verge Rev 的文档写它拦截和处理所有流量,TCP 和 UDP 都算。系统代理靠软件自觉,TUN 不问软件的意见。

开它要管理员权限。Clash Verge Rev 为此做了服务模式,文档的说法是让 TUN 模式能够以非管理员身份启动,装好服务以后日常打开就不用再输密码。Windows 上装服务可能被杀毒软件拦,macOS 上会弹窗要登录密码。

Mihomo 的 TUN 配置里有几项值得知道。

tun:
  enable: true
  stack: mixed
  dns-hijack:
    - "any:53"
  auto-route: true
  auto-detect-interface: true

stack 决定用哪一套协议栈,文档列的可选值是 system、gvisor、mixed 和 mips,默认 gvisor。system 借系统协议栈,稳定且占用低。gvisor 在用户态实现网络。mixed 是 TCP 走系统、UDP 走 gvisor。mips 是 mihomo 自研的那一套。

auto-route 自动改写全局路由。auto-detect-interface 自动选出口网卡,文档提醒多网卡设备上最好手动指定。dns-hijack 把发往 53 端口的查询截给内核自己的 DNS 模块,配套的注意事项写在 DNS 泄漏怎么查那篇里。Linux 上还有一个 auto-redirect,文档写明它自动配置 iptables 或 nftables 做 TCP 重定向,要求 auto-route 一起开。

开 TUN 的代价也要知道三条。Clash Verge Rev 的 Windows FAQ 记了打开 TUN 后网络反而不正常的情况,原因是系统里有多张网卡或者网段和配置里的规则冲突,处理办法是到网络设置里删掉多余的虚拟网卡。macOS 上开 TUN 时系统 DNS 会被改成 223.6.6.6,官方说明这是为了让 TUN 正常工作,关掉就恢复。再有就是别和另一个 VPN 或者游戏加速器同时开,两边都要改系统路由。

TUN 开着还有软件绕过去

先切全局模式试一次。能通就是分流规则没覆盖到这个域名,切回规则模式给它补一条 DOMAIN-SUFFIX 规则就行,两种模式的分工在规则模式那条术语里。全局下也不通,往下看。

有的软件自己把域名解析完,只拿一个 IP 去建连接,内核收到的时候域名已经没了,按域名写的规则全部落空。Mihomo 的域名嗅探就是为这种连接准备的,从 TLS 握手的 SNI、HTTP 的 Host 或者 QUIC 报文里把域名读回来。

sniffer:
  enable: true
  parse-pure-ip: true
  override-destination: false
  sniff:
    HTTP:
      ports: [80, 8080-8880]
      override-destination: true
    TLS:
      ports: [443, 8443]
    QUIC:
      ports: [443, 8443]
  skip-domain:
    - Mijia Cloud

parse-pure-ip 对拿不到域名的流量强制嗅探,override-destination 决定要不要拿嗅探到的域名当实际访问目标,skip-domain 用来放过那些嗅探之后反而出问题的域名,官方示例里排除的就是米家设备。

还有一条路是按进程写规则。Mihomo 的规则文档里有 PROCESS-NAME,用进程匹配,在 Android 平台上可以匹配包名。上面第一节在连接页里看到的进程名,正好拿来填这里。

手机上没有系统代理这个选项

安卓和 iPhone 上的代理客户端都是以 VPN 的身份工作的,等于一直在 TUN 模式,不存在只开系统代理的选项。对应地,这两个系统同一时间只允许一个 VPN 配置处于连接状态,再打开另一个代理应用,先前那个会被顶掉。

要控制哪些应用走代理,用客户端的分应用功能。FlClash 在工具里叫访问控制,有两种模式,一种是只让选中的应用进 VPN,另一种是把选中的应用排除在外,国内应用多的手机用排除模式省事。v2rayNG 里这一项叫分应用代理。iPhone 上没有这么细的开关,能改的是客户端里的分流规则。各家的位置不一样,客户端总览里每一页都有对应的图文步骤。

常见问题

系统代理和 TUN 模式有什么区别

系统代理是把代理服务器的地址和端口写进操作系统的设置里,愿意读这项设置的软件才会把请求发过来,Clash Verge Rev 的文档说明这是行业约定而非强制,而且它代理不了 UDP。TUN 模式是客户端建一张虚拟网卡并改写路由,TCP 和 UDP 一起接管,代价是要管理员权限,容易和别的 VPN 冲突。

开了 TUN 模式为什么有的软件还是不走代理

先看是不是分流规则的事。把模式临时切到全局再试,能通就是规则没覆盖到这个域名。还有一种是软件自己把域名解析完,只拿一个 IP 去连,域名规则全部落空,处理办法是打开 Mihomo 的域名嗅探,让内核从 TLS 握手的 SNI 里把域名读回来。

命令行里 curl 和 git 不走代理怎么办

它们不读系统代理,要自己给环境变量。Windows 的 CMD 用 set,PowerShell 用 $env,macOS 和 Linux 用 export,把 http_proxy 和 https_proxy 指到本机端口,Clash Verge Rev 默认 7897。Clash Verge Rev 还能在托盘图标右键菜单里直接复制这几条环境变量。

微软商店里下载的应用连不上代理是什么原因

UWP 应用有沙盒机制,默认访问不了本机的 localhost 地址,所以连不上代理端口。Clash Verge Rev 的官方 FAQ 给的办法是打开设置页里 Clash 设置分组的 UWP 工具,在弹出的窗口里勾选需要走代理的应用,再点保存。开 TUN 模式也能绕开这个限制。

来源

系统代理TUN分流Clash Verge Rev

接着读