如何设置简单的自托管动态 DNS 服务器

如何设置简单的自托管动态 DNS 服务器

我有一个小型内部网络,其中有运行虚拟机管理程序的物理机,而这些虚拟机又运行着多个 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 为中心):

  1. 安装支持动态 DNS 的 DNS 服务器

  2. 在服务器上配置适当的 DNS 区域

  3. 配置 DNS 服务器以允许区域进行安全和不安全的 DNS 更新

  4. 使用与 DNS 区域匹配的 DNS 后缀配置 DNS 客户端

  5. 配置 DNS 客户端以使用 DNS 服务器进行名称解析

  6. 配置 DNS 客户端以在 DNS 中注册

相关内容