各位佬好,我遇到了一个WebRTC泄露的问题,折腾了两晚上没解决,来请教一下大家。
我用的是Android系统,常用的浏览器是基于内置WebView的Via浏览器。之前一直用Nekobox代理,也没有出现WebRTC泄露真实IP的问题。最近因为负载均衡等需求,就换成了Clash Meta for Android,用的是 Loyalsoldier/clash-rules 这个分流规则。
问题来了,DNS不漏,但WebRTC总是泄露。我在以下两个网站测试了一下:
结果发现真实IP都漏了。Android的VPN服务是几乎接管所有流量的模式,按理来说,WebRTC的STUN请求应该走代理,而不是直连才对。
为了确认是不是分流规则导致的WebRTC泄露,我直接把Clash规则简化到只保留一条“- MATCH,PROXY”,确保所有流量都走的PROXY出口。重新测试,结果真实IP还是漏了。想到WebRTC基于UDP,我又在 Proxy 和 Proxy Group 里禁用了所有UDP流量,并在规则里写了UDP Reject。结果还是一样,IP泄露。
更奇怪的是,当我恢复所有分流和规则,开启Global全局模式时,WebRTC居然不直连了。这是个什么情况?但不管怎样,Global模式总不能一直开,不然国内网站的延迟高得离谱,CDN资源还会反向优化到国外。
现在的问题是,不更换代理客户端和浏览器的前提下,Clash应该怎么设置才能Reject所有WebRTC连接?另外像桌面端有相关禁用WebRTC的插件,那Android基于WebView的浏览器(比如Via)有办法禁止WebRTC吗?
2 Likes
原始状态如下,很简洁的一个配置文件
port: 7890
socks-port: 7891
allow-lan: true
mode: rule
log-level: info
external-controller: 127.0.0.1:9090
proxies:
- name: test
server: xxx
port: 443
client-fingerprint: random
type: vless
uuid: xxx
tls: true
tfo: false
skip-cert-verify: false
servername: xxx
network: ws
ws-opts:
path: "/xxx"
headers:
Host: xxx
proxy-groups:
- name: PROXY
type: select
proxies:
- test
- DIRECT
rule-providers:
reject:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/reject.txt"
path: ./ruleset/reject.yaml
interval: 86400
icloud:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/icloud.txt"
path: ./ruleset/icloud.yaml
interval: 86400
apple:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/apple.txt"
path: ./ruleset/apple.yaml
interval: 86400
google:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/google.txt"
path: ./ruleset/google.yaml
interval: 86400
proxy:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt"
path: ./ruleset/proxy.yaml
interval: 86400
direct:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/direct.txt"
path: ./ruleset/direct.yaml
interval: 86400
private:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/private.txt"
path: ./ruleset/private.yaml
interval: 86400
gfw:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/gfw.txt"
path: ./ruleset/gfw.yaml
interval: 86400
tld-not-cn:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/tld-not-cn.txt"
path: ./ruleset/tld-not-cn.yaml
interval: 86400
telegramcidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/telegramcidr.txt"
path: ./ruleset/telegramcidr.yaml
interval: 86400
cncidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/cncidr.txt"
path: ./ruleset/cncidr.yaml
interval: 86400
lancidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/lancidr.txt"
path: ./ruleset/lancidr.yaml
interval: 86400
applications:
type: http
behavior: classical
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/applications.txt"
path: ./ruleset/applications.yaml
interval: 86400
rules:
- DOMAIN,clash.razord.top,DIRECT
- DOMAIN,yacd.haishan.me,DIRECT
- RULE-SET,private,DIRECT
- RULE-SET,reject,REJECT
- RULE-SET,icloud,DIRECT
- RULE-SET,apple,DIRECT
- RULE-SET,google,PROXY
- RULE-SET,proxy,PROXY
- RULE-SET,direct,DIRECT
- RULE-SET,lancidr,DIRECT,no-resolve
- RULE-SET,cncidr,DIRECT,no-resolve
- RULE-SET,telegramcidr,PROXY,no-resolve
- GEOIP,LAN,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- MATCH,PROXY
首先感谢 @xjp666 大佬的帮助,因为我是新人,无法一天内连续回帖,大佬很热心地在私聊频道帮我分析了包括分流和DNS在内的各种原因。
关于解决方案,其实很魔幻。昨晚和大佬分析了一通没解决,我打算去CMFA提个Issue,结果发现这个Repo的Issue区已经被关闭了。本以为这问题没办法解决了,突然发现有个刚刚新鲜出炉的Release,更新文档很长,主要是修复和适配Meta内核的一些特性。更新后,就用主楼提到的UDP规则,配置文件都没动,这次WebRTC稳稳的不泄露了。升级更新解君愁啊!
唯一遗憾的是CFMA还保留了一些Bug,比如同样配置的WireGuard在Clash Verge Rev能用,但在Clash Meta for Android上就不行。看CMFA讨论区,这个Bug已经存在很久了,希望能尽早修复。
1 Like
呃呃,主楼里已经说了解决方案啊。节点和节点组不支持udp的,请直接disable,同时在rule那里加上udp类型直接reject的规则
@xjp666 大佬给出了一个详细的分析和解决方案,比我直接reject的好,我请他过来发一下。
不是不是,我的问题,没看懂并不是你的问题。
这样说,webrtc是基于udp的,因此对于不支持UDP的节点,可以在proxy加udp: false
,在proxy group加disable-udp: true
,在rules加- NETWORK,udp,RECJET
来实现。
真诚、友善,不懂的欢迎继续问。另外 @xjp666 大佬估计不在线,他的方案更完善,可以等他发帖,我就不班门弄斧啦。
1 Like
xjp666
(rm -rf)
August 1, 2024, 10:31am
15
刚刚测试复现了这个问题,原因是有些节点不支持 udp,匹配不了所有规则,导致 clash 走直连,关键日志文件如下:
level=debug msg="PROXY UDP is not supported"
level=info msg="[UDP] 198.18.0.1:49681 --> stun.nextcloud.com:443 doesn't match any rule using DIRECT"
level=debug msg="[Rule] use default rules"
level=debug msg="PROXY UDP is not supported"
level=info msg="[UDP] 198.18.0.1:49759 --> jp1.stun.twilio.com:3478 doesn't match any rule using DIRECT"
level=debug msg="PROXY UDP is not supported"
level=info msg="[UDP] 198.18.0.1:49765 --> stun.syncthing.net:3478 doesn't match any rule using DIRECT"
level=debug msg="PROXY UDP is not supported"
level=info msg="[UDP] 198.18.0.1:49695 --> us1.stun.twilio.com:3478 doesn't match any rule using DIRECT"
level=debug msg="[Rule] use default rules"
level=info msg="[UDP] 198.18.0.1:49749 --> stun.nextcloud.com:443 doesn't match any rule using DIRECT"
level=debug msg="[Rule] use default rules"
level=info msg="[UDP] 198.18.0.1:49697 --> stun.syncthing.net:3478 doesn't match any rule using DIRECT"
level=debug msg="[Rule] use default rules"
level=info msg="[UDP] 198.18.0.1:49725 --> jp1.stun.twilio.com:3478 doesn't match any rule using DIRECT"
level=debug msg="PROXY UDP is not supported"
level=info msg="[UDP] 198.18.0.1:49685 --> stunserver.stunprotocol.org:3478 match GeoIP(lan) using DIRECT"
level=debug msg="PROXY UDP is not supported"
其中 PROXY 为代理节点分组,选中的节点不支持 udp:
PROXY UDP is not supported
结果是走直连:
doesn't match any rule using DIRECT
解决方法1:
出站代理 udp 设置为 true( 默认为 false),
https://wiki.metacubex.one/config/proxies/#udp
https://wiki.metacubex.one/config/rules/#_2
方法1只适用支持 udp 的代理,但是没有设置 udp 为 true 的情况
解决方法2:
在规则最后加上一条兜底:
NETWORK,udp,REJECT
代理不支持 udp 则拦截数据出站,以避免 WebRTC 泄露
参考:
https://github.com/MetaCubeX/mihomo/issues/945
https://github.com/MetaCubeX/mihomo/pull/178
2 Likes
可以换个思路,家里用paopaodns.然后配置远程dns直接走外面查询。 这样就肯定不漏了
感觉和DNS关系不大,完全交给远程查询能确保DNS不漏,但是对WebRTC,如果出口代理不支持UDP,仍会因为Clash默认Compatible的策略回退到Direct导致漏真实IP。这点也是Clash被诟病已久的地方。(另外Clash还会默认出口代理的UDP支持为True,所以特别容易漏 )