![如何将 DNS 资源记录更新从 Linux 发送到仅接受安全更新的 Windows Active Directory DNS 区域?](https://linux22.com/image/786089/%E5%A6%82%E4%BD%95%E5%B0%86%20DNS%20%E8%B5%84%E6%BA%90%E8%AE%B0%E5%BD%95%E6%9B%B4%E6%96%B0%E4%BB%8E%20Linux%20%E5%8F%91%E9%80%81%E5%88%B0%E4%BB%85%E6%8E%A5%E5%8F%97%E5%AE%89%E5%85%A8%E6%9B%B4%E6%96%B0%E7%9A%84%20Windows%20Active%20Directory%20DNS%20%E5%8C%BA%E5%9F%9F%EF%BC%9F.png)
我的公司有一个现有的 Windows AD DNS 区域,我不直接管理它(但我知道管理它的人)。该区域将接受动态更新,但更新必须是“安全的”。我有一台 Linux 机器(它运行 IPAM 系统),我想从它向 AD 发送任意 DNS 更新。如何做到这一点?
答案1
首先,有几个假设:
- 您的 AD DNS 服务器已投入运行。它已配置一个区域,只要更新是安全的,该区域就允许更新。
- 您有一些 AD 凭据,具有更新区域的权限。我认为该
DNSAdmin
组可能默认被授予权限(不确定),因此让您的用户成为该组的成员。最好使用具有最低权限的服务帐户。 - 您有一个可以发送更新的 Linux 机器。您的版本
nsupdate
支持-g
启用 GSS-TSIG 的标志。
让我们开始吧。我们需要做一些设置。
首先,我们需要获取并配置 Kerberos 5 身份验证后端。
- 如果你使用的是 Ubuntu,可以使用 安装所需的工具
apt install sssd-krb5 krb5-user
。如果你使用的是其他发行版,请查看评论以查看是否有人指出了你需要哪些软件包。 - 接下来,我们需要添加 AD 的信息。这不是 DNS 信息,而是有关如何获取票证的 Kerberos 信息。使用您最喜欢的文本编辑器打开文件
krb5.conf
;对于 Ubuntu 来说就是/etc/krb5.conf
。 - 在该
[libdefaults]
部分下,添加如下条目是明智之举:default_realm = CORP.EXAMPLE.LOCAL
。不知道为什么,但 Realm 似乎需要大写。 - 在该
[realms]
部分下,我们需要添加 AD 域和服务器(域控制器)信息。请遵循此模板。再次将领域名称设为大写。
[realms]
CORP.EXAMPLE.LOCAL = {
kdc = ms-dc-01.corp.example.local:88
kdc = ms-dc-02.corp.example.local:88
admin_server = ms-dc-01.corp.example.local
default_domain = corp.example.local
}
好的,让我们看看它是否有效。
接下来,我们将尝试通过身份验证从 AD 获取 Kerberos 票证。
- 运行命令。希望它会提示您输入密码。希望仅此而已。
kinit [email protected]
- 无法
kinit
接受密码?请尝试启用跟踪输出,如下所示:KRB5_TRACE=/dev/stdout kinit ...
。请注意,有时用户名可能会导致大小写问题。 - 看看你是否有票。运行命令
klist
。希望你能看到类似这样的内容。如果没有,请后退一步并尝试读取跟踪输出。
Valid starting Expires Service principal
05/19/2023 17:22:42 05/20/2023 03:22:42 krbtgt/[email protected]
- 暂停一下。我们所做的是使用我们的凭证向 AD 请求 Kerberos 票证。如果票证被授予,它将被放入客户端的缓存中。当您使用时,您正在查看缓存
klist
。您可能不应该将其留在缓存中超过您需要的时间,因为 root Linux 用户可以读取和使用缓存。您可以使用命令终止票证kdestroy
。 - 使用该票证,让我们看看是否可以向 DNS 服务器发送 DNS 更新。运行该
nsupdate
命令。这将为您提供一个新的命令提示符,等待有关您要执行的操作的指令。输入以下命令:
gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update add my-new-test-record.corp.example.local. 3600 A 1.1.1.1
show
send
quit
注意,有些服务器不需要 TTL 参数,有些则需要。耸耸肩。
- 使用您最喜欢的 DNS 实用程序询问 DNS 服务器是否有该记录:
host -ta my-new-test-record.corp.example.local chicago-dns-14.corp.example.local
- 现在,您可以以几乎相同的方式删除该记录。
nsupdate
再次运行。输入以下命令:
gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update delete new-server-test-record.corp.example.local. A 1.1.1.1
send
请注意,删除时不需要包含 TTL。
- 运行
kdestroy
以从缓存中删除您的 Kerberos 票证。
太棒了,下一步是什么?
好的,以上就是手动操作的方法。现在,让我们将密码放入 keytab 文件中,这样我们就不必每次都输入密码,而且密码也不会保存在明文文件中供其他用户阅读。
- 运行
ktutil
命令。输入以下命令:
addent -password -p [email protected] -k 0 -f
- 希望您能收到输入密码的提示。然后继续:
wkt username.keytab
quit
- 好的,希望您现在有一个 keytab 文件。此文件包含您的密码的大多数安全版本。我不知道具体是怎么回事,但它以某种方式加密了。
- 现在我们有了 keytab 文件,我们可以
kinit
使用一些新参数运行,这样我们就可以避免输入密码:kinit -kt username.keytab [email protected]
- 运行 a
klist
以查看您是否获得了票。 - 运行
kdestroy
以撕毁您的票。
好的,现在让我们看看是否可以将其变成一个真正复杂的单行代码。
- 运行命令:
kinit -kt username.keytab [email protected] && echo "gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update delete new-server-test-record.corp.example.local. 3600 A 1.1.1.1
send" |nsupdate && kdestroy
我知道这看起来不止一行,但是第一行的引号会让 Bash 等待,直到你关闭引号。
你能编写这个脚本吗?
当然
#!/bin/bash
if [ $# == 3 ]; then
if [ $1 == "add" ] ; then
kinit -kt DnsAdministrator.keytab [email protected]
echo "gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update $1 $2.corp.example.local. 7200 A $3
send" |nsupdate
kdestroy
elif [ $1 == "delete" ] || [ $1 == "del" ] ; then
kinit -kt DnsAdministrator.keytab [email protected]
echo "gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update $1 $2.corp.example.local. A $3
send" |nsupdate
kdestroy
else
echo "<action> must be either add or delete."
fi
else
echo "There must be precisely 3 parameters: <action>, <record-name> and <ip-address>"
fi
然后像这样使用它:
./my-dns-script.sh add my-new-test-record 1.1.1.1
或者
./my-dns-script.sh delete my-new-test-record 1.1.1.1