我在各种用于动态DNS区域更新的脚本中使用nsupdate
已经很长时间了,没有任何问题。我一直使用TSIG对DNS服务器进行身份验证,其中ddns-confgen
生成了密钥。这意味着我没有使用dnssec-keygen
生成的密钥对;密钥文件格式如下:
key "ddns-key.my.domain.example" {
algorithm hmac-sha512;
secret "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefijklmnopqrstuvwxyzabcdefghij==";
};
然后,相应的区域配置包含:
update-policy {
grant ddns-key.my.domain.example name host.my.domain.example ANY;
};
现在我有一个更复杂的任务,并尝试通过Perl
脚本来解决。我研究了Perl::DNS::Update
,Perl::DNS
和Perl::DNS:RR:TSIG
的文档,并研究了许多示例,这些示例应该使这些模块的用法更加清楚。
但是,我看到的每个示例在通过TSIG
签署请求时,都会使用dnssec-keygen
格式的已用密钥文件,而不是我所拥有的格式的密钥文件。确实如此,例如
$o_Resolver = new Net::DNS::Resolver(nameservers => ['127.0.0.1']);
$o_Update = new Net::DNS::Update('my.domain.example', 'IN');
$o_Update -> push(update => rr_del('host A'));
$o_Update -> push(update => rr_add('host 1800 IN A 192.0.2.1'));
$o_Update -> sign_tsig('/etc/bind/ddns-key.my.domain.example.key');
$o_Reply = ($o_Resolver -> send($o_Update));
不起作用,产生以下消息:
TSIG: unable to sign packet at /path/to/script.pl line 240.
unknown type "ddns-key.my.domain.example" at /usr/local/share/perl/5.20.2/Net/DNS/RR.pm line 669.
file /etc/bind/ddns-key.my.domain.example.key line 1
at /usr/local/share/perl/5.20.2/Net/DNS/RR/TSIG.pm line 403.
TSIG: unable to sign packet at /path/to/script.pl line 240.
我想我现在有两个选择:使用dnssec-keygen
产生的格式的密钥(似乎可以直接用于Net::DNS
及其朋友),或者手动构建TSIG密钥,如文档:
my $key_name = 'tsig-key';
my $key = 'awwLOtRfpGE+rRKF2+DEiw==';
my $tsig = new Net::DNS::RR("$key_name TSIG $key");
$tsig->fudge(60);
my $update = new Net::DNS::Update('example.com');
$update->push( update => rr_add('foo.example.com A 10.1.2.3') );
$update->push( additional => $tsig );
[当然,我不会在Perl
脚本中对密钥进行硬编码,而是从密钥文件中读取它。]
切换到其他密钥文件格式将意味着更改DNS服务器配置,这不是一个很好的解决方案。 “手动”读取密钥文件,然后“手动”构造密钥也不太令人满意,因此出现了问题:
我是否正确理解无法将ddns-confgen
格式的密钥文件直接与Net::DNS
及其子模块一起使用来TSIG
签署DNS更新请求?>