请考虑以下情形:
example.com
托管在 CloudFlare 上,并由 CloudFlare DNSSEC 签名。 一切运行正常example.com
。
在公司内部,我们有一些内部私人区域,用于 Active Directory 和 Unix 域:ad.example.com
和unix.example.com
。
由于我无法为这些区域启用退出功能,因此example.com
我只能为内部区域启用 DNSSEC。unix.example.com
一切似乎都按预期运行。但ad.example.com
什么都不起作用。
基本上,内部名称服务器上的信任链已被打破:
Jul 2 20:36:14 idm1 named-pkcs11[4345]: broken trust chain resolving 'wpad.ad.example.com/A/IN': 172.21.1.2#53
Jul 2 20:36:17 idm1 named-pkcs11[4345]: validating dc1.ad.example.com/A: bad cache hit (dc1.ad.example.com/DS)
Jul 2 20:36:17 idm1 named-pkcs11[4345]: broken trust chain resolving 'dc1.ad.example.com/A/IN': 172.21.1.2#53
Jul 2 20:37:18 idm1 named-pkcs11[4345]: validating ad.example.com/SOA: got insecure response; parent indicates it should be secure
Jul 2 20:37:18 idm1 named-pkcs11[4345]: no valid RRSIG resolving 'dc1.ad.example.com/DS/IN': 172.21.1.2#53
Jul 2 20:37:18 idm1 named-pkcs11[4345]: validating ad.example.com/SOA: got insecure response; parent indicates it should be secure
Jul 2 20:37:18 idm1 named-pkcs11[4345]: no valid RRSIG resolving 'dc1.ad.example.com/DS/IN': 172.21.1.3#53
Jul 2 20:37:18 idm1 named-pkcs11[4345]: no valid DS resolving 'dc1.ad.example.com/A/IN': 172.21.1.2#53
Jul 2 20:37:18 idm1 named-pkcs11[4345]: validating dc1.ad.example.com/A: bad cache hit (dc1.ad.example.com/DS)
Jul 2 20:37:18 idm1 named-pkcs11[4345]: broken trust chain resolving 'dc1.ad.example.com/A/IN': 172.21.1.3#53
我知道我需要在父区域添加 DS 记录,因此我在 CloudFlare 上为 添加两个条目,为ad.example.com
添加一个条目unix.example.com
。
DS 条目由 Linux 机器使用以下命令生成:
为了unix.example.com
:
dig unix.example.com. DNSKEY @172.21.1.5 > dnskey-unix.txt
dnssec-dsfromkey -f dnskey-unix.txt -2 unix.example.com
然后我在CloudFlare上添加了以下DS注册:
unix.example.com. IN DS 54355 8 2 3658D593EF31ED0E9D2369DF09D63F9B48FB5CD25A1AA336A2E4EE0AF55150AE
为了ad.example.com
:
dig ad.example.com. DNSKEY @172.21.1.2 > dnskey-ad.txt
dnssec-dsfromkey -f dnskey-ad.txt -2 ad.example.com
同样unix.example.com
,我在 CloudFlare 上添加了以下内容
ad.example.com. IN DS 63807 13 2 32D219185C727AE506B5565D522728D1B3A8677F737B07EC3BFEC2092B96F737
ad.example.com. IN DS 39922 13 2 000525D1A95F86820CA668D91E952BCCFA7000A5364A3E30AC43D3ACCDB62DAD
由于 AD 使用两个独立的区域,因此我也生成了 DS 条目_msdcs.ad.example.com
:
dig _msdcs.ad.example.com. DNSKEY @172.21.1.2 > dnskey-ad-msdcs.txt
dnssec-dsfromkey -f dnskey-ad-msdcs.txt -2 _msdcs.ad.example.com
并将结果添加到其父区域ad.example.com
::
_msdcs.ad.example.com. IN DS 19659 13 2 9F1D143D601B976F05EAB6C1C14C998537B80511349B7BDEB0CFFE2A0882DAF3
_msdcs.ad.example.com. IN DS 14682 13 2 4B72A44979E24321724D870E17E85D7099260132A1645F236511F4FC545B98E8
就是这样。我以为这个实现是正确的,但事实并非如此。对于域中的机器来说,unix.example.com
这是可以的:
[root@idm1 ~]# dig +dnssec A idm1.unix.example.com
; <<>> DiG 9.11.13-RedHat-9.11.13-3.el8 <<>> +dnssec A idm1.unix.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21833
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 3
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; COOKIE: 203752b5a85d2bb2c796f55b5efe71f71401f1abaf39c190 (good)
;; QUESTION SECTION:
;idm1.unix.example.com. IN A
;; ANSWER SECTION:
idm1.unix.example.com. 1200 IN A 172.21.1.5
idm1.unix.example.com. 1200 IN RRSIG A 8 5 1200 20200724170015 20200702220913 24543 unix.example.com. kVOJD49rzVaQLtLBdxyUTU2E+1CQscSClWjs7RgGj0nMAg/6Va1GEw0j jlDl2s1FOKxbJCN7g50UT+MjgTPkgQozwUPOBYeaKB6npTrROwZH3vBG yT346elPNP7x5fRO41ATUrf22PauCvo73+1+iTmTsizxVwda8u88H5Ld CD4+laE9GphuHdc2usITGaKze4UBwA81ExN2UpwOJYPhyHFzOAF3oBg8 XCPoJxQhgHNmkCAmTZCmWeD+kPkyaMSv9clF/23lZ9YJ+cICHtCzWWTM yEC7988sAk2MVIzptF0OYQ+TzsVDxcM8TPlhZNZAz+SE3hVPalY31TUc bm+DiQ==
;; AUTHORITY SECTION:
unix.example.com. 86400 IN NS idm2.unix.example.com.
unix.example.com. 86400 IN NS idm1.unix.example.com.
unix.example.com. 86400 IN RRSIG NS 8 4 86400 20200728184956 20200702220913 24543 unix.example.com. iVLmN9NkjI08NPMObfhDFh2csUnMkEmFTi0UhphhedbL2wFc1MsP37gS lwSXK8gjPiopC1gbfRj9d0BwG6fJCrc9+1DUnUMKDqqpsr2/U3prOJWs 70l+4m1S6OI5vemhGMZuSzfPW7hGnPCY3xzYnzMJ3atvPwBJzG5tx2Rd V59sYgJBc7LDZxhGJxxtc5V2cNbCo6q51zoDV8OeDMaBK5n6shhnbpOq 3mlTC757vYxzwl8akvWDvQtgTJhZKuye+PSBn3dyqIcoSr6ZG/Ymm23n l89DzpvNVwRw0xtw7lmvQWsj0w1RefPwKG9sytGjCNw9CZ30IIeqvE+o hPP3Gw==
;; ADDITIONAL SECTION:
idm2.unix.example.com. 1200 IN A 172.21.1.6
idm2.unix.example.com. 1200 IN RRSIG A 8 5 1200 20200718050002 20200702220913 24543 unix.example.com. RSKi/wms8XQevqzqY/EnvApSKY4cMvTwZtPImyngb8EJ/ONBfljkZDrj YTIh36fg8UnDE4WeaDjhrLAEV0/7T5f1udC/Eje0i7ezH7F301/8qaQ9 1BHWOoK+viwisa5w4ywZMq6mTcZCGs+RpgudIcczkW4RlmW/zpRnqYjq f/U4a5GEXV64s7Nc7ZfMxvssM9r1QknX3XC8yWKPlgjCRn/be03bhA+z UNfNpBU1684q1/hTJ0f+d0BFtb1ZNkZ2TIceXCDIum8UQCEsH6XLjtYI x4TnKUtG7WVL65xKc7SecZY1v/Ew9hMtnmF42+9rV95Rj2vGdA+QJF98 8H1xJw==
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Jul 02 20:47:03 -03 2020
;; MSG SIZE rcvd: 1079
但不适用于以下机器ad.example.com
:
[root@idm1 ~]# dig +dnssec A dc1.ad.example.com
; <<>> DiG 9.11.13-RedHat-9.11.13-3.el8 <<>> +dnssec A dc1.ad.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 9918
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; COOKIE: 2c9efcfef9cb965cfc1898755efe7260ec5a94eb75e18a03 (good)
;; QUESTION SECTION:
;dc1.ad.example.com. IN A
;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Jul 02 20:48:48 -03 2020
;; MSG SIZE rcvd: 83
另一个相关信息;Unix 域上的名称服务器被配置为仅转发到 AD 上的区域,反之亦然。
问题:
- 我不确定是否可以通过这种方式设置 DNSSEC。
- 在 CloudFlare 上,显然没有内部区域的 NS 条目,它们应该从外部不可见,尽管有和的 DS 条目
ad.example.com
;unix.example.com
这支持吗?
谢谢!
编辑:我在评论中在@PatrickMevzek 的帮助下找到了更多信息。
Windows DNS 服务器未验证 DNSSEC。我必须使用以下命令手动启用它:
DnsCmd.exe /Config /enablednssec 1
使用以下命令获取根信任锚
Restart-Service DNS
:DnsCmd.exe /RetrieveRootTrustAnchors
dc1
在和上执行这两个命令后dc2
,Linux 的 BIND9 能够解析地址,而不会抱怨信任中断。无需在 CloudFlare 上添加 NS 条目。
但是当我尝试在 Windows DNS 服务器上进行验证时,我遇到了另一个问题;在 BIND9 上使用时,delv
它+vtrace
可以按预期工作:
[root@idm1 ~]# delv +vtrace dc1.ad.example.com.br @172.21.1.5
;; fetch: dc1.ad.example.com.br/A
;; validating dc1.ad.example.com.br/A: starting
;; validating dc1.ad.example.com.br/A: attempting positive response validation
;; fetch: ad.example.com.br/DNSKEY
;; validating ad.example.com.br/DNSKEY: starting
;; validating ad.example.com.br/DNSKEY: attempting positive response validation
;; fetch: ad.example.com.br/DS
;; validating ad.example.com.br/DS: starting
;; validating ad.example.com.br/DS: attempting positive response validation
;; fetch: example.com.br/DNSKEY
;; validating example.com.br/DNSKEY: starting
;; validating example.com.br/DNSKEY: attempting positive response validation
;; fetch: example.com.br/DS
;; validating example.com.br/DS: starting
;; validating example.com.br/DS: attempting positive response validation
;; fetch: com.br/DNSKEY
;; validating com.br/DNSKEY: starting
;; validating com.br/DNSKEY: attempting positive response validation
;; fetch: com.br/DS
;; validating com.br/DS: starting
;; validating com.br/DS: attempting positive response validation
;; fetch: br/DNSKEY
;; validating br/DNSKEY: starting
;; validating br/DNSKEY: attempting positive response validation
;; fetch: br/DS
;; validating br/DS: starting
;; validating br/DS: attempting positive response validation
;; fetch: ./DNSKEY
;; validating ./DNSKEY: starting
;; validating ./DNSKEY: attempting positive response validation
;; validating ./DNSKEY: verify rdataset (keyid=20326): success
;; validating ./DNSKEY: signed by trusted key; marking as secure
;; validating br/DS: in fetch_callback_validator
;; validating br/DS: keyset with trust secure
;; validating br/DS: resuming validate
;; validating br/DS: verify rdataset (keyid=46594): success
;; validating br/DS: marking as secure, noqname proof not needed
;; validating br/DNSKEY: in dsfetched
;; validating br/DNSKEY: dsset with trust secure
;; validating br/DNSKEY: verify rdataset (keyid=2471): success
;; validating br/DNSKEY: marking as secure (DS)
;; validating com.br/DS: in fetch_callback_validator
;; validating com.br/DS: keyset with trust secure
;; validating com.br/DS: resuming validate
;; validating com.br/DS: verify rdataset (keyid=33739): success
;; validating com.br/DS: marking as secure, noqname proof not needed
;; validating com.br/DNSKEY: in dsfetched
;; validating com.br/DNSKEY: dsset with trust secure
;; validating com.br/DNSKEY: verify rdataset (keyid=33095): success
;; validating com.br/DNSKEY: marking as secure (DS)
;; validating example.com.br/DS: in fetch_callback_validator
;; validating example.com.br/DS: keyset with trust secure
;; validating example.com.br/DS: resuming validate
;; validating example.com.br/DS: verify rdataset (keyid=33095): success
;; validating example.com.br/DS: marking as secure, noqname proof not needed
;; validating example.com.br/DNSKEY: in dsfetched
;; validating example.com.br/DNSKEY: dsset with trust secure
;; validating example.com.br/DNSKEY: verify rdataset (keyid=2371): success
;; validating example.com.br/DNSKEY: marking as secure (DS)
;; validating ad.example.com.br/DS: in fetch_callback_validator
;; validating ad.example.com.br/DS: keyset with trust secure
;; validating ad.example.com.br/DS: resuming validate
;; validating ad.example.com.br/DS: verify rdataset (keyid=34505): success
;; validating ad.example.com.br/DS: marking as secure, noqname proof not needed
;; validating ad.example.com.br/DNSKEY: in dsfetched
;; validating ad.example.com.br/DNSKEY: dsset with trust secure
;; validating ad.example.com.br/DNSKEY: no RRSIG matching DS key
;; validating ad.example.com.br/DNSKEY: verify rdataset (keyid=63807): success
;; validating ad.example.com.br/DNSKEY: marking as secure (DS)
;; validating dc1.ad.example.com.br/A: in fetch_callback_validator
;; validating dc1.ad.example.com.br/A: keyset with trust secure
;; validating dc1.ad.example.com.br/A: resuming validate
;; validating dc1.ad.example.com.br/A: verify rdataset (keyid=3675): success
;; validating dc1.ad.example.com.br/A: marking as secure, noqname proof not needed
; fully validated
dc1.ad.example.com.br. 3556 IN A 172.21.1.2
dc1.ad.example.com.br. 3556 IN RRSIG A 8 5 3600 20200713013625 20200703003625 3675 ad.example.com.br. Ov1CyF1c7p7NoYWGx041NG76lXEI3gCMYECklGYSd5pqQDpgHP1P7Tuc 9/6WulDJBaHW0FAvAiclpH1M7xmzsSEHmTamnuMeHDP6zsgXTu7dmRr4 YLwH5lidELNt1wFffNfDFu6/xHuQcxWppgqf8so1zBhz/+TYQKFbvs+/ zOs=
但是,当我在 Windows DNS 服务器上执行相同查询时,它完全失败并出现信任损坏错误:
[root@idm1 ~]# delv +vtrace dc1.ad.example.com.br @172.21.1.2
;; fetch: dc1.ad.example.com.br/A
;; validating dc1.ad.example.com.br/A: starting
;; validating dc1.ad.example.com.br/A: attempting positive response validation
;; fetch: ad.example.com.br/DNSKEY
;; validating ad.example.com.br/DNSKEY: starting
;; validating ad.example.com.br/DNSKEY: attempting positive response validation
;; fetch: ad.example.com.br/DS
;; chase DS servers resolving 'ad.example.com.br/DS/IN': 172.21.1.2#53
;; fetch: example.com.br/NS
;; validating example.com.br/NS: starting
;; validating example.com.br/NS: attempting positive response validation
;; fetch: example.com.br/DNSKEY
;; validating example.com.br/DNSKEY: starting
;; validating example.com.br/DNSKEY: attempting positive response validation
;; fetch: example.com.br/DS
;; validating example.com.br/DS: starting
;; validating example.com.br/DS: attempting positive response validation
;; fetch: com.br/DNSKEY
;; validating com.br/DNSKEY: starting
;; validating com.br/DNSKEY: attempting positive response validation
;; fetch: com.br/DS
;; validating com.br/DS: starting
;; validating com.br/DS: attempting positive response validation
;; fetch: br/DNSKEY
;; validating br/DNSKEY: starting
;; validating br/DNSKEY: attempting positive response validation
;; fetch: br/DS
;; validating br/DS: starting
;; validating br/DS: attempting positive response validation
;; fetch: ./DNSKEY
;; validating ./DNSKEY: starting
;; validating ./DNSKEY: attempting positive response validation
;; validating ./DNSKEY: verify rdataset (keyid=20326): success
;; validating ./DNSKEY: signed by trusted key; marking as secure
;; validating br/DS: in fetch_callback_validator
;; validating br/DS: keyset with trust secure
;; validating br/DS: resuming validate
;; validating br/DS: verify rdataset (keyid=46594): success
;; validating br/DS: marking as secure, noqname proof not needed
;; validating br/DNSKEY: in dsfetched
;; validating br/DNSKEY: dsset with trust secure
;; validating br/DNSKEY: verify rdataset (keyid=2471): success
;; validating br/DNSKEY: marking as secure (DS)
;; validating com.br/DS: in fetch_callback_validator
;; validating com.br/DS: keyset with trust secure
;; validating com.br/DS: resuming validate
;; validating com.br/DS: verify rdataset (keyid=33739): success
;; validating com.br/DS: marking as secure, noqname proof not needed
;; validating com.br/DNSKEY: in dsfetched
;; validating com.br/DNSKEY: dsset with trust secure
;; validating com.br/DNSKEY: verify rdataset (keyid=33095): success
;; validating com.br/DNSKEY: marking as secure (DS)
;; validating example.com.br/DS: in fetch_callback_validator
;; validating example.com.br/DS: keyset with trust secure
;; validating example.com.br/DS: resuming validate
;; validating example.com.br/DS: verify rdataset (keyid=33095): success
;; validating example.com.br/DS: marking as secure, noqname proof not needed
;; validating example.com.br/DNSKEY: in dsfetched
;; validating example.com.br/DNSKEY: dsset with trust secure
;; validating example.com.br/DNSKEY: verify rdataset (keyid=2371): success
;; validating example.com.br/DNSKEY: marking as secure (DS)
;; validating example.com.br/NS: in fetch_callback_validator
;; validating example.com.br/NS: keyset with trust secure
;; validating example.com.br/NS: resuming validate
;; validating example.com.br/NS: verify rdataset (keyid=34505): success
;; validating example.com.br/NS: marking as secure, noqname proof not needed
;; validating ad.example.com.br/DNSKEY: in dsfetched
;; validating ad.example.com.br/DNSKEY: falling back to insecurity proof (SERVFAIL)
;; validating ad.example.com.br/DNSKEY: checking existence of DS at 'br'
;; validating ad.example.com.br/DNSKEY: checking existence of DS at 'com.br'
;; validating ad.example.com.br/DNSKEY: checking existence of DS at 'example.com.br'
;; validating ad.example.com.br/DNSKEY: checking existence of DS at 'ad.example.com.br'
;; fetch: ad.example.com.br/DS
;; chase DS servers resolving 'ad.example.com.br/DS/IN': 172.21.1.2#53
;; fetch: example.com.br/NS
;; validating example.com.br/NS: starting
;; validating example.com.br/NS: attempting positive response validation
;; validating example.com.br/NS: keyset with trust secure
;; validating example.com.br/NS: verify rdataset (keyid=34505): success
;; validating example.com.br/NS: marking as secure, noqname proof not needed
;; validating ad.example.com.br/DNSKEY: in dsfetched2: SERVFAIL
;; no valid DS resolving 'ad.example.com.br/DNSKEY/IN': 172.21.1.2#53
;; validating dc1.ad.example.com.br/A: in fetch_callback_validator
;; validating dc1.ad.example.com.br/A: fetch_callback_validator: got SERVFAIL
;; broken trust chain resolving 'dc1.ad.example.com.br/A/IN': 172.21.1.2#53
;; resolution failed: broken trust chain