Closed PussAzuki closed 5 years ago
你如果之前就描述的如此清楚明白,问题或许早已解决。
我以为写chinadns的和类似功能软件的作者会懂与这类似的逻辑(不少文章都是chnroute+一些国内有CDN的dnsmasq规则来分流)...于是我直接用“优先使用国内IPv4 CDN”来指代这个功能了...
这个情况的确存在。我先说说我自己的简略看法:
加个选项,比如 -X
,该选项默认未启用(禁用)
至于你说的“请求国内网站”,因为chinadns-ng无法判断域名是国内还是国外,因此只能进行如上判断。
改成这两个个状态如何?
状态一:禁用状态,保持现在的逻辑
状态二: 当已从国内DNS得到有效的A结果后,丢弃从国内DNS得到相同域名的AAAA结果,并不再继续查询 若无A结果,但AAAA结果在chnroute6内,则在此返回结果,否则继续向国外DNS查询,这样应该能处理掉绝大部分了吧...
“国内网址逻辑”是基于优先匹配IPv4地址是否在chnroute里,然后匹配IPv6 ONLY的网址是否在chnroute6里,但如果用户喜欢皮...那也没办法了
你说的状态二不现实,chinadns-ng 只认单个查询。如果要实现你说的“丢弃从国内dns得到的相同域名的aaaa结果”,那么chinadns_ng还需要维护另外一个hashmap,key为域名,而且还要考虑该hashmap中的entry如何清除,比如超时逻辑?否则这个map会越来越大。总之这么做极大的增加了复杂度,会引来更多的bug。
另外丢弃aaaa结果也不是一个好的解决办法,很多程序在未收到相应的解析结果时,会进行重试,这反而会恶化用户的体验。这种情况不少见,curl就是典型。
看起来还需要严谨的考虑啊...但看起来对有国内IPv4的网址进行对AAAA结果进行丢弃还行啊,也不会缺少什么...
当然不排除一些鹅心的鹤立鸡群的网址,例如 ipv6.baidu.com ,但该网址使用率远没有 www.baidu.com 来的高吧...对目前的国内环境来说,暂且还不算是损人利己的程度...
这个情况的确存在。我先说说我自己的简略看法: 加个选项,比如
-X
,该选项默认未启用(禁用)
- 禁用状态:相关逻辑同前,不做改变。
- 启用状态:当 chinadns-ng 从国内 DNS 收到 AAAA 类型的 reply 时,如果此 reply 中未包含任何 ipv6 地址(比如只有 CNAME 记录),那么也将其视为“包含 ipv6 地址,且该 ipv6 地址为国内地址”,于是 chinadns-ng 会最终接受此 reply,并返回给请求客户端。
总之,我认为这种方式是比较可取的。当请求客户端收到这个 reply 后,检查发现里面并没有 ipv6 地址,那么它就会采用 ipv4 类型的 reply。这符合你的期望。
这样操作的结果其实与直接请求 114 这样的 dns 的结果是一样的。没有区别。解析如下:直接使用 114 作为 dns 时,客户端也是同时发送两个 query,一个 a,一个 aaaa,然后会从 114 收到两个 reply,分别对应 a 类型的和 aaaa 类型的,aaaa 类型的没有 ipv6 地址,只有一个 cname 记录,a 类型的有 ipv4 地址,于是客户端最终选择 a 类型的 reply。与上述的“启用状态”产生的结果完全一致。
那也可以...至少先把目前的bug给修了... 既然你都说到这个份上了...那在此改进版的基础上加个给6in4用户实验用的选项:过滤国内DNS返回的有效的国内AAAA结果,至少我这类用户几乎和非仅有国内IPv6地址的网站是无缘的
没有明白你说的:
在此基础上,过滤国内dns返回有效国内aaaa记录。
请给出判断流程。
以下流程只针对国内dns:
发送DNS解析请求到国内DNS(一个是A,另一个AAAA) ----> 得到两个reply ----> 同时将其与chnroute(6)进行对比(得到在表内和不在表内的两个结果) ----> A在表内 或 A不在表内但AAAA在表内,立刻丢弃AAAA结果并不再查询 / 都不在表内,开始对境外DNS的结果进行判断...
大概这样子的流程
我还是要重复那句话,chinadns-ng 只认单个 query/reply,他并不知道哪两个 query 或 reply 是相关联的。因此目前我只考虑之前讨论的 -X
选项,讨论结束。如下图,如果你没有明白我说的“只认单个 query/reply”是什么意思,那么请看 chinadns.c
源码。
只认单个那也行...就请让用户能设置chnroute6为空或者只留一些需要的名单的IPv6地址或者网段 加个只对国内DNS起作用黑名单功能,这样在逻辑上就能尽可能的满足了吧...
如果你认真读过文档,就会知道,chnroute/chnroute6 这些 ipset 可以一个都不导入(或者导入一个空的 chnroute/chnroute6),这样产生的效果就是国内dns返回的ipv4/ipv6都会被过滤。
如果你认真读过文档,就会知道,chnroute/chnroute6 这些 ipset 可以一个都不导入(或者导入一个空的 chnroute/chnroute6),这样产生的效果就是国内dns返回的ipv4/ipv6都会被过滤。
嘶...那从目前来看(把目前的逻辑缺陷修了)没问题了?我目前遇到这个混合结果的问题(无论是否有指定chnroute6文件或将其设置为空)都会返回目前的国内DNS的A结果+国外DNS的AAAA结果
是的,有时间我再加上那个选项(也即上面讨论的 -X
)。
是的,有时间我再加上那个选项(也即上面讨论的
-X
)。
但如果还是出现了逻辑爆炸问题或许该考虑黑名单了...
先这样吧,到时候再看效果。
好的
我再加上那个选项(也即上面
小写的 -x
会不会和谐一点?其他选项都是小写的
当然那只是假设为 -X。不是真的叫这个名。
@PussAzuki 我回想了一下,这个改动其实不大,仅仅是一个返回值的问题。具体的:在检查一个 dns reply packet 的时候,如果与之关联的 query type 为 A/AAAA,但其 answer 中却未找到任何 ipv4/ipv6 地址时,我返回给上层的处理结果为 NOTCHN(非国内 IP),这样的结果就是,在解析 yys.163.com AAAA
时 china-dns 的响应结果被过滤的情况,因为程序内部认为 china-dns 返回的是"国外ip"。
https://github.com/zfl9/chinadns-ng/blob/b82028ec44784d552e59ec389c3b98929a0aa707/dnsutils.c#L234
如果改为 DNSRET_PASS
(国内 IP),问题就解决了。我待会加个切换选项吧,用来处理这种情况。
已更新,见选项 -n/--noip-as-chnip
。
有种你走进了你自己写的代码的坑里的感觉...参见您的这条评论.... 你自己的逻辑的坑 正如您所说的...或许"n"这个选项默认开启会更好的符合您的预期?
正如您所说的...或许"n"这个选项默认开启会更好的符合您的预期?
我自己的期望是应该丢弃这样的 reply,许多默认选项产生的效果都是我个人最期望的。
前提 部分域名的国内DNS查询结果 其相对应的国外DNS结果 理应命中的CIDR 实际返回的结果
so...how?
目前国内DNS查询到只有IPv4结果的已经正常...但ipv4/6都有的好像都会这样...chn(6)文件可以去op适配的那边查看
能尽量文字描述最好。图片连个copy都没有。。。
你自己上 op 系统,手动测试下这个命令:
ipset test chnroute6 2402:4e00:8010::155 # 应该是这个 ip 吧,自己检查下
我这边测试是没有问题的: chinadns-ng 的 log 如下:
2019-09-15 14:45:04 INF: [handle_local_packet] query [www.qq.com] from 127.0.0.1#13552
2019-09-15 14:45:04 INF: [handle_remote_packet] reply [www.qq.com] from 114.114.114.114#53, result: accept
2019-09-15 14:45:04 INF: [handle_remote_packet] reply [www.qq.com] from 8.8.8.8#53, result: ignore
2019-09-15 14:45:10 INF: [handle_local_packet] query [www.qq.com] from 127.0.0.1#50121
2019-09-15 14:45:10 INF: [handle_remote_packet] reply [www.qq.com] from 114.114.114.114#53, result: accept
2019-09-15 14:45:10 INF: [handle_remote_packet] reply [www.qq.com] from 8.8.8.8#53, result: ignore
A 查询的输出如下:
$ dig @127.0.0.1 -p55 www.qq.com A
; <<>> DiG 9.14.4 <<>> @127.0.0.1 -p55 www.qq.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14743
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 931d4dda8f02916b (echoed)
;; QUESTION SECTION:
;www.qq.com. IN A
;; ANSWER SECTION:
www.qq.com. 245 IN CNAME public.sparta.mig.tencent-cloud.net.
public.sparta.mig.tencent-cloud.net. 245 IN A 120.241.186.165
public.sparta.mig.tencent-cloud.net. 245 IN A 120.241.186.164
;; Query time: 37 msec
;; SERVER: 127.0.0.1#55(127.0.0.1)
;; WHEN: Sun Sep 15 14:45:04 CST 2019
;; MSG SIZE rcvd: 132
AAAA 查询的输出如下:
$ dig @127.0.0.1 -p55 www.qq.com AAAA
; <<>> DiG 9.14.4 <<>> @127.0.0.1 -p55 www.qq.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53636
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: cafd557bd3f199d5 (echoed)
;; QUESTION SECTION:
;www.qq.com. IN AAAA
;; ANSWER SECTION:
www.qq.com. 234 IN CNAME public.sparta.mig.tencent-cloud.net.
public.sparta.mig.tencent-cloud.net. 234 IN AAAA 2402:4e00:8010::154
public.sparta.mig.tencent-cloud.net. 234 IN AAAA 2402:4e00:8010::155
;; Query time: 37 msec
;; SERVER: 127.0.0.1#55(127.0.0.1)
;; WHEN: Sun Sep 15 14:45:10 CST 2019
;; MSG SIZE rcvd: 156
自己注意一下 chinadns-ng 的日志,必要的话打开 --verbose 选项。
使用 nslookup 再次测试了一遍,没毛病:
> server
Default server: 127.0.0.1
Address: 127.0.0.1#55
> www.qq.com
Server: 127.0.0.1
Address: 127.0.0.1#55
Non-authoritative answer:
www.qq.com canonical name = public.sparta.mig.tencent-cloud.net.
Name: public.sparta.mig.tencent-cloud.net
Address: 120.241.186.165
Name: public.sparta.mig.tencent-cloud.net
Address: 120.241.186.164
Name: public.sparta.mig.tencent-cloud.net
Address: 2402:4e00:8010::155
Name: public.sparta.mig.tencent-cloud.net
Address: 2402:4e00:8010::154
chinadns-ng 输出:
2019-09-15 14:54:25 INF: [handle_local_packet] query [www.qq.com] from 127.0.0.1#41559
2019-09-15 14:54:25 INF: [handle_remote_packet] reply [www.qq.com] from 114.114.114.114#53, result: accept
2019-09-15 14:54:25 INF: [handle_local_packet] query [public.sparta.mig.tencent-cloud.net] from 127.0.0.1#41637
2019-09-15 14:54:25 INF: [handle_remote_packet] reply [public.sparta.mig.tencent-cloud.net] from 114.114.114.114#53, result: accept
2019-09-15 14:54:25 INF: [handle_remote_packet] reply [public.sparta.mig.tencent-cloud.net] from 8.8.8.8#53, result: ignore
2019-09-15 14:54:25 INF: [handle_remote_packet] reply [www.qq.com] from 8.8.8.8#53, result: ignore
你自己上 op 系统,手动测试下这个命令:
ipset test chnroute6 2402:4e00:8010::155 # 应该是这个 ip 吧,自己检查下
看起来是chnroute6文件里的有误...没问题了
emmmmmm,说来有点好笑,现在我这省的DNS不污染ipv6结果了,直接返回空值...所以,你懂的,今天我这方案暴毙了一半,然后我个人不太喜欢黑名单(因为要么误伤+够不到 的部分很多,要么就是要维护很多东西),所以...我还得再深思熟虑啊
我用的是电信网,有公网IPv4,也有原生双栈的支持,但因一些原因,我改用6in4作为IPv6地址。 我将您的这个项目布置在刷了openwrt的路由器上,用了一段时间,感觉没有任何问题。 然而好景不长,目前我发现了您的这个项目存在逻辑问题:当国内DNS返回国内网站的IPv6地址查询结果为空时,会将从国外DNS的IPv6地址查询结果混进来,并可能因此导致访问体验劣化
图一 我再路由器的5453口部署了stubby并直接使用了DoT来进行DNS查询,图一是只从那个端口进行dig的结果.
图二 我再直接向114DNS进行dig查询,显而易见的是没有IPv6结果的.
图三 那我再向路由器进行nslookup查询会如何?图三就是结果
图四 这是我在用的配置,免得又说无图言O之类的
我只想说目前的逻辑看起来存在没有细分IPv4和IPv6结果的逻辑问题,还望改进