我有一个小型内部网络,其中有运行虚拟机管理程序的物理机,而这些虚拟机又运行着多个 KVM Ubuntu 虚拟机。我该如何设置内部动态 DNS 服务器,以便当我运行脚本创建新虚拟机时,该虚拟机可以自动在 DNS 服务器中注册?
绑定似乎是 Linux 的标准 DNS 服务器,但它似乎是为更“静态”的 DNS 模型而设计的。动态更新它需要一个复杂的脚本,该脚本必须通过 SSH 进入 DNS 服务器,编辑配置文件,然后重新启动服务器。这似乎不是一个非常优雅的解决方案。有更好的选择吗?
我看到一个类似问题,尽管他们要求在亚马逊上提供公共设置的解决方案。我的服务器完全是私有的,我不想依赖外部 VM 主机或动态 DNS 提供商。
答案1
实际上,Bind 能够通过 RFC 2136 标准消息进行动态 DNS 更新。使用 nsupdate 工具和正确的配置(不是很难,但也不是完全不重要)。
验证这些更新消息的选项包括 1) 仅允许某些 IP 发送更新消息 2a) TSIG 对称加密 2b) 基于 SIG(0) 的公钥加密或 1 和 2 的组合*。可以在其他地方找到说明这里
在亲自实施时,我发现最大的问题是给予 named 在 /var/named 中足够的写入权限。它需要能够在目录中创建文件,并且对动态区域的文件具有写入权限。
Sig(0) 密钥由 dnssec-keygen 实用程序生成,名称类型为 HOST,密钥类型为 KEY。例如(可能不准确)(RSAMD5 涵盖几乎所有绑定包):
dnssec-keygen -a RSAMD5 -b 1024 -n HOST -f 密钥 host.domain.tld
生成的 .key 文件将被添加到您的区域文件中,.private 将在使用 nsupdate 的命令行上指定。
答案2
我确实通过 nsupdate 设置了与动态更新的绑定(如 CarbonLifeForm 所述),并将其与一个简单的 Perl 脚本结合起来,该脚本通过加密的 HTTPS REST 请求调用,检查子域/密码组合,然后使用请求的 IP 调用 nsupdate。
来自任何客户端的示例更新调用(它将自动将相应的子域设置为该客户端的公共 IP)
只需使用任意浏览器访问(在此示例中,https 通过端口 12345 提供):
https://ddns.YOURDOMAIN.net:12345/update-my-ip.pl?subdomain=***&password=***
或通过命令行(例如通过 cronjob 每 15 分钟更新一次):
www-browser -dump 'https://ddns.YOURDOMAIN.net:12345/update-my-ip.pl?subdomain=***&password=***'
以下是 perl 脚本 update-my-ip.pl:
#!/usr/bin/perl
use strict;
use CGI;
use Digest::SHA1 qw(sha1_hex);
my %accounts = (
# create via: sha1sum, then type password, then press Ctrl-D to calculate checksum (echo with pipe gives wrong result!)
# update via: www-browser -dump 'https://ddns.YOURDOMAIN.net:12345/update-my-ip.pl? subdomain=***&password=***'
'YOURSUBDOMAIN1' => '93485720985720394853452345235-fake-sha1-checksum1',
'YOURSUBDOMAIN2' => '93485720985720394853452345235-fake-sha1-checksum2',
'YOURSUBDOMAIN3' => '93485720985720394853452345235-fake-sha1-checksum3',
);
my $cgi = new CGI;
print "Content-type: text/html\n\n";
my $subdomain = $cgi->param('subdomain');
my $password = $cgi->param('password');
if( !$password || !$subdomain || length($password) <= 3 || length($subdomain) <= 1)
{
print "ERROR\n";
exit 0;
}
my $sha1 = sha1_hex($password);
my $ip = $ENV{'REMOTE_ADDR'};
my $should_be_sha1 = $accounts{$subdomain};
if( $sha1 && length($sha1) > 10 && $sha1 eq $should_be_sha1)
{
print "START: ddns.YOURDOMAIN.net DNS updating <a href=\"http://$subdomain.YOURDOMAIN.net\">http://$subdomain.YOURDOMAIN.net</a> (<a href=\"https://$subdomain.YOURDOMAIN.net\">SSL</a>) to IP <a href=\"http://$ip\">$ip</a>.<br/>\n";
my $out = `echo "update delete $subdomain.YOURDOMAIN.net A\n\n" | nsupdate 2>&1`;
print "STEP1 $out<br/>\n";
$out = `echo "update add $subdomain.YOURDOMAIN.net 60 A $ip\n\n" | nsupdate 2>&1`;
print "STEP2 $out<br/>\n";
print "DONE<br/>\n";
}
else
{
print "ERROR\n";
}
答案3
由于您的服务器都是私有的,我假设您不想将 IP 地址发布到更大的互联网上。这实际上简化了事情。
我知道在我的小型网络中我已经取得了成功域名系统,一个无效的简单 DNS 和 DHCP 服务器。它应该允许客户端在获得 DHCP 租约时将自己添加到 DNS 服务器。
进一步阅读:https://superuser.com/questions/312515/dnsmasq-without-altering-etc-hosts-file-manually
答案4
一般而言(以 Windows 为中心):
安装支持动态 DNS 的 DNS 服务器
在服务器上配置适当的 DNS 区域
配置 DNS 服务器以允许区域进行安全和不安全的 DNS 更新
使用与 DNS 区域匹配的 DNS 后缀配置 DNS 客户端
配置 DNS 客户端以使用 DNS 服务器进行名称解析
配置 DNS 客户端以在 DNS 中注册