Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
zfl9 opened this issue Aug 6, 2024 · 37 comments
Closed

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

zfl9 opened this issue Aug 6, 2024 · 37 comments

Comments

@zfl9
Copy link
Owner

zfl9 commented Aug 6, 2024

#183 (comment)
#183 (comment)
#185 (comment)

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

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

@lwb1978
Copy link

lwb1978 commented Aug 6, 2024

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

@zfl9
Copy link
Owner Author

zfl9 commented Aug 9, 2024

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

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

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

  • proto:// 可选:空(UDP+TCP上游),udp://(UDP上游),tcp://(TCP上游),tls://(DoT上游)。
  • host@ 可选(用于DoT):设置 SNI(服务器名称指示),启用证书验证时,也会检查证书中的域名是否与之匹配。
  • ip 不可省略:没啥可说的,ipv6 地址不需要使用 [] 括起来。
  • #port 可选:默认为协议标准端口,UDP/TCP 标准端口是 53,DoT 标准端口为 853。
  • ?param=value 可选(新增的),暂定以下两个 param:
    • count=10:表示单个 “UDP/TCP/TLS 连接/会话” 最多处理 10 个查询请求。默认值 10。
    • life=20:表示单个 “UDP/TCP/TLS 连接/会话” 最多存活 20 秒(从创建连接开始)。默认值 20。
    • count=0 表示不限制查询数。
    • count=1 等价于 dns2tcp 的行为(每个查询都单独一个连接)。
    • life=0 表示不限制会话寿命。
    • 当前版本的 UDP 会话策略:count=10 && life=20(与新版本的默认配置一样)。
    • 当前版本的 TCP/TLS 连接策略:count=0 && life=0(新版本的默认配置将更安全)。

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

@lwb1978
Copy link

lwb1978 commented Aug 9, 2024

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

@zfl9
Copy link
Owner Author

zfl9 commented Aug 9, 2024

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

  • 等新版本发布后,对于 -c tls://1.1.1.1,默认 count=10,life=20。也就是单个连接最多处理 10 个查询。比如短时间内,chinadns-ng 收到 30 个查询,那么就会依次创建 3 个 TLS 连接,分别服务于 1-10,11-20,21-30 查询。这个策略应该是比较安全的,同时兼顾了性能和实际网络情况(上游限速),应该不容易触发上游限速,当然具体效果还是需要实际测试验证。
  • 如果上游限速策略比较激进,在上述默认配置下也会触发限速,那么可以改为 -c tls://1.1.1.1?count=1,这种情况下,每个查询都单独一个 TLS 连接,对于国内 DNS 来说,性能影响应该不大,毕竟国内 DNS 的往返时间(RTT)还是比较短的。

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

@jarod360
Copy link

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

@lwb1978
Copy link

lwb1978 commented Aug 15, 2024

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

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

@jarod360
Copy link

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

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

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

@zfl9
Copy link
Owner Author

zfl9 commented Aug 30, 2024

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


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

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

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

@cnJamesLucas
Copy link

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

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

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

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

@cnJamesLucas
Copy link

cnJamesLucas commented Sep 2, 2024

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 2, 2024

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

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

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

@cnJamesLucas
Copy link

cnJamesLucas commented Sep 2, 2024

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

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

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

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

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 3, 2024

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

@cnJamesLucas
Copy link

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

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

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 3, 2024

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

@cnJamesLucas
Copy link

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

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 3, 2024

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

@cnJamesLucas
Copy link

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

好的。

@zfl9
Copy link
Owner Author

zfl9 commented Sep 3, 2024

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

好的。

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

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

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

@cnJamesLucas
Copy link

没有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
Copy link
Owner Author

zfl9 commented Sep 3, 2024

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

zfl9 added a commit that referenced this issue Sep 5, 2024
@zfl9
Copy link
Owner Author

zfl9 commented Sep 6, 2024

实测:阿里的 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
Copy link

lwb1978 commented Sep 6, 2024

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

@lwb1978
Copy link

lwb1978 commented Sep 6, 2024

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 6, 2024

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

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

@cnJamesLucas
Copy link

cnJamesLucas commented Sep 6, 2024

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 6, 2024

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

@lwb1978
Copy link

lwb1978 commented Sep 6, 2024

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

@cnJamesLucas
Copy link

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

收费呀,都出了付费版。

@lwb1978
Copy link

lwb1978 commented Sep 6, 2024

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 6, 2024

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

  • 用运营商的 DNS,虽然免不了污染,但解析速度和拿到的 IP 的质量基本是最好的。
  • 用国内公共 DNS,而且最好上 TCP 查询,UDP 查询可能会被运营商劫持,目前不会像 DoT 这般限流。
  • 用 dnspod 的 DoT,目前还能正常用用。
  • 自建 DNS,有点折腾。

@lwb1978
Copy link

lwb1978 commented Sep 6, 2024

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

@zfl9
Copy link
Owner Author

zfl9 commented Sep 8, 2024

见 2024.09.08 版本。

@zfl9
Copy link
Owner Author

zfl9 commented Sep 11, 2024

先关了,有反馈再 reopen。

@zfl9 zfl9 closed this as completed Sep 11, 2024
@yk271
Copy link

yk271 commented Sep 12, 2024

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

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

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

QQ20240913-011036
QQ20240913-011127

@zfl9
Copy link
Owner Author

zfl9 commented Sep 13, 2024

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

@lwb1978
Copy link

lwb1978 commented Sep 13, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants