Рассмотрим следующий сценарий:
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, и наоборот.
Вопросы:
ad.example.com
и unix.example.com
; это поддерживается?Спасибо!
РЕДАКТИРОВАТЬ: я понял дополнительную информацию с помощью @PatrickMevzek в комментариях.
DNS-сервер Windows не проверял DNSSEC. Мне пришлось вручную включить его с помощью команды: DnsCmd.exe /Config /enablednssec 1
Получены якоря корневого доверия после Restart-Service DNS
, командой: DnsCmd.exe /RetrieveRootTrustAnchors
После этого две команды на обоих dc1
и dc2
; BIND9 Linux смог разрешить адреса без жалоб на нарушение доверия. Нет необходимости добавлять записи NS в CloudFlare.
Но у меня есть еще одна проблема при попытке проверки на DNS-серверах Windows; когда используешь delv
с участием +vtrace
в BIND9 он работает как положено:
[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 Server, он полностью терпит неудачу с ошибкой разрыва доверия:
[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