我可以使用 dnspython 编写带有 $TTL 的 DNS 区域文件吗?

Can I write a DNS Zone file with $TTL using dnspython?

我使用 dnspython 中的 dns.zone.Zone 来表示 DNS 区域,当我使用 to_text() 方法时,我得到一个如下所示的区域:

@ 86400 IN SOA dns0.noris.net. hostmaster.noris.net. 1234 86400 1800 2419200 600
@ 86400 IN A 185.199.108.153
@ 86400 IN A 185.199.109.153
@ 86400 IN A 185.199.110.153
@ 86400 IN A 185.199.111.153

有没有办法让输出使用 BIND 样式的默认 TTL,而不是像这样每条记录一个 TTL?

$TTL 86400
@ IN SOA dns0.noris.net. hostmaster.noris.net. 1234 86400 1800 2419200 600
@ IN A 185.199.108.153
@ IN A 185.199.109.153
@ IN A 185.199.110.153
@ IN A 185.199.111.153

(背景:我想在默认区域 TTL 更改时最小化差异)。

dnspython 库,截至 v2.1.0rc1(截至 2020 年 11 月 9 日的最新版本),本身不支持这种类型的区域样式 。 查看 to_text() 调用的堆栈跟踪:

  1. dns/zone.py#622: to_text()
  2. dns/zone.py#586: to_file()
  3. dns/node.py#53: to_text()
  4. dns/rdataset.py#233: to_text()

——这是进行实际格式化的地方:

for rd in self:
    extra = ''
    if want_comments:
        if rd.rdcomment:
            extra = f' ;{rd.rdcomment}'
        s.write('%s%s%d %s %s %s%s\n' %
                (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass),
                 dns.rdatatype.to_text(self.rdtype),
                 rd.to_text(origin=origin, relativize=relativize,
                            **kw),
                 extra))

因此,如您所见,self.ttl 总是包含在 rdataset 文本输出中。

你可以做的是遍历区域,自己创建一个你喜欢的样式的区域文件——或者直接对 to_text() 输出进行更改,这是一个 standardized zone description,因此是稳定的足以自动处理。看起来如何的快速示例:

zone_lines = ['$TTL %s' % zone['@'].rdatasets[0].ttl]
for rdat in zone.to_text().decode('ascii').strip().split('\n'):
    rdat_params = rdat.split(' ')
    rdat_params.pop(1)
    zone_lines.append(' '.join(rdat_params))

zone_text = '\n'.join(zone_lines)

您还可以为 dnspython 项目 on Github 创建功能请求。然后作者会考虑你的功能请求,他们最近反应很好。