我在 Debian Jessy 上使用 Bind 设置了自己的动态 DNS 服务器。一切都运行良好。实际的 ddns 更新是通过 nsupdate 完成的(由同一台服务器上的 php 执行)。php 链接本身使用 https 加密,但我想知道 nsupdate 命令(也包括 ddns 密钥字符串)是否也经过某种加密?从理论上讲,一般来说,如果它没有加密,有人可以在传输过程中读取密钥,这将允许他自己将 ddns 更新发送到服务器?
如果是这样,有没有办法确保 nsupdate 仅在本地运行(因为它无论如何都在同一个/我的服务器上执行)或其他一些安全措施?目前,这些行在 nsupdate 命令中使用服务器的官方 DNS 名称,而不是“localhost”或其他名称(不确定是否支持):
server ns1.external-domain-name.de
zone external-domain-name.de.
key ddns.external-domain-name.de.key MySecretKey12345
update delete ddns.external-domain-name.de.
update add ddns.external-domain-name.de 60 A
send
答案1
秘密已加密。我们不能告诉你力量由于您没有向我们提供具体信息(通过 TSIG 的 HMAC-MD5 等),因此我们无法确定 DDNS 机密是否包含加密,但可以肯定的是,DDNS 机密包含某种加密包装器。否则,正如您所指出的那样,它们很容易受到重放攻击。
答案2
命令可以以明文形式发送,但用于允许更新的密钥却不能。
但无论如何,如果你需要在同一台主机上进行更新,使用-l
带有 的选项会更容易nsupdate
。它将使用自生成的密钥并仅与 localhost 通信:
-l
仅限本地主机模式。这会将服务器地址设置为 localhost(禁用服务器,以便服务器地址无法被覆盖)。与本地服务器的连接将使用 /var/run/named/session.key 中的 TSIG 密钥,如果任何本地主区域将更新策略设置为本地,则该密钥由 named 自动生成。
为此,您需要添加update-policy local;
动态区域定义:
zone "dyn.example.com" {
type master;
file "/var/cache/bind/dyn.example.com";
update-policy local;
};
并且您需要重新启动服务器或systemctl restart bind9
系统上的等效程序。rndc reload
不足以使其生成特殊的“local-ddns”密钥。
如果您需要在 中设置更多规则update-policy
,则需要将其替换update-policy local;
为包含的部分grant local-ddns zonesub ANY;
。您不能同时拥有简单的“本地”行和真正的策略部分。因此,您需要类似以下内容:
zone "dyn.example.com" {
type master;
file "/var/cache/bind/dyn.example.com";
update-policy {
grant local-ddns zonesub ANY; // Generates a "local-ddns" key in /var/run/named/session.key
// other update policies
// grant *.dyn.example.com. self *.dyn.example.com. ANY;
};
};
然后你可以进行如下更新:
host=myhost: ip=10.1.2.3.4
printf "update add $host.dyn.example.com. 3600 A $ip\n\n" | nsupdate -l
如果您使用配置文件来提供nsupdate -l
,则它们中不能有一行server ...
,否则您将收到此错误:
cannot reset server in localhost-only mode
syntax error