tokenpls:mihomo 会跳过不支持 UDP 的规则,QUIC 可能落到 DIRECT
tokenpls 解释,mihomo 规则模式处理 UDP 时,若命中的出站不支持 UDP 会跳过该规则继续匹配,QUIC/UDP 连接可能最终落到 DIRECT;全局模式则直接交给选中节点。可在支持 UDP 的节点加 udp: true,或拒绝 UDP/443 让 QUIC 回退 HTTP/2,并说明订阅节点缺少该字段的常见原因。
作者原文@TokenPLS感谢这么详细的复现记录,你在 Connections 里的观察是对的,原因就在那里。
不是 PROCESS-NAME / 域名规则没匹配上,是匹配上之后被跳过了。
Clash 的内核是 mihomo。mihomo 在规则模式下处理 UDP 连接时,如果命中的规则指向的出站不支持 UDP(
metadata.NetWork == UDP && !adapter.SupportUDP(),见上游tunnel/tunnel.go的match),会跳过这条规则继续往下匹配;包括MATCH在内全部跳完后,连接落到DIRECT,而且不记录命中的规则(rule == nil)。所以你看到的是:同一个域名,HTTPS(TCP)命中规则走代理;QUIC(UDP/443)规则列为空、走 DIRECT,用本机出口 IP 出去,于是触发了地区检测。全局模式不做规则匹配,也就不检查节点的
udp字段:UDP 直接交给选中的节点,而 Shadowsocks、VMess、Trojan 等出站发 UDP 时并不看这个字段,服务端支持 UDP 中转的话,QUIC 就真的走了代理。这也说明你的节点服务端是支持 UDP 的,只是配置里没写udp: true,加上即可。节点为什么不带 UDP:mihomo 里 Shadowsocks、ShadowsocksR、VMess、VLESS、Trojan、Snell、SOCKS5、AnyTLS、Mieru 等出站转不转发 UDP,由节点的
udp字段决定,不写就是不转发;HTTP/HTTPS 代理本身没有 UDP。订阅转换出来的节点常常没写udp: true。解决办法(任选其一)
- 服务端支持 UDP 的话,给节点加上
udp: true,QUIC 就会按规则走代理:yaml proxies: - name: JP-01 type: ss # ... udp: true- 把 QUIC 拒掉,让客户端退回 HTTP/2 走代理。在自定义规则(或
rules最前面)加一条:
```yaml
- AND,((NETWORK,UDP),(DST-PORT,443)),REJECT
``如果只想拦截原本会漏到 DIRECT 的那部分,可以把这条放在MATCH` 之后:前面指向 DIRECT 的 UDP 规则照常命中,只有被跳过的 UDP 才会落到它。这是上游 mihomo 的既有行为,Clash 1.0.16 (139) 及以后的 Mac 版行为不变,用上面任一写法即可。