以编程方式检查域名是否受到DNSSEC保护。

10

如标题所述,我想以编程的方式检查域名的DNS响应是否受到DNSSEC的保护。
我该怎么做?

如果有Python解决方案将会很好。

更新: 将请求更改为响应,对于造成的困扰,请谅解。


1
这看起来很相关:http://www.unbound.net/documentation/pyunbound/examples/example4.html - kasperd
我们曾经尝试使用unbound相当长的一段时间,但它从未表现出良好的效果。 - vy32
2个回答

21

使用DNS解析器(例如dnspython),您可以查询域名的DNSKEY RRset并打开DO(dnssec OK)查询标志。如果查询成功,则答案将设置AD(已验证的数据)标志,并包含区域(如果已签名)的RRSIG签名。

更新:使用dnspython的基本示例:

import dns.name
import dns.query
import dns.dnssec
import dns.message
import dns.resolver
import dns.rdatatype

# get nameservers for target domain
response = dns.resolver.query('example.com.',dns.rdatatype.NS)

# we'll use the first nameserver in this example
nsname = response.rrset[0].to_text() # name
response = dns.resolver.query(nsname,dns.rdatatype.A)
nsaddr = response.rrset[0].to_text() # IPv4

# get DNSKEY for zone
request = dns.message.make_query('example.com.',
                                 dns.rdatatype.DNSKEY,
                                 want_dnssec=True)

# send the query
response = dns.query.udp(request,nsaddr)
if response.rcode() != 0:
    # HANDLE QUERY FAILED (SERVER ERROR OR NO DNSKEY RECORD)

# answer should contain two RRSET: DNSKEY and RRSIG(DNSKEY)
answer = response.answer
if len(answer) != 2:
    # SOMETHING WENT WRONG

# the DNSKEY should be self signed, validate it
name = dns.name.from_text('example.com.')
try:
    dns.dnssec.validate(answer[0],answer[1],{name:answer[0]})
except dns.dnssec.ValidationFailure:
    # BE SUSPICIOUS
else:
    # WE'RE GOOD, THERE'S A VALID DNSSEC SELF-SIGNED KEY FOR example.com

我之前也尝试过使用dnspython,但是我没有找到从中获取所需数据的方法,而且文档非常糟糕。你知道如何编写这个吗? - Thorben
@Thorben 在答案中添加了一个基本示例。 - isedev
谢谢。代码看起来很好。不幸的是,我在response = dns.query.udp(request, ns)处遇到了一个奇怪的错误TypeError: coercing to Unicode: need string or buffer, NS found,但我相信它通常是有效的。然而,我已经解析了dig +dnssec domain的输出。 - Thorben
2
你能够扩展一下代码以验证信任链吗? - Tom Maier
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - kasperd
显示剩余3条评论

2
要查看特定请求是否受保护,请查看请求数据包中的DO标志。无论你使用哪种语言和库来接口DNS,都应该有一个访问器(可能被称为其他名称,如“dnssec”)。
如果你想知道某个区域是否受保护,第一个答案是正确的,但不完整。所述过程将告诉你区域自己的数据是否已签名。为了检查委托到该区域的保护情况,你需要向父区域的名称服务器请求所需区域的(正确签名的)DS记录。

我也遇到了这个问题,但我不知道如何扩展代码以使用dnspython验证信任链。你有简单的例子吗? - Tom Maier
2
很遗憾,没有。在我们最近发布的工具Zonemaster中,有一些代码可以执行此检查(以及许多其他检查),但它是用Perl编写的。如果您想看看它,可以在Github上找到https://github.com/dotse/zonemaster-engine,并且最相关的功能是文件lib/Zonemaster/Test/DNSSEC.pm中的`dnssec11`函数。 - Calle Dybedahl
那么,您如何检查特定的“响应”是否受保护?我们是否还需要查看响应数据包中“DO标志”的存在? - weefwefwqg3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接