I have a fairly complicated split-brain DNS setup, and I'm hoping to add DNSSEC to the ecosystem to support SSHFP (which requires DNSSEC). I am not totally sure I understand how this needs to work, and need some specific help as to what happens to complete the chain of trust.
I have a hosted domain, "example.com". The registrar supports DNSSEC and it is enabled. I have multiple subdomains that branch off of that which are hosted inside my network. Externally, I need the public IP of my network, and internally, I need a private IP. My internal network is a domain, specifically "domain.example.com". I have an A record for "domain.example.com" pointing to the public IP of my network at the registrar.
Inside the network, I have an internal-only bind9 DNS server. It is authoritative for the zones it serves; for example, "zabbix.domain.com" resolves the internal IP of the web proxy in the network, but externally it resolves the public IP of the network (which hits the web proxy). I know these will never fully achieve DNSSEC without a huge effort, and that's fine for now.) Separately, I have lots of servers at "server.domain.example.com" and I want to create SSHFP records for these, and the Bind9 server should be authoritative for domain.example.com.
I have DNSSEC enabled on the zone and get the DNSKEY value back using dig/delv, but ultimately DNSSEC validation fails due to a broken chain of trust. This is, as I understand it, because there needs to be a DS record on the registrar side for domain.example.com as a complement to the DNSKEY values for my internal resolver's domain.example.com zone. My registrar does NOT allow me to update that record self-service, but I can submit a ticket to have them do it, and I want to make sure I'm asking for the right things.
I've done research into whether or not I need to add trust anchors to my internal zone, but my understanding is I do not. Below is the output of (sensitive bits removed) some commands to test:
dig @10.##.##.## domain.example.com DNSKEY +dnssec +multi
; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> @10.##.##.## domain.example.com DNSKEY +dnssec +multi
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24783
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: 7e8e8e3927e50bbb0100000066d8e4242a8bbf513c31dcd6 (good)
;; QUESTION SECTION:
;domain.example.com. IN DNSKEY
;; ANSWER SECTION:
domain.example.com. 3600 IN DNSKEY 257 3 13 (
qwertyuiop==
) ; KSK; alg = ECDSAP256SHA256 ; key id = 51820
domain.example.com. 3600 IN DNSKEY 257 3 13 (
qwertyuiop==
) ; KSK; alg = ECDSAP256SHA256 ; key id = 18461
domain.example.com. 3600 IN RRSIG DNSKEY 13 3 3600 (
20240917225048 20240903215048 18461 domain.example.com.
qwertyuiop== )
domain.example.com. 3600 IN RRSIG DNSKEY 13 3 3600 (
20240917225048 20240903215048 51820 domain.example.com.
qwertyuiop== )
;; Query time: 0 msec
;; SERVER: 10.##.##.###53(10.##.##.##) (UDP)
;; WHEN: Wed Sep 04 15:50:12 PDT 2024
;; MSG SIZE rcvd: 463
delv @10.##.##.## domain.example.com. A +rtrace
;; fetch: domain.example.com/A
;; fetch: domain.example.com/DNSKEY
;; fetch: domain.example.com/DS
;; fetch: example.com/DNSKEY
;; fetch: example.com/DS
;; fetch: com/DNSKEY
;; fetch: com/DS
;; fetch: ./DNSKEY
;; insecurity proof failed resolving 'domain.example.com/DNSKEY/IN': 10.##.##.###53
;; broken trust chain resolving 'domain.example.com/A/IN': 10.##.##.###53
;; resolution failed: broken trust chain