使用dnspython进行DNSSEC查询时遇AttributeError错误排查
解决dnspython查询DNSSEC签名域时的AttributeError: 'NS' object has no attribute 'is_absolute'错误
我之前也碰到过类似的问题,这个错误本质上是对dnspython的API调用逻辑有误,再加上可能存在的版本适配问题,咱们一步步来解决:
1. 先搞清楚错误根源
is_absolute()是dnspython中dns.name.Name类(也就是域名对象)的方法,而不是NS记录对象的方法。你参考的Stack Overflow示例可能是针对旧版本dnspython写的,或者示例代码里不小心把调用对象搞错了——直接对NS记录实例调用了这个方法,才会抛出这个属性不存在的错误。
2. 修正脚本中的核心错误
把脚本里对NS对象的is_absolute()调用,改成对NS记录的target属性(也就是实际的域名对象)调用。举个修正后的完整查询脚本示例:
import dns.resolver import dns.message # 配置DNS解析器指向本地BIND服务器 resolver = dns.resolver.Resolver() resolver.nameservers = ['127.0.0.1'] try: # 查询com域的NS记录,同时请求DNSSEC签名 response = resolver.query('com', 'NS', want_dnssec=True) # 遍历返回的NS记录 print("查询到的NS记录:") for ns_record in response.rrset: # NS记录的target是域名对象,调用它的is_absolute()方法 domain = ns_record.target print(f"- {domain}") if domain.is_absolute(): print(f" ✅ 是绝对域名") else: print(f" ❌ 是相对域名") # 验证DNSSEC签名(如果返回了签名记录) if hasattr(response, 'key_rrset') and response.key_rrset: print("\nDNSSEC签名信息:") for key_rr in response.key_rrset: print(f"- 签名密钥:{key_rr}") except dns.resolver.NXDOMAIN: print("错误:目标域名不存在") except Exception as e: print(f"查询出错:{str(e)}")
3. 顺便验证BIND服务器的配置是否正确
确保你的BIND已经正确加载了签名后的forward.com.signed文件,检查named.conf.local里的zone配置:
zone "com" { type master; file "/var/cache/bind/forward.com.signed"; # 路径要和你的文件位置一致 dnssec-enable yes; dnssec-validation yes; dnssec-lookaside auto; };
配置完成后重启BIND服务:
sudo systemctl restart bind9
可以先用dig命令测试本地DNS是否正常返回签名记录:
dig @127.0.0.1 ns com +dnssec
如果能看到RRSIG记录,说明BIND的DNSSEC配置是正常的。
4. 检查dnspython版本适配
如果上面的修正还是有问题,先检查你安装的dnspython版本:
pip show dnspython
dnspython 2.x和1.x的API有一些差异,如果你用的是2.x版本,上面的脚本是兼容的;如果是1.x版本,want_dnssec参数可能需要换成其他写法,但核心的is_absolute()调用逻辑还是一样的——必须针对域名对象调用。
内容的提问来源于stack exchange,提问作者user9371654
相关产品推荐
相关产品推荐

