Closed KobeArthurScofield closed 8 months ago
domainStrategy
。感谢回复,前来补充细节。如有问题还请不吝指教。
以下日志因为隐私原因做了打码及筛选,如果需要完整日志可以私发。
客户端分流及 DNS 查询规则为黑名单(优先 direct),使用加强版 geosite 和 geoip,代理 geosite:gfw
geoip:google
规则,没有 block。
所有域名(不管直连还是代理)均使用 FakeDNS。
使用的可连通 ts 服务器在国内直连,无法正常连通 ts 服务器在 GCP 上,因为 IP 匹配被代理(如果直连则是没问题的)。
尝试在 Windows 下复现这个问题,但是目前 Xray 尚未集成 TUN,额外使用其它组件会因为其它原因难以复现成功。 (目前来说最稳定复现的目前为手机上使用 v2rayNG 并启用 FakeDNS)
关于客户端 fake DNS 的 UDP 问题,请测试最新的 commit 的修改。
替换客户端和服务端仍然没有解决。客户端使用 FakeDNS 时直连不受影响。
如果你认为在代理 UDP 时传送域名目标地址到服务器会引起问题,想要总是发送 IP 目标地址到服务器的话,建议实现 outbound 的
domainStrategy
。
这个应该也算一个解决办法。当然如果服务端也有 UDP 域名对 IP 映射转换这个似乎也不是问题(似乎也能根据服务器的情况灵活调整)。
fake DNS 对于依赖正确 IP 地址的使用场景(以及 STUN 之类)无能为力。
如果客户端下接的应用对 IP 要求很高(比如需要验证正确的对端地址)的确有问题。不过下接的应用如果不严格验证 IP 的话(只需保持使用时一致即可) FakeDNS 依然是个不错的解决办法,考虑到 sniffer 并不能完全识别所有协议的情况。
https://sekai.icu/posts/udp-fqdn-in-transport-proxy/ (该文章中对于 xray 的描述已过时)
似乎现在将 UDP 的目标域名直接传了上去(见日志)。
已经找到借用 sing-box 进行 TUN 接管和 DNS 查询的方法。不过这个方法需要进行全局代理,因此最后的日志会很杂。此处放出相关配置。
为了避免 Xray 自己的 FakeDNS 转换对结果发生干扰,此处使用 sing-box 作为 FakeDNS 源,由 sing-box 将域名传送给 Xray。 (不知道为什么 sing-box 也是传输域名而非 IP,歪打正着保留了域名反而方便测试。如果 sing-box 做完全的 TUN 而将 Xray 作为 FakeDNS 源、 DNS 查询和分流结果也许可能一样。)
考虑到跨版本支持的问题,送往代理的出口使用 Shadowsocks TCP+ UDP。 服务端为 Xray-core 1.8.7。
目前从 release 中下载部分版本测试(Windows x64),确认 UDP 可通的版本区间为 1.5.5 - 1.8.3,这些版本的共同特点是在将流量送往服务器前会预先解析 UDP 流量对应的域名(日志可见),尽管在日志中看起来是发送的域名,实际上应该发送了 IP 或者预先做了其它映射来方便转换。 使用的 sing-box 版本为 1.8.2,sing-box 到 Xray 的流量使用 VLESS + XUDP 传输。
看了下版本变化的记录里面似乎和 #1011 以及 #2356 有关,应该是想实现一个更好的 UDP sniff 处理逻辑但是漏了一些地方没处理。
- 如果你认为在代理 UDP 时传送域名目标地址到服务器会引起问题,想要总是发送 IP 目标地址到服务器的话,建议实现 outbound 的
domainStrategy
。
其实如果客户端的应用程序不太看重 IP 地址是否在指定的目标内而是只要使用时保持地址恒定(FakeDNS 不敏感)的话,传输域名目标地址到服务器处理似乎是更好的做法,这样的话解析策略交由服务端 ~防止出现比如客户端解析了 IPv6 地址交给了单纯的 IPv4 服务器上的服务端的尴尬行为~ 。
~问题推测:可能是服务端收到来自 inbound 的域名发往 Freedom outbound 或者 SOCKS (SOCKS5) outbound 后,回包还原时出现了问题,没有正确地将来自同一个 IP (或者及端口)返回的数据包的地址还原成域名发回给客户端,或者只还原了第一个数据包而忽略了其后的数据包(UDP 还原的时候应该以包为单位而不是流)。~
做了个新的测试,将 https://github.com/XTLS/Xray-core/issues/2962#issuecomment-1906593113 中 Xray-core 的出口设置为直连优先(相当于全部直连),这个时候本来不通的版本反而通了,~模拟服务器测试的结果否定猜测~。
想试试模拟客户端带 FakeDNS(全部代理)的结果,但是似乎总有问题导致所有版本都不通(甚至前面出发前会查询 UDP 域名的 DNS 的版本也不会查询了)(双端使用最新的 action 版本也有这个问题),还求指点。
但是如果将上面的 Xray 部分的配置改为默认直连的话情况会变成如下(依然不通):
希望不是 FakeDNS 功能跟某些地方耦合导致的问题。~理想情况下 FakeDNS 应该在入站的时候路由之前就被终结,被转换为域名,只是不知道是否出于一些局限或者性能考量所以实现上有奇怪的地方。~
客户端(mihomo)执行 curl -v --http3-only https://www.google.com.hk
server端日志:
2024/03/05 15:13:41 [Info] [3961181656] proxy/vless/inbound: received request for tcp:v1.mux.cool:0
2024/03/05 15:13:41 [Info] [3961181656] proxy: Xtls Unpadding new block, content 1224 padding 0 command 0
2024/03/05 15:13:41 [Info] [3961181656] common/mux: received request for udp:185.45.7.185:443
2024/03/05 15:13:41 [Info] [3961181656] common/mux: XUDP new [239 112 130 139 101 205 19 187]
2024/03/05 15:13:41 [Info] [3961181656] app/dispatcher: default route for udp:185.45.7.185:443
2024/03/05 15:13:41 [Info] [3961181656] proxy/freedom: connection opened to udp:185.45.7.185:443, local endpoint [::]:21523, remote endpoint 185.45.7.185:443
2024/03/05 15:13:42 [Info] [3961181656] proxy: Xtls Unpadding new block, content 1216 padding 0 command 1
执行 curl -v -I https://www.google.com.hk
server端日志:
2024/03/05 15:14:50 [Info] [110381494] proxy/vless/inbound: firstLen = 1181
2024/03/05 15:14:50 [Info] [110381494] proxy/vless/inbound: received request for tcp:www.google.com.hk:443
2024/03/05 15:14:50 [Info] [110381494] app/dispatcher: default route for tcp:www.google.com.hk:443
2024/03/05 15:14:50 [Info] [110381494] transport/internet/tcp: dialing TCP to tcp:www.google.com.hk:443
2024/03/05 15:14:50 [Info] [110381494] proxy: Xtls Unpadding new block, content 517 padding 585 command 0
2024/03/05 15:14:50 [Info] [110381494] proxy: XtlsFilterTls found tls client hello! 517
2024/03/05 15:14:50 [Info] [110381494] proxy/freedom: connection opened to tcp:www.google.com.hk:443, local endpoint [2406:ef80:1:64ea:91::a]:2673, remote endpoint [2404:6800:4005:820::2003]:443
2024/03/05 15:14:50 [Info] [110381494] proxy: XtlsFilterTls found tls 1.3! 4317 TLS_AES_256_GCM_SHA384
2024/03/05 15:14:50 [Info] [110381494] proxy: XtlsPadding 4317 122 0
2024/03/05 15:14:50 [Info] [110381494] proxy: Xtls Unpadding new block, content 235 padding 857 command 2
2024/03/05 15:14:50 [Info] [110381494] proxy: CopyRawConn readv
2024/03/05 15:14:50 [Info] [110381494] proxy: XtlsPadding 648 333 2
2024/03/05 15:14:50 [Info] [110381494] proxy: CopyRawConn splice
应该 v188 修了 如果还有问题再打开
感谢回复!至少客户端 v1.8.8 (v2rayNG 1.8.17) 下带 FakeDNS 直连的 QUIC 恢复正常了(之前似乎有问题,无法正常触发)。
不过服务端与客户端同为 v1.8.8 时 代理 QUIC 似乎无法触发(flow 为 xtls-rprx-vision-upd443,是否实际响应会偏慢的问题?), (更正:443 端口的 QUIC 正常,线路问题) 被代理的 Teamspeak 之类的应用似乎也有问题(响应似乎很缓慢)。
另外因为才想到可以用虚拟机来做客户端,然后将模拟的服务端放置在宿主机或者另一个虚拟机中,这样就可以在保证没有隐私问题的同时获得详细记录(不过 UDP 回包依然不会被 log...) 然后似乎的确还有点问题(比如 Teamspeak 依然不通,被代理的 QUIC 也可能会有问题但是大部分几率会触发)。
现在的测试如下图,用到的服务实际可以直连使用:
客户端程序 ---- sing-box (as tun2socks) ---- Xray-core (as client) ||(VM)====VLESS TCP====(Host)|| Xray-core (as server)
其中 sing-box 依然为 1.8.x,Xray-core 为 1.8.9。另外使用 Wireshark 监听通过 sing-box TUN 的数据包。作为对照,Wireshark 的采样有两份,一份是 tun + fakedns 下的采样,一份是默认无代理无其它处理的采样。
减少呈现内容起见所有内容使用附件:(测试用文件内疑似隐私信息均在处理前就隐蔽) 以下是用到的配置文件: sing-box (as tun2socks): sbox-t2s.json Xray-core (as client): xrayclient.json Xray-core (as server): xrayserver.json 以下是日志文件: sing-box: tun.txt Xray-core (client): client.txt Xray-core (server): server.txt 以下是 Wireshark 抓包,重点关注与对端 (voice.teamspeak.com) UDP 9987 端口的来回包(另外包含使用默认设置下的 Edge 浏览器访问 cloudflare-quic.com 的数据包): TUN + FakeIP: domain-throught.zip 直接连接:direct.zip
无法正常代理的 UDP 要求为在代理客户端到代理服务端传递的不是 IP 地址而是域名,即服务端接收到的 UDP 地址是域名。
如果确定不是 core 中 UDP 链路处理上的问题,可以转为 discussion 蹲一个有缘人(?)
你搞那么复杂干嘛,这种环境谁给你去看,sb_tunin-sb_socksout<->ray_socksin-ray_directout
, sb_tunin-sb_socksout<->sb_socksin-sb_directout
这两种情况本地测试抓包看下 Loopback 网卡的 SOCKS5 (以及出口网卡的流量)有什么区别,测试下你的软件对于域名地址的 UDP 请求,UDP 响应是否必须是域名地址才能工作
sb_tunin-sb_socksout.json
sb_socksin-sb_directout.json
ray_socksin-ray_directout.json
感谢回复,这个方法的确有效果
sb_tunin-sb_socksout<->ray_socksin-ray_directout
,sb_tunin-sb_socksout<->sb_socksin-sb_directout
这两种情况本地测试抓包看下 Loopback 网卡的 SOCKS5 (以及出口网卡的流量)有什么区别
如果是 sb_tunin-sb_socksout<->ray_socksin-ray_directout
的情况,发出的 SOCKS5 UDP 为域名,返回的 SOCKS5 UDP 为 FakeIP 范围内的 IP 地址(应该是 Xray-core 的 DNS 查询被 sing-box 一同劫持了),TUN 上的抓包是 FakeIP 返回,连接成功。(如果是这样的话将 sing-box 和 Xray-core 拆开到两个机器上面可能会有不一样的效果)
如果是 sb_tunin-sb_socksout<->sb_socksin-sb_directout
的情况,SOCKS5 中的 UDP 均为域名,TUN 上的抓包是 FakeIP 返回,连接成功。
切换成两个端点不同机器的话
如果是 sb_tunin-sb_socksout<->ray_socksin-ray_directout 的情况,发出的 SOCKS5 UDP 为域名,返回的 SOCKS5 UDP 为实际地址,TUN 上的抓包是真实地址返回,连接失败。
如果是 sb_tunin-sb_socksout<->sb_socksin-sb_directout 的情况,SOCKS5 中的 UDP 均为域名,TUN 上的抓包是 FakeIP 返回,连接成功。
问题描述
在使用 FakeIP 进行透明代理或者代理送出数据到服务端时附带的地址为域名的话,被代理的应用可能会出现连接问题。在单使用 Xray-core 时不影响直连。 这个问题在以下情况复现:
服务端使用 Xray-core (所有版本均在发布后三天内更新,目前为 1.8.7),搭配客户端为 Xray-core 亦或是 sing-box 时均存在。但是如果数据送入入口前已经被解析为非 FakeIP 则不受该问题影响。 服务端使用 Xray-core (所有版本均在发布后三天内更新,目前为 1.8.7)
疑似与代理 UDP 时 IP 和域名的对应处理有关。
服务端日志
``` 2024/01/22 08:39:14 [Info] [4137504723] proxy/vless/inbound: firstLen = 98 2024/01/22 08:39:14 [Info] [4137504723] proxy/vless/inbound: received request for tcp:v1.mux.cool:0 2024/01/22 08:39:14 [Info] [4137504723] common/mux: received request for udp:<被代理域名>:9987 2024/01/22 08:39:14 [Debug] app/dns: domain <被代理域名> will use DNS in order: [localhost] 2024/01/22 08:39:14 [Info] app/dns: Localhost got answer: <被代理域名> -> [错误日志提供的信息不太多。打开 access log 可能会有发现。
服务端配置(最小化)
``` yaml dns: hosts: servers: - address: localhost domains: - geosite:private skipFallback: false queryStrategy: UseIP disableCache: false disableFallback: false disableFallbackIfMatch: true tag: InternalDNSServer routing: domainStrategy: IPIfNonMatch rules: - type: field ip: - geoip:private outboundTag: blocked inbounds: - listen: "::" port: port1,port2 protocol: vless settings: clients: - id:客户端日志(v2rayNG)
``` jsonc { "dns": { "queryStrategy": "UseIP", "tag": "dns-server", "hosts": { "这个问题可能会在引入 TUN 后变得很明显,也许可以通过建立对应的域名——地址对来缓解,只是如果一个 IP 可以被多个域名解析到时会比较麻烦,不知道有无办法可解。