GithubHelp home page GithubHelp logo

Comments (48)

zfl9 avatar zfl9 commented on July 19, 2024

这个 10.0.23.172 是 chinadns-ng 所在机器的还是其他机器的?

$ fgrep 'query [safebrowsing.googleapis.com]' chinadns-ng.log | awk '{print $(NF-1)}' | sort | uniq
10.0.23.172#34065
10.0.23.172#49736
10.0.23.172#54354
10.0.23.172#55054
10.0.23.172#56825
10.0.23.172#57499
10.0.23.172#60149
10.0.23.172#62897
10.0.23.172#64578

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

我本地复现不出来。

想看下你的 iptables 规则,有点怀疑是 iptables 规则导致死循环了。

for t in raw mangle nat filter; do
    echo "========= $t ==========="
    iptables -t $t -S
done

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

如果能稳定复现,麻烦安装下 strace 工具,然后将 strace 捕获的系统调用日志发我下,我看看咋回事。

strace -s1024 -ttv chinadns-ng 命令行参数 2>&1 | tee -a chinadns-strace.log

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

这次关闭了ss-rules以排除干扰
这个版本的OpenWRT似乎只有nftables了,附上nft list table inet fw4
nft.log
和strace日志
chinadns-strace.log.zip

10.0.23.*是内网其他主机

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

看了strace日志,并没发现 chinadns-ng 本身有什么异常,这些请求全部来自同一客户机:

$ fgrep recvfrom chinadns-strace.log | head -n1
10:58:26.619475 recvfrom(4, "\236\275\1\0\0\1\0\0\0\0\0\0\7clients\1l\6google\3com\0\0\1\0\1", 1472, 0, {sa_family=AF_INET, sin_port=htons(63862), sin_addr=inet_addr("10.0.23.172")}, [28 => 16]) = 38

# 请求都是来自 .172 主机(发起ssh连接的那台主机),chinadns-ng 运行在 .1 主机
$ fgrep recvfrom chinadns-strace.log  | \grep -Po 'inet_addr\(.+?\)' | sort | uniq
inet_addr("10.0.23.172")

# 发送dns查询的src-port是这些,前面的数字是重复的次数(可以理解为客户机使用此端口发送的dns查询数量)
$ fgrep recvfrom chinadns-strace.log | \grep -Po 'htons\(.+?\)' | sort | uniq -c
      1 htons(12069)
      1 htons(12116)
      1 htons(14069)
      1 htons(14219)
      1 htons(15264)
      1 htons(1736)
      1 htons(17771)
      1 htons(18246)
      1 htons(20167)
      1 htons(20346)
      1 htons(20638)
      1 htons(2226)
      1 htons(22497)
      1 htons(23366)
      1 htons(23497)
      1 htons(24228)
      1 htons(24230)
      1 htons(24875)
      1 htons(26797)
      1 htons(26878)
      1 htons(27314)
      1 htons(28454)
      1 htons(31382)
      1 htons(33537)
      1 htons(33805)
      1 htons(34994)
      1 htons(35877)
      1 htons(36719)
      1 htons(36767)
      1 htons(37122)
      1 htons(37412)
      1 htons(38234)
      1 htons(40174)
   2649 htons(40824)
      1 htons(40961)
      1 htons(41149)
      1 htons(41215)
   2649 htons(43460)
      1 htons(43513)
      1 htons(46053)
     21 htons(49283)
      2 htons(49350)
      2 htons(49407)
     32 htons(49997)
      1 htons(50821)
      1 htons(50891)
      1 htons(51274)
      1 htons(51278)
      6 htons(51442)
      5 htons(51615)
      2 htons(51977)
      2 htons(52193)
      1 htons(52716)
      3 htons(52936)
      1 htons(53446)
      1 htons(53503)
      4 htons(53929)
      8 htons(54023)
      1 htons(54060)
      1 htons(54148)
      2 htons(54234)
      1 htons(54340)
      5 htons(54448)
      1 htons(54564)
      2 htons(54729)
      1 htons(54782)
      1 htons(54831)
      5 htons(54874)
      1 htons(55027)
      5 htons(55194)
      1 htons(55581)
      1 htons(56025)
      5 htons(56136)
      1 htons(56195)
      2 htons(56333)
     19 htons(56527)
      4 htons(56604)
      3 htons(56686)
      5 htons(56847)
      1 htons(56861)
      1 htons(56998)
      5 htons(57050)
      2 htons(57246)
      5 htons(57345)
      5 htons(57557)
      3 htons(57811)
      3 htons(57915)
      1 htons(57919)
      3 htons(58066)
      1 htons(58407)
      2 htons(58725)
      5 htons(58808)
      1 htons(59159)
      2 htons(59329)
      3 htons(59406)
      4 htons(59449)
      2 htons(59500)
     20 htons(59604)
      5 htons(60112)
      1 htons(60166)
      3 htons(60354)
      1 htons(60428)
      1 htons(60748)
      5 htons(60824)
      1 htons(60907)
     13 htons(60910)
      5 htons(61120)
      6 htons(61222)
      4 htons(61269)
      3 htons(61592)
      1 htons(61664)
     21 htons(61669)
      1 htons(61705)
      2 htons(61971)
      5 htons(62006)
      7 htons(62559)
      2 htons(62890)
      1 htons(62969)
      1 htons(63062)
      2 htons(63070)
      1 htons(63131)
     10 htons(63171)
      1 htons(63276)
      5 htons(63330)
      1 htons(63442)
      4 htons(63777)
      6 htons(63858)
      2 htons(63862)
      4 htons(63867)
      4 htons(63887)
      4 htons(64016)
      5 htons(64048)
      1 htons(64165)
      4 htons(64349)
      1 htons(64411)
      8 htons(64471)
      4 htons(64542)
      5 htons(64651)
      1 htons(64838)
      1 htons(64860)
      4 htons(64866)
      2 htons(64943)
      2 htons(64979)
      1 htons(65449)
      1 htons(8972)
      1 htons(9238)

看起来比较可疑的就是这两个端口,发送的 dns 查询数量有 2649 次:

   2649 htons(40824)
   2649 htons(43460)

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

10.0.23.172是一台ikuai路由器,下面有上百个设备,大量请求是合理的,那么同一端口等于是子网内某一台主机吧?
日志中create new socket, old socket is used for %d这条在不停出现且数字在增长,正常情况应该是每60s一个?

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

create new socket, old socket is used for %d

这个log没问题,这个log后面还有一条:

there are 1886 unfinished queries, continue to use the old

意思是,当前还有未完成的 query(还没收到 response),所以继续用之前的 socket。

事实上,我搜了 log,upstream socket 并没有 close,一直都是最开始创建的那两个:

$ fgrep epoll chinadns-strace.log | fgrep -v wait
10:58:26.276121 epoll_create1(0)        = 5
10:58:26.276226 epoll_ctl(5, EPOLL_CTL_ADD, 4, {events=EPOLLIN, data={u32=4, u64=4}}) = 0
10:58:26.620591 epoll_ctl(5, EPOLL_CTL_ADD, 6, {events=EPOLLIN, data={u32=0, u64=0}}) = 0
10:58:26.621059 epoll_ctl(5, EPOLL_CTL_ADD, 7, {events=EPOLLIN, data={u32=2, u64=2}}) = 0

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

我仔细分析了 chinadns-ng 收到的 query msg,以及 forward 给上游的 query msg。没发现什么异常。


异常的情况是,上游从未返回数据:

$ grep -o 'handle_[\w_]++' chinadns-strace.log  | sort | uniq -c
  34434 handle_local_packet
   7704 handle_timeout_event

这说明所有请求最终都会超时。

我认为你应该检查下为什么上游从来没有 response 过。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

另外,你在开头说 你使用了 dns2tcp 作为上游,但我看了你发的所有 log(包括最开始那次),都是用的 8.8.8.8。

虽然这和当前的问题没啥关系。。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

另外,我统计了一下 chinadns-ng 在运行期间收到的 query 数量:

[10:58:26] -> [10:59:50] 差不多 1 分 30 秒,共 5739 个查询,大概每秒 68 个请求。

感觉不是死循环,如果是死循环,那么 query 频率肯定不会这么低。

$ wc -l all*
  5739 all_forward_data.txt
  5739 all_req_data.txt
 11478 total

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

综上所述,这里面最大的问题是:国内和国外上游从未响应 chinadns-ng 的请求

如果你设置了 iptables/nftables 规则,将流量重定向给 ss-redir,建议你看下 ss-redir 的日志。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

为了排除干扰,strace这次没有用dns2tcp和ss-redir。

而且就算是--trust-dns=114.114.114.114也出现了同样的问题……

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

日志中create new socket, old socket is used for %d这条在不停出现且数字在增长,正常情况应该是每60s一个?

这里我需要说明下,从程序逻辑上来说,这条log的出现是完全正常的,不是异常情况。

这个逻辑是从 2023.05.08 版本开始引入的。

目的是避免长时间使用同一个端口(socket)与 dns upstream 通信,具体你可以看下 #125

所以给 upstream socket 设置了一个 life time,目前是 60s。

也就是说每 60s 会换一个新的 socket(因此 src 端口号通常会变化),用来与 upstream 通信。

当然,更换新 socket 的前提是,当前没有 未完成的dns查询(否则这些未完成的查询必定失败,因为再也没有机会从 upstream 收到他们的 response 了)。

如果检测到有 未完成的dns查询,那么 socket 更替逻辑 将延后,这就是你经常看到 there are 1886 unfinished queries, continue to use the old 打印的原因。

因为你这里的 upstream 一直不响应,因此堆积的未完成 query 越来越多,所以更替逻辑一直在延后。

正常来说,一个 dns 查询会很快收到 response(通常也就是几十毫秒),所以就算出现延后处理,也就是维持个几秒钟。不会出现你这种极限情况。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

为了排除干扰,strace这次没有用dns2tcp和ss-redir。

而且就算是--trust-dns=114.114.114.114也出现了同样的问题……

那你要看下你的网络环境了,你在 chinadns-ng 所在机器,用 dig 测下:

dig @114.114.114.114 baidu.com
dig @114.114.114.114 github.com
dig @114.114.114.114 google.com

看下是否能正常响应。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

总之,你要解决 上游不响应 这个核心问题。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

为了排除干扰,strace这次没有用dns2tcp和ss-redir。
而且就算是--trust-dns=114.114.114.114也出现了同样的问题……

那你要看下你的网络环境了,你在 chinadns-ng 所在机器,用 dig 测下:

dig @114.114.114.114 baidu.com
dig @114.114.114.114 github.com
dig @114.114.114.114 google.com

看下是否能正常响应。

baidu.com正常,github和google超时。
这种情况的处理是不向用户返回任何结果?哪怕是china-dns是有结果的?
而且超时也有个等待过程吧,为什么会触发像死循环一样的大量请求

在我后续测试中已经不能在开启程序1分钟准时复现了,但10分钟内还是会出现的。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

另外关于 chinadns-ng 几个使用上的建议:

  • 指定大陆域名列表,让这些域名的查询只转发给 china 上游(单纯转发query和response,没有额外逻辑):-m chnlist.txt
  • 指定污染域名列表,让这些域名的查询只转发给 trust 上游(单纯转发query和response,没有额外逻辑):-g gfwlist.txt
  • 对于其他不在列表的域名,需要导入 chnroute.ipset、chnroute6.ipset,用于 ip 判定,只允许使用 china 上游返回的是国内ip的情况,如果不是,则一律使用 trust 上游的结果。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

你目前的 chinadns-ng 参数,很容易出问题,因为全都是 tag:none 域名,tag:none 域名总是先考虑 china 上游的结果,当 china 上游的结果不合适时(也就是 A/AAAA 查询,ip不是大陆ip),才会采纳 trust 上游的结果。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

你目前的 chinadns-ng 参数,很容易出问题,因为全都是 tag:none 域名,tag:none 域名总是先考虑 china 上游的结果,当 china 上游的结果不合适时(也就是 A/AAAA 查询,ip不是大陆ip),才会采纳 trust 上游的结果。

为了定位问题,这些功能都暂时没有开。正常使用时是会使用域名和ip过滤的。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

那当然不行,就算是定位问题,也是要按照常规使用模式来的。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

baidu.com正常,github和google超时。
这种情况的处理是不向用户返回任何结果?哪怕是china-dns是有结果的?

首先,从你给的 strace 日志来看,你的所有上游(无论是 china 还是 trust)都没有进行任何响应(不是一两个请求不响应,是所有,这1分半内的所有请求!),那肯定就是超时,毫无悬念。程序总不能凭空给你捏造一个 response 吧。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

为什么会触发像死循环一样的大量请求

之前的分析都已经说了,这些请求都是来自其他机器的,而且你说有几百个客户端在下面,按照平均每秒 68 个查询的频率来看,也不是死循环。。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

总之问题不在于请求(而且请求频率也不是你说的死循环这种情况),问题在于所有上游都没返回数据。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

另外,这是之前关于去掉 抢答模式 的一些讨论,有谈到上游 timeout 的一些话题

034b7d1#r103923807

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

我觉得这个帖子的标题存在误导。

上午看到这个 issue 后,我一直在看 epoll 相关的东西,然而并未发现什么可疑的地方会导致你说的死循环。

另外也怀疑是否 forward 给 upstream 的时候发生了什么神奇的操作,导致 forward 给 chinadns-ng 的监听端口了,这是我能想到的第二种会导致死循环的情况。然而也不是这种情况(而且理论上上不可能有这种情况,除非是不正确的 iptables/nftables 规则导致的)。


问题核心还是 上游没有响应的问题。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

开了域名和ip列表似乎持久了一些……然并卵。

公平模式能理解,处理是正确的,可是为什么china上游也不给我返回结果呢……这个联通dns已经十数年没有坏过了吧

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

我觉得这个帖子的标题存在误导。

上午看到这个 issue 后,我一直在看 epoll 相关的东西,然而并未发现什么可疑的地方会导致你说的死循环。

另外也怀疑是否 forward 给 upstream 的时候发生了什么神奇的操作,导致 forward 给 chinadns-ng 的监听端口了,这是我能想到的第二种会导致死循环的情况。然而也不是这种情况(而且理论上上不可能有这种情况,除非是不正确的 iptables/nftables 规则导致的)。

问题核心还是 上游没有响应的问题。

说得对,似乎是什么导致了上游不仅仅是timeout……更像是reset

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

在 chinadns-ng 正常运行过程中,如果发现上游不响应(看日志能知道),那么立即进行 dig 测试(在 chinadns-ng 所在机器):

  • dig @chinadns-ng的国内上游ip 发生超时的域名(其他域名也可以试下)
  • dig @chinadns-ng的可信上游ip 发生超时的域名(其他域名也可以试下)

如果 dig 这边总是能够正常 query/response,但是 chinadns-ng 不正常,请告诉我。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

我有点怀疑和 #125 类似,可能对于你这边的上游 DNS 来说,socket life time 60 秒还是太长了,导致 upstream 拒绝给你响应(因为你这几十秒内,一直使用相同的 src-ip && src-port 请求,恰好你的网络环境下,DNS 查询频率也比较高,服务器可能认为你在 DDOS 攻击?)

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

我有点怀疑和 #125 类似,可能对于你这边的上游 DNS 来说,socket life time 60 秒还是太长了,导致 upstream 拒绝给你响应(因为你这几十秒内,一直使用相同的 src-ip && src-port 请求,恰好你的网络环境下,DNS 查询频率也比较高,服务器可能认为你在 DDOS 攻击?)

要验证这个情况,有个很简单的方法,你修改下源码,重新编译。

#define SOCK_LIFETIME 60 /* for upstream socket */

将 60 改为 1 看下。

改为 0 也可以

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

如果确实是这个原因,那么后面我会给一个命令行参数,用于调整 life time,而不是写死。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

musl报错了所以没有使用。
SOCK_LIFETIME改为1后似乎更容易崩溃了

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

什么报错?

崩溃?进程掉了?麻烦说清楚。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

什么报错?

崩溃?进程掉了?麻烦说清楚。

指的是CPU占用满

最近尝试了不同方法试图修复:

  1. 在前面加了dnsmasq转发,之后没有再出现cpu占用满的情况,但变成了所有dns查询均无法响应,客户端表现为浏览器报错dns无响应
  2. 去掉了--noip-as-chnip,似乎排除了问题,不再有无响应的情况发生,由于联通dns返回结果不稳定(间断地墙),可复现的域名可能有:api.blocknative.com,a.nel.cloudflare.com,wandb.ai,g.live.com,api.wallet.coinbase.com。这些域名的特点是CNAME域名,并且不在gfwlist和chnlist里表现为直接查询上游(dns2tcp 8.8.8.8)正常,但chinadns-ng拒绝返回结果。这个表现在我使用的旧版(v1.0-beta.25)中没有出现。log里出现了之前没有的报错:
    2023-11-20 13:45:35 I [main.c:330 handle_remote_packet] reply [g.live.com] from 202.96.69.38 (2802), result: filter 2023-11-20 13:45:35 I [main.c:332 handle_remote_packet] reply [g.live.com] from <previous-trustdns> (2802), result: accept 2023-11-20 13:45:35 W [ipset.c:607 test_res_ipset] error when querying ip: (22) Invalid argument

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

你说的那个报错,确定ipset导入成功了?你这是查询chnroute的报错。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

nft list table inet global有内容,而且只有少数域名才有这个报错,需要的话我可以把ipset上传

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

命令行参数如何指定的?nft需要特殊格式,family@table@set

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

用的是--ipset-name4 chnroute

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

参数格式错了,具体看readme。--help也有说格式。

chinadns-ng 的启动日志里面,也会打印当前使用的是 ipset 还是 nftset。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024
 -4, --ipset-name4 <set4>             ip test for tag:none, default: chnroute
 -6, --ipset-name6 <set6>             ip test for tag:none, default: chnroute6
                                      if setname contains @, then use nft-set
                                      format: family_name@table_name@set_name

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

明白了,nft的set name是inet@global@chnroute而不是chnroute对吧

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

是的,如果用的是默认nftset数据文件。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

如果你的china-dns有超时的情况,建议同时指定两个china-dns,一个是你的联通dns,一个是稳定的不会超时的dns,比如119.29.29.29、223.5.5.5、114.114.114.114

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

另外,如果可以,建议给 china-dns 上游配置 DoH(chinadns-ng 2.0 准备内置 DoH 上游支持,目前可以借助 dnsproxy 工具来实现),上 DoH 不容易被干扰,也就不会出现你说的超时的情况。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

--noip-as-chnip 选项我建议你先看下 README 中的相关说明,先了解作用,再决定是否要用。我个人不认为必须用这个选项。

from chinadns-ng.

FlyingSB avatar FlyingSB commented on July 19, 2024

--noip-as-chnip 选项我建议你先看下 README 中的相关说明,先了解作用,再决定是否要用。我个人不认为必须用这个选项。

这个开了很久了(beta.25),当时解决了什么问题已经记不清了……

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

现在的版本与b25版本有一些改变,建议重新过一下readme。

from chinadns-ng.

zfl9 avatar zfl9 commented on July 19, 2024

readme也对很多东西做了原理上的分析,对排查问题绝对是有帮助的。当你深刻理解运行原理和每个参数后,才能用好。

from chinadns-ng.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.