zfl9 / chinadns-ng

chinadns 重构增强版,支持域名分流、ipset/nftset、UDP/TCP/DoT
GNU Affero General Public License v3.0
1.1k stars 184 forks source link

上游 TCP/DoT 服务器的 限流/限速 问题 #189

Closed zfl9 closed 3 weeks ago

zfl9 commented 2 months ago

https://github.com/zfl9/chinadns-ng/issues/183#issuecomment-2239543851 https://github.com/zfl9/chinadns-ng/issues/183#issuecomment-2241529115 https://github.com/zfl9/chinadns-ng/issues/185#issuecomment-2270397669

根据收集的情况看,似乎 腾讯、阿里的 TCP DNS、DoT DNS 存在比较严重的限速,需要研究一个解决方案。

根据 #185 的反馈,似乎长连接(pipeline 查询)更容易受到限流的影响,考虑增加一个选项,对单个 TCP/TLS 连接增加一个配额,例如配置为 10,则表示单个连接最多服务 10 次 DNS 查询,避免在单个连接上执行过多查询。根据日志看,被限速时,上游服务器似乎不会立即主动关闭连接,所以看起来像连接假死了,导致 chinadns-ng 在一段时间内一直在等待上游 DNS 的 reply。

lwb1978 commented 2 months ago

经过用dns2tcp测试上游tcp://223.5.5.5,同样的dns请求量没有出现dns查询timeout的问题。在当下国内各种公共dns普遍限速的环境下,chinadns-ng确实这方面有改进的空间。

zfl9 commented 1 month ago

这个配置信息需要附加到 upstream 的 url 上,因为允许不同的 upstream 具有不同的限额配置。

因此需要扩展 upstream 的 url 格式,如下(加空格是为了方便阅读,实际格式中不允许有空格):

proto:// host@ ip #port ?param1=value1 ?param2=value2 ...


UPDATE: udp、tcp、tls 会话默认配置都改为 count=10 && life=10。

lwb1978 commented 1 month ago

老大,如果是仅用作dns转发的情况下如何设置呢?如这样的使用方式: chinadns-ng -b 127.0.0.1 -l 5454 -c tls://1.1.1.1 -d chn

zfl9 commented 1 month ago

仅用作转发 DNS 程序也一样的,没有特别之处。

我建议保持默认配置,因为根据先前 UDP 的经验(很久之前就是 count=10 && life=20 了),这个配置是安全的,兼顾了性能(不会频繁创建 udp socket、TCP/TLS 连接)和实际网络情况(避免触发上游 DNS 对单个连接/端口的限流、限速)。

jarod360 commented 1 month ago

希望DOT增加支持纯域名加端口的方式。

lwb1978 commented 1 month ago

希望DOT增加支持纯域名加端口的方式。

如果是纯域名的dns地址,还得添加bootstrap-dns服务器设置,否则连dns本身的域名都解析不了,这工作量估计有点大了。

jarod360 commented 1 month ago

希望DOT增加支持纯域名加端口的方式。

如果是纯域名的dns地址,还得添加bootstrap-dns服务器设置,否则连dns本身的域名都解析不了,这工作量估计有点大了。

明白了,太复杂了。那就现在这样吧。用的私有dns服务器,ip地址有时候会变动。

zfl9 commented 1 month ago

久等了,这周末或下周应该会更新此功能。这段时间太忙了


顺便关闭 wolfssl 的 LTO 构建标志,目前收到几个反馈:x86_64 平台,使用 TLS 上游时,有概率连不上服务器,提示 fatal alert error 之类的,这个现象通常是运行了一段时间后出现的,有反馈说关闭 LTO 就正常。

注:其他编译单元的 LTO 设置仍然尊重构建选项中的 LTO 配置(默认:启用 LTO 优化),只是 wolfssl 库使用常规 -O3 优化。

应该是 ssl session resume 导致的,见后面的更新。

cnJamesLucas commented 1 month ago

久等了,这周末或下周应该会更新此功能。~这段时间太忙了~

顺便关闭 wolfssl 的 LTO 构建标志,目前收到几个反馈:x86_64 平台,使用 TLS 上游时,有概率连不上服务器,提示 fatal alert error 之类的,这个现象通常是运行了一段时间后出现的,有反馈说关闭 LTO 就正常。

注:其他编译单元的 LTO 设置仍然尊重构建选项中的 LTO 配置(默认:启用 LTO 优化),只是 wolfssl 库使用常规 -O3 优化。

各种平台都有这个问题。X86 ARM64,可能不一定是LTO问题。

cnJamesLucas commented 1 month ago

我自己编译了一个ARM64不带LTO版本的,查询几次后也一样报Upstream.zig:551 TCP.on_error failed: received alert fatal error 由于腾讯经常卡死,阿里的有BUG,我用PowerDNS Recursor自建服务器,但用腾讯阿里这些又还好。

zfl9 commented 1 month ago

查询几次?意思是短时间内就能重现吗?我好像没遇到这种情况,也是aarch64。

构建命令行是什么,发来看看。

另外,走代理了吗?国内dot的还是国外的dot服务器?

cnJamesLucas commented 1 month ago

查询几次?意思是短时间内就能重现吗?我好像没遇到这种情况,也是aarch64。

构建命令行是什么,发来看看。

另外,走代理了吗?国内dot的还是国外的dot服务器?

我自建的是在国外服务器,直连过去,我在国外查询也会出现,应该不是干扰问题。

是的,可以精确重现,十几次就会不行。 zig build -Dtarget=aarch64-linux-musl -Dcpu=generic+v8a -Dlto=false -Dwolfssl

zfl9 commented 1 month ago

你这个看起来像是被gfw阻断了/干扰了,直连境外不走代理。毕竟DoT流量特征挺明显的。

cnJamesLucas commented 1 month ago

你这个看起来像是被gfw阻断了/干扰了,直连境外不走代理。毕竟DoT流量特征挺明显的。

我用境外服务器访问也一样的。

今天换了别的客户端是正常的。

zfl9 commented 1 month ago

难不成是ssl session恢复的问题?默认给启用了session恢复

cnJamesLucas commented 1 month ago

难不成是ssl session恢复的问题?默认给启用了session恢复

怎么disable?我再编译一个看看。

zfl9 commented 1 month ago

没有build option可以控制,待会我切个测试分支,关闭ssl session恢复功能。你再测测

cnJamesLucas commented 1 month ago

没有build option可以控制,待会我切个测试分支,关闭ssl session恢复功能。你再测测

好的。

zfl9 commented 1 month ago

没有build option可以控制,待会我切个测试分支,关闭ssl session恢复功能。你再测测

好的。

https://github.com/zfl9/chinadns-ng/tree/no-ssl-session-resume

这个分支。记得先 zig build clean-all

作为对照,建议编译该分支的两个版本,一个 lto,一个 no-lto。

cnJamesLucas commented 1 month ago

没有build option可以控制,待会我切个测试分支,关闭ssl session恢复功能。你再测测

好的。

https://github.com/zfl9/chinadns-ng/tree/no-ssl-session-resume

这个分支。记得先 zig build clean-all

作为对照,建议编译该分支的两个版本,一个 lto,一个 no-lto。

可以了,没报错了。lto,no-lto都没问题了。

zfl9 commented 1 month ago

可能是 wolfssl 的 session 恢复 BUG。。先不管了,去除这个特性。

zfl9 commented 1 month ago

实测:阿里的 DoT 在南方某省份,“限流”很严重。测试了电信和移动,都是这样。

这里说的“限流”是指连接服务器失败,目前发现有以下两种表现:

$ # 表现形式1:
$ # 若在 timeout 时间内可以 retry 成功,则 chinadns-ng 可以应对
$ dig +tls @223.5.5.5 taobao.com +retry=0 +timeout=3
;; Connection to 223.5.5.5#853(223.5.5.5) for taobao.com failed: connection refused.

$ # 表现形式2:
$ # 注意,dig 没有任何输出
$ # 这种故意等 2 秒的恶意行为无法应对,因为故意拉大了 retry 间隔,很容易触发 timeout
$ time dig +tls @223.5.5.5 taobao.com +retry=0 +timeout=3
dig +tls @223.5.5.5 taobao.com +retry=0 +timeout=3  0.00s user 0.01s system 0% cpu 2.074 total

$ # 表现形式2:
$ # 还是上面这个环境,在 chinadns-ng 中测试 (tls://223.6.6.6)
$ # 可以看到 dig 没输出是因为 ssl 握手时,alidns 故意等了 2 秒,然后发送一个 close 信号
$ # 而且 chinadns-ng 尝试了两次 connect(ssl 握手),都是这样,每次都是故意卡你 2 秒。
2024-09-06 15:16:05 I [server.zig:335 QueryLog.query] query(id:20781, tag:chn, qtype:1, 'taobao.com') from 127.0.0.1#36541
2024-09-06 15:16:05 I [server.zig:404 QueryLog.forward] forward query(qid:7, from:udp, 'taobao.com') to china group
2024-09-06 15:16:05 I [Upstream.zig:1114 Group.send] forward query(qid:7, from:udp) to upstream tls://223.6.6.6
2024-09-06 15:16:07 W [Upstream.zig:789 TCP.on_error] connect(tls://223.6.6.6) failed: peer sent close notify alert
2024-09-06 15:16:09 W [Upstream.zig:789 TCP.on_error] connect(tls://223.6.6.6) failed: peer sent close notify alert
2024-09-06 15:16:10 W [server.zig:121 Query.on_timeout] query(qid:7, id:20781, tag:chn) from udp://127.0.0.1#36541 [timeout]

腾讯的 DoT 目前正常(tls://1.12.12.12、tls://120.53.53.53),虽然解析耗时稍微高一些,但不像阿里这般变态。

另外,阿里的 tcp://223.5.5.5、tcp://223.6.6.6 (纯 TCP 查询)却又正常,不存在 DoT 那样的拒绝连接问题。

lwb1978 commented 1 month ago

我这边在windows下用telnet测试阿里的223.5.5.5的853端口直接不通,只有阿里的ipv6地址的853端口才通

lwb1978 commented 1 month ago

我在passwall添加直连dns dot支持时,在dot列表中阿里的服务器只放了ipv6地址,因为我不确定223.5.5.5是否真的支持tls,另外国内的dot服务器太少了,目前我只知道腾讯、360和阿里有。

zfl9 commented 1 month ago

对于阿里 DoT 的这种变态限制,chinadns-ng 实际上无能为力。

奇怪的是,不同地区这个现象还不同(根据收集到的反馈),Ta那边阿里DoT没有这种情况。。。

cnJamesLucas commented 1 month ago

自建吧,这些免费的都要开始收钱了。没办法。 阿里有个BUG的,我反馈给他们他们也不修。他们的DOT,DOH没有用name compression,导致记录多的解析超过udp的mtu。

zfl9 commented 1 month ago

国内的这些 “公共” DoT/DoH 基本要废了。

lwb1978 commented 1 month ago

这么变态的限制,他们开放服务干嘛?只为了代表它有吗?

cnJamesLucas commented 1 month ago

这么变态的限制,他们开放服务干嘛?只为了代表它有吗?

收费呀,都出了付费版。

lwb1978 commented 1 month ago

连dns都要付费,还不如用isp的算数

zfl9 commented 1 month ago

感觉目前也就这么几个选项能用了(国内 DNS):

lwb1978 commented 4 weeks ago

tcp目前我找到的国内公共dns只有两家,一个是阿里:223.5.5.5、223.6.6.6,还有就是字节跳动:180.184.1.1、180.184.2.2;阿里的tcp也有限速,而字节跳动的目前暂时还没有限速;国内除了udp以外,其他类型的dns真的少得可怜。

zfl9 commented 4 weeks ago

见 2024.09.08 版本。

zfl9 commented 3 weeks ago

先关了,有反馈再 reopen。

yk271 commented 3 weeks ago

请教各位大佬,目前阿里的 udp 会限速么?电信宽带现在因为路由的问题,用运营商 DNS 体验太糟糕了。

无论是到 1.1.1.1 还是 Cloudflare 的 NS 服务器,电信的路由都有严重的问题(貌似电信家宽的 DNS 也是走 163 线路递归的),导致解析 tag:none 的域名速度极其缓慢(别看截图中只有 1 秒,实际解析时经常超过 5 秒)。

前段时间因为阿里限速切回了运营商 DNS,没想到体验如此糟糕。

QQ20240913-011036 QQ20240913-011127

zfl9 commented 3 weeks ago

udp 目前应该没有(就算有,也是比较难触发的),自己换成 223.5.5.5 试试呗,可以再加上 119.29.29.29,备用。

lwb1978 commented 3 weeks ago

用字节跳动的,经过测试目前没有限速,地址我上面有发出来。