[GH-ISSUE #3] 想法交流 #3

Open
opened 2026-03-15 02:16:37 +03:00 by kerem · 3 comments
Owner

Originally created by @yingziwu on GitHub (Mar 3, 2020).
Original GitHub issue: https://github.com/arloan/prdns/issues/3

看到你的贴子,可以说是英雄所见略同。大概在一年前根据相似的原理写了一个防DNS污染的小项目。
具体的内容可以参考我这篇博文:https://blog.bgme.me/posts/some-ideas-about-anti-pollution-dns-server/
这篇博文写的有一点早,再加上后来GFW的DNS污染模块做了一些升级(对于AAAA请求,也会返回虚假的AAAA纪录,而不是像博文中写的直接返回A纪录),把项目简单重写了一下。所以看博文时,防火墙缺陷一节看完之后就不用再向下看了。(等一下会对该博文进行一下更新)

大概看了一下项目的源码,感觉可能会存在以下问题:
问题一:上面v友所说的对于泛解析不适用,无法区分该域名是泛解析域名还是被GFW污染的域名。
对于这个问题可以采用我博文中的方法,向境外一未开放53端口的主机发送DNS请求来解决。

问题二:其实是问题一的衍生,鉴于国内某些运营商的DNS劫持行为(甚至直接劫持53端口),如果其对 NXDOMAIN 返回有效的A纪录或AAAA纪录的话,那么你的项目就没有什么用了。方法一中的解决办法也受到很大的限制。
这个一个可能的解决方法是,向境外未开放53端口的主机发送DNS时,不要请求A、AAAA纪录,而是请请求MX、TXT等纪录,并同时附加上 norecurse flag。如果在这种情况下收到A纪录或AAAA纪录的回复,即证明该域名已被DNS污染。

问题三:对于CNAME至被污染域名的域名无效。
举例说明:现有一域名 test.example.com CNAME至 www.google.com
那么你项目中的测试方法便对这样的域名无效,因为 test.example.com 并不存在于GFW的屏蔽列表之中,所以你构造的 ne-[timestamp].test.example.com 查询并不会得到GFW的伪响应。但由于其CNAME至被污染域名www.google.com,所以你最终得到的解析结果仍是被污染的。

对于第三个问题,说一个现实一点的例子,之前有一段时间 github头像加载不出来。
经过我的分析,问题大致如下:
avatars*.githubusercontent.com 域名本身没有被屏蔽,但是由于被 CNAME 至了 github.map.fastly.net
而之前 map.fastly.netssl.fastly.net 被DNS投毒,致使 avatars*.githubusercontent.com 解析至被污染域名。

对于问题三,由于我的项目直接使用bind来递归查询,所以不存在这个问题。
但对于你的项目而言,大概需要对于所有 CNAME 指向的域名再进行二次查询验证。


本来是想直接在 v2ex 原贴下进行回复的,但由于v2ex的奇葩设计,上述文本无法直接发出(需验证手机号),所以特贴在此处。
另外,如果你愿意并且有空的话,可以帮忙转贴至v2ex吗?

Originally created by @yingziwu on GitHub (Mar 3, 2020). Original GitHub issue: https://github.com/arloan/prdns/issues/3 看到[你的贴子](https://www.v2ex.com/t/649297),可以说是英雄所见略同。大概在一年前根据相似的原理写了一个防DNS污染的小项目。 具体的内容可以参考我这篇博文:https://blog.bgme.me/posts/some-ideas-about-anti-pollution-dns-server/ 这篇博文写的有一点早,再加上后来GFW的DNS污染模块做了一些升级(对于AAAA请求,也会返回虚假的AAAA纪录,而不是像博文中写的直接返回A纪录),把项目简单重写了一下。所以看博文时,防火墙缺陷一节看完之后就不用再向下看了。(等一下会对该博文进行一下更新) 大概看了一下项目的源码,感觉可能会存在以下问题: 问题一:上面v友所说的对于泛解析不适用,无法区分该域名是泛解析域名还是被GFW污染的域名。 对于这个问题可以采用我博文中的方法,向境外一未开放53端口的主机发送DNS请求来解决。 问题二:其实是问题一的衍生,鉴于国内某些运营商的DNS劫持行为(甚至直接劫持53端口),如果其对 ``NXDOMAIN`` 返回有效的A纪录或AAAA纪录的话,那么你的项目就没有什么用了。方法一中的解决办法也受到很大的限制。 这个一个可能的解决方法是,向境外未开放53端口的主机发送DNS时,不要请求A、AAAA纪录,而是请请求MX、TXT等纪录,并同时附加上 ``norecurse`` flag。如果在这种情况下收到A纪录或AAAA纪录的回复,即证明该域名已被DNS污染。 问题三:对于CNAME至被污染域名的域名无效。 举例说明:现有一域名 ``test.example.com`` CNAME至 ``www.google.com``。 那么你项目中的测试方法便对这样的域名无效,因为 test.example.com 并不存在于GFW的屏蔽列表之中,所以你构造的 ``ne-[timestamp].test.example.com`` 查询并不会得到GFW的伪响应。但由于其CNAME至被污染域名www.google.com,所以你最终得到的解析结果仍是被污染的。 对于第三个问题,说一个现实一点的例子,之前有一段时间 github头像加载不出来。 经过我的分析,问题大致如下: ``avatars*.githubusercontent.com`` 域名本身没有被屏蔽,但是由于被 CNAME 至了 ``github.map.fastly.net`` 。 而之前 ``map.fastly.net``、``ssl.fastly.net`` 被DNS投毒,致使 ``avatars*.githubusercontent.com`` 解析至被污染域名。 对于问题三,由于我的项目直接使用bind来递归查询,所以不存在这个问题。 但对于你的项目而言,大概需要对于所有 CNAME 指向的域名再进行二次查询验证。 ----------------------------- 本来是想直接在 v2ex 原贴下进行回复的,但由于v2ex的奇葩设计,上述文本无法直接发出(需验证手机号),所以特贴在此处。 另外,如果你愿意并且有空的话,可以帮忙转贴至v2ex吗?
Author
Owner

@yingziwu commented on GitHub (Mar 3, 2020):

@tomac4t
基本上同意你的观点。

再加上后来GFW的DNS污染模块做了一些升级(对于AAAA请求,也会返回虚假的AAAA纪录,而不是像博文中写的直接返回A纪录)

这件事我是在今年1月份,查看日志时发现的。后来进行一些测试与抓包,GFW部分节点确实是会对AAAA查询返回虚假的AAAA纪录,但旧有直接返回A纪录的模块好像也还在工作,这一点抓包可以看的很清楚。
dig 测试1
dig 测试2 与 bind 日志
抓包

<!-- gh-comment-id:594007088 --> @yingziwu commented on GitHub (Mar 3, 2020): @tomac4t 基本上同意你的观点。 >再加上后来GFW的DNS污染模块做了一些升级(对于AAAA请求,也会返回虚假的AAAA纪录,而不是像博文中写的直接返回A纪录) 这件事我是在今年1月份,查看日志时发现的。后来进行一些测试与抓包,GFW部分节点确实是会对AAAA查询返回虚假的AAAA纪录,但旧有直接返回A纪录的模块好像也还在工作,这一点抓包可以看的很清楚。 ![dig 测试1](https://img.bgme.bid/media_attachments/files/000/883/437/original/956540deedc02087.png) ![dig 测试2 与 bind 日志](https://img.bgme.bid/media_attachments/files/000/883/412/original/b2991374a2cf6c90.png) ![抓包](https://img.bgme.bid/media_attachments/files/000/883/423/original/9426d05da0d3d5f4.png)
Author
Owner

@arloan commented on GitHub (Mar 4, 2020):

@yingziwu

问题一:泛解析是没有问题的。

问题二:被运营商劫持的情况这个项目没有考虑,不过仍然可以使用-p指定一个境内的非udp 53端口的DNS,或者-p指定一个提供tcp查询的DNS(假设运营商没有劫持tcp 53)来解决。

问题三:这个确实不行,因为本项目没有做递归。等我有空想想怎么处理最简单。

<!-- gh-comment-id:594272680 --> @arloan commented on GitHub (Mar 4, 2020): @yingziwu 问题一:泛解析是没有问题的。 问题二:被运营商劫持的情况这个项目没有考虑,不过仍然可以使用-p指定一个境内的非udp 53端口的DNS,或者-p指定一个提供tcp查询的DNS(假设运营商没有劫持tcp 53)来解决。 问题三:这个确实不行,因为本项目没有做递归。等我有空想想怎么处理最简单。
Author
Owner

@arloan commented on GitHub (Mar 4, 2020):

@tomac4t
只污染子域的情况确实没有考虑,现在的做法是,对于任意域名的查询,都只检查其顶级域名是否被污染。我觉得可以改为检查子域应该可以解决。

<!-- gh-comment-id:594274062 --> @arloan commented on GitHub (Mar 4, 2020): @tomac4t 只污染子域的情况确实没有考虑,现在的做法是,对于任意域名的查询,都只检查其顶级域名是否被污染。我觉得可以改为检查子域应该可以解决。
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/prdns#3
No description provided.