Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNSSEC signature problem for non-existent CAA record #696

Closed
Darkspirit opened this issue Feb 27, 2019 · 39 comments · Fixed by #697
Closed

DNSSEC signature problem for non-existent CAA record #696

Darkspirit opened this issue Feb 27, 2019 · 39 comments · Fixed by #697

Comments

@Darkspirit
Copy link
Contributor

Darkspirit commented Feb 27, 2019

I noticed that Let's Encrypt fails to issue a certificate for a subdomain that doesn't have a CAA record.

AcmeChallenge { url: "https://acme-staging-v02.api.letsencrypt.org/acme/challenge/8jXImq1gAHL7wCgdnvQdAwq1AI5-ZEMC53OJh8ID5Xo/255101671", type: "dns-01", status: "invalid", validated: None, error: Some(AcmeError { type: "urn:ietf:params:acme:error:dns", detail: "DNS problem: SERVFAIL looking up CAA for www2.ikenmeyer.com", status: 400 }), token: "SZxytWSDIoSPxNwaxklLuM82sQ-uNw3O6326E-ooNXc" }

Acme challenges themselves work smooth.

"DNSSEC validation failure"

An existing CAA record is fine of course:
https://dns.google.com/query?name=www.ikenmeyer.com&type=CAA&dnssec=true

This problem occurs both with OpenSSL and ring.

It could be related to a different problem I observed while setting a low "Negative TTL" value:
http://dnsviz.net/d/ikenmeyer.eu/dnssec/
RRSIG ikenmeyer.eu/SOA alg 14, id 8974: The TTL of the RRSIG RR (600) does not match the TTL of the RRset it covers (86400).
Lowering SOA TTL (86400) to the value of Negative TTL (600) doesn't seem to help either.

Debian Testing:
Binary compiled with:
cargo install trust-dns-server --git https://github.com/bluejekyll/trust-dns --rev 8a3130976acb9e9219da7e516c4f850dc91c75e4 --features "dnssec-ring dnssec-openssl" --force

Keys generated with:
openssl ecparam -out keys/p384.pem -name secp384r1 -genkey
kt generate p384 --out keys/ikenmeyer.eu.pk8

Journals have been deleted before starting the server. Start command is basically:
/home/trustdns/named --config=/home/trustdns/config.toml --zonedir=/home/trustdns/zones/

/home/trustdns/config.toml

listen_addrs_ipv4 = ["217.197.83.185"]
listen_addrs_ipv6 = ["::1", "2001:67c:1400:2190::1", "2001:67c:1400:2190::2"]
listen_port = 53

# [...]

# openssl, only today and for comparison
[[zones]]
zone = "ikenmeyer.com"
zone_type = "Master"
file = "ikenmeyer.com"
enable_dnssec = true
stores = { type = "sqlite", zone_file_path = "ikenmeyer.com", journal_file_path = "ikenmeyer.com.jrnl", allow_update = true }
keys = [{key_path="keys/p384.pem", algorithm="ECDSAP384SHA384", is_zone_signing_key=true}, {key_path="auth.pk8", algorithm="ED25519", is_zone_update_auth=true}]

# ring
[[zones]]
zone = "ikenmeyer.eu"
zone_type = "Master"
file = "ikenmeyer.eu"
enable_dnssec = true
stores = { type = "sqlite", zone_file_path = "ikenmeyer.eu", journal_file_path = "ikenmeyer.eu.jrnl", allow_update = true }
keys = [{key_path="keys/ikenmeyer.eu.pk8", algorithm="ECDSAP384SHA384", is_zone_signing_key=true}, {key_path="auth.pk8", algorithm="ED25519", is_zone_update_auth=true}]

/home/trustdns/zones/ikenmeyer.com

@ 86400 IN SOA ns1.darkspirit.eu. hostmaster.terrax.net. (
 201902272       ; Serial
 3600            ; Refresh - we don't have slaves
 600             ; Retry
 86400           ; Expire
 600)            ; Negative TTL - rfc2308
@ 600 IN NS ns1.darkspirit.eu.
@ 600 IN NS ns2.darkspirit.eu.
@ 600 IN MX 0 .
@ 600 IN TXT "v=spf1 mx -all"
@ 600 IN CAA 0 issue "letsencrypt.org; validationmethods=dns-01"
@ 600 IN CAA 0 iodef "mailto:caa@terrax.net"
www 600 IN CAA 0 issue "letsencrypt.org; validationmethods=dns-01"
www2 60 IN AAAA 2001:67c:1400:2190::1
_dmarc 600 IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; rua=mailto:postmaster@terrax.net; ruf=mailto:postmaster@terrax.net; rf=afrf; pct=100; ri=86400"
terrax._domainkey 600 IN CNAME terrax._domainkey.terrax.net.

/home/trustdns/zones/ikenmeyer.eu

@ 86400 IN SOA ns1.darkspirit.eu. hostmaster.terrax.net. (
 201902171       ; Serial
 3600            ; Refresh - we don't have slaves
 600             ; Retry
 86400           ; Expire
 600)            ; Negative TTL - rfc2308
@ 600 IN NS ns1.darkspirit.eu.
@ 600 IN NS ns2.darkspirit.eu.
@ 600 IN MX 5 mx.h.terrax.net.
@ 600 IN TXT "v=spf1 mx -all"
@ 600 IN CAA 0 issue "letsencrypt.org; validationmethods=dns-01"
@ 600 IN CAA 0 iodef "mailto:caa@terrax.net"
_xmpp-client._tcp 60 IN SRV 5 0 5222 xmpp.ikenmeyer.eu.
_xmpp-server._tcp 60 IN SRV 5 0 5269 xmpp.ikenmeyer.eu.
xmpp 60 IN AAAA 2a01:4f8:1c1c:92b1::1
xmpp 60 IN A 116.203.51.149
xmpp 60 IN MX 0 .
_5222._tcp 60 IN TLSA 3 1 2 4727dbd37773096819b1c0f0406714f42cdcadb958862ed4f862e90cb777e231a593a6c632f7c45f5ad4c7ca66e2d3c0b78b97490e0d04006555e25522e3d4c9
_5269._tcp 60 IN TLSA 3 1 2 4727dbd37773096819b1c0f0406714f42cdcadb958862ed4f862e90cb777e231a593a6c632f7c45f5ad4c7ca66e2d3c0b78b97490e0d04006555e25522e3d4c9
_dmarc 600 IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; rua=mailto:postmaster@ikenmeyer.eu; ruf=mailto:postmaster@ikenmeyer.eu; rf=afrf; pct=100; ri=86400"
terrax._domainkey 600 IN CNAME terrax._domainkey.terrax.net.
@Darkspirit
Copy link
Contributor Author

Oh, I should mention darkspirit.eu doesn't use sqlite and is also affected:
https://dns.google.com/query?name=doesntexist.darkspirit.eu&type=CAA&dnssec=true

[[zones]]
zone = "darkspirit.eu"
zone_type = "Master"
file = "darkspirit.eu"
enable_dnssec = true
keys = [{ key_path = "keys/darkspirit.eu.pk8", algorithm = "ECDSAP384SHA384", is_zone_signing_key = true }]
@ 86400 IN SOA ns1.darkspirit.eu. hostmaster.terrax.net. (
 201902171       ; Serial
 3600            ; Refresh
 600             ; Retry
 86400           ; Expire
 600)            ; Negative Cache TTL
@ 600 IN NS ns1.darkspirit.eu.
@ 600 IN NS ns2.darkspirit.eu.
@ 600 IN MX 0 .
@ 600 IN TXT "v=spf1 mx -all"
@ 600 IN CAA 0 issue "letsencrypt.org; validationmethods=dns-01"
@ 600 IN CAA 128 iodef "mailto:caa@terrax.net"
ns1 600 IN AAAA 2001:67c:1400:2190::1
ns1 600 IN A 217.197.83.185
ns1 600 IN MX 0 .
ns2 600 IN AAAA 2001:67c:1400:2190::2
ns2 600 IN A 217.197.83.185
ns2 600 IN MX 0 .
_dmarc 600 IN TXT "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; rua=mailto:postmaster@terrax.net; ruf=mailto:postmaster@terrax.net; rf=afrf; pct=100; ri=86400"
terrax._domainkey 600 IN CNAME terrax._domainkey.terrax.net.

@bluejekyll
Copy link
Member

Am I understanding correctly that NSEC is not being returned on the response for www2 and CAA? Or is it that the RRSIG being returned for the NSEC is incorrect?

@Darkspirit
Copy link
Contributor Author

Darkspirit commented Feb 27, 2019

I try to get the best out of my incompetence and provide a direct comparison to PowerDNS:

Inexisting subdomain within existing zone:
Trust-DNS: http://dnsviz.net/d/www2.ikenmeyer.eu/dnssec/ [Google: AD=false + validation failure]
PowerDNS: http://dnsviz.net/d/asdf.terrax.net/dnssec/ [Google: AD=true + fine]

Existing subdomain (AAAA) with inexisting record type CAA:
Trust-DNS: [Google: AD=false + validation failure]
PowerDNS: [Google: AD=true + fine]

@Darkspirit
Copy link
Contributor Author

@Darkspirit Darkspirit changed the title DNSSEC signature problem for inexisting CAA record DNSSEC signature problem for non-existent CAA record Feb 27, 2019
@bluejekyll
Copy link
Member

Ok, we'll need some logs from the server. We're getting a SERVFAIL in the response

$> dig +dnssec +tcp  www2.ikenmeyer.eu CAA

; <<>> DiG 9.10.6 <<>> +dnssec +tcp www2.ikenmeyer.eu CAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 9600
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; QUESTION SECTION:
;www2.ikenmeyer.eu.		IN	CAA

;; Query time: 947 msec
;; SERVER: 2001:558:feed::1#53(2001:558:feed::1)
;; WHEN: Thu Feb 28 06:04:28 PST 2019
;; MSG SIZE  rcvd: 46

Could you enable debug logs, send the startup section and then the request section for the above dig request?

@Darkspirit
Copy link
Contributor Author

Server:
rm zones/*jrnl
RUST_LOG=debug /home/trustdns/named --config=/home/trustdns/config.toml --zonedir=/home/trustdns/zones/ --debug > debug.log

Laptop with Debian Testing (having a local unbound through dnssec-trigger):

$ dig +dnssec +tcp  www2.ikenmeyer.eu CAA

; <<>> DiG 9.11.5-P1-2-Debian <<>> +dnssec +tcp www2.ikenmeyer.eu CAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 12119
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;www2.ikenmeyer.eu.             IN      CAA

;; Query time: 218 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Do Feb 28 16:07:15 CET 2019
;; MSG SIZE  rcvd: 46

The single CAA request at end of debug.log was made by this command and directly to @ns1.darkspirit.eu:

$ dig +dnssec +tcp www2.ikenmeyer.eu CAA @ns1.darkspirit.eu

; <<>> DiG 9.11.5-P1-2-Debian <<>> +dnssec +tcp www2.ikenmeyer.eu CAA @ns1.darkspirit.eu
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3770
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; OPT=5: 08 0d 0e 0f ("....")
; OPT=6: 08 0d 0e 0f ("....")
;; QUESTION SECTION:
;www2.ikenmeyer.eu.             IN      CAA

;; AUTHORITY SECTION:
ikenmeyer.eu.           600     IN      NSEC    _dmarc.ikenmeyer.eu. NS SOA MX TXT KEY DNSKEY CAA
ikenmeyer.eu.           600     IN      RRSIG   NSEC 14 2 600 20200227150708 20190228150708 8974 ikenmeyer.eu. 22kypFRT9prJcsqpFveb//WrAf173ICy1MUPkZZQ88EmpUuHQem5bFQe gmGlPVnZAy+6s4h5qdDlQOlJYNZ1NGNyugdOrgnDyJ73n29nGnhiWgVT v2AVKYywUMzMGJwO
ikenmeyer.eu.           86400   IN      SOA     ns1.darkspirit.eu. hostmaster.terrax.net. 201902172 3600 600 86400 600
ikenmeyer.eu.           600     IN      RRSIG   SOA 14 2 86400 20200227150708 20190228150708 8974 ikenmeyer.eu. 9T2e29wF5AYyvDG/i/mmedhuNYyKx3lXAonSPb0wYckvANE1KbmLHHnW qAAxVR3XwdrLB6AIpyMiJpNSETj7hW5ZFt/hCMuYdsG2836QpXGIkZ7W byCPSi2RHDobVCCt

;; Query time: 48 msec
;; SERVER: 2001:67c:1400:2190::1#53(2001:67c:1400:2190::1)
;; WHEN: Do Feb 28 16:07:22 CET 2019
;; MSG SIZE  rcvd: 447

@bluejekyll
Copy link
Member

ok, thanks. I thought we were seeing a different issue, but it looks like the SERVFAIL was from an intermediate resolver, rather than the trust-dns server. here's what I think is going on:

https://github.com/bluejekyll/trust-dns/blob/master/crates/server/src/authority/catalog.rs#L416-L435

That section adds the NSEC records to the nameserver (authority) section of the request in all cases. But in this case because www2 has a AAAA record at that name, we're not getting an NXDOMAIN, but instead an empty NOERROR response. We could go back and review the RFC, but my guess is that this logic is wrong. And that in the empty NOERROR case we need to add the NSEC records to the answer section instead of the nameserver section of the response.

@bluejekyll
Copy link
Member

@Darkspirit want to try out #697 and see if it resolves this issue?

@Darkspirit
Copy link
Contributor Author

"Suspicious or confusing response received."

@bluejekyll
Copy link
Member

Hmm. Looks like DNSSEC flag isn’t being set. I can’t post a fix right now, will as soon as I can.

@bluejekyll
Copy link
Member

@Darkspirit I haven't merge #697 into master yet, are you using the fix-nsec-noerror branch for these tests? I just ran dig +dnssec +tcp www2.ikenmeyer.eu CAA @ns1.darkspirit.eu and it looks like the answer section is still empty.

@Darkspirit
Copy link
Contributor Author

I reverted to master after your reply, as fix-nsec-error looked a bit scarier to me. My workaround now is just setting a CAA record for each sub domain.

cargo install trust-dns-server --git https://github.com/bluejekyll/trust-dns --branch fix-nsec-noerror --features dnssec-ring -f is now in use again.

@bluejekyll
Copy link
Member

Ok, thanks. I need to go back and double check the RFCs for NSEC.

@bluejekyll
Copy link
Member

So The NSECs are supposed to be in the Authority/Nameserver section of the response. So that looks like it was correct originally. It looks like the authoritative flag wasn't being set in a NODATA/NXDOMAIN response. I've made sure that's always set now, it that same branch. I don't know if that's the only patch, needed, but I didn't see anything else that seemed wrong.

I need to double check if the authoritative flag should be false in the NXDOMAIN case, which it might be, so this might still be wrong.

@Darkspirit
Copy link
Contributor Author

Darkspirit commented Mar 2, 2019

cargo install trust-dns-server --git https://github.com/bluejekyll/trust-dns --branch fix-nsec-noerror --features dnssec-ring -f

Recompiled and live.
aa flag is now present. Errors are still there:

Existing subdomain (AAAA) with inexistent record type (CAA)
Trust-DNS:
dig +nocmd +dnssec +tcp www2.ikenmeyer.com CAA @ns1.darkspirit.eu
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48395
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
DNSSEC validation failure. https://dns.google.com/query?name=www2.ikenmeyer.com&type=CAA&dnssec=true
http://dnsviz.net/d/www2.ikenmeyer.com/dnssec/ (doesn't test CAA)

PowerDNS for comparison:
dig +nocmd +dnssec +tcp www.terrax.net CAA @ns1.terrax.net
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9513
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available
https://dns.google.com/query?name=www.terrax.net&type=CAA&dnssec=true
http://dnsviz.net/d/www.terrax.net/dnssec/ (doesn't test CAA)


Inexistent subdomain
Trust-DNS:
$ dig +nocmd +dnssec +tcp www2.ikenmeyer.eu CAA @ns1.darkspirit.eu
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 501
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
DNSSEC validation failure. https://dns.google.com/query?name=www2.ikenmeyer.eu&type=CAA&dnssec=true
http://dnsviz.net/d/www2.ikenmeyer.eu/dnssec/

https://dnssec-analyzer.verisignlabs.com/www2.ikenmeyer.eu

No NSEC record could prove that no records of type A for www2.ikenmeyer.eu exist

PowerDNS for comparison:
$ dig +nocmd +dnssec +tcp asdf.terrax.net CAA @ns1.terrax.net
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 13425
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1
;; WARNING: recursion requested but not available
https://dns.google.com/query?name=asdf.terrax.net&type=CAA&dnssec=true
http://dnsviz.net/d/asdf.terrax.net/dnssec/

Cloudflare for comparison:
$ dig +nocmd +dnssec +tcp asdf.cloudflare.com CAA @ns3.cloudflare.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25429
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available
http://dnsviz.net/d/asdf.cloudflare.com/dnssec/

@bluejekyll
Copy link
Member

bluejekyll commented Mar 2, 2019

So it looks like we need an additional NSEC record for the result. trust-dns is only responding with a single NSEC record, while it appears we need two. I'm reviewing this: https://tools.ietf.org/html/rfc4035#section-3.1.3 to see what is wrong.

Ok, this is what we've gotten wrong, the wildcard name error response

... then the name server
   MUST include the following NSEC RRs in the Authority section, along
   with their associated RRSIG RRs:

   o  An NSEC RR proving that there is no exact match for <SNAME,
      SCLASS>.

   o  An NSEC RR proving that the zone contains no RRsets that would
      match <SNAME, SCLASS> via wildcard name expansion.

We're not including that second record.

@bluejekyll
Copy link
Member

Ok, new change is up that has the wildcard nsec proof included. I still need to add a test case for this.

@Darkspirit
Copy link
Contributor Author

That fixed Existing subdomain (AAAA) with inexistent record type (CAA). Thanks! :)
https://dns.google.com/query?name=www2.ikenmeyer.com&type=CAA&dnssec=true

Inexistent subdomain is still broken.
https://dns.google.com/query?name=www2.ikenmeyer.eu&type=CAA&dnssec=true

@Darkspirit
Copy link
Contributor Author

Darkspirit commented Mar 3, 2019

Btw, it seems that Cloudflare handles NSEC a bit special: https://blog.cloudflare.com/black-lies/
Could it be interesting to you? Ctrl+F When CloudFlare Lies
I find this quite elegant.

  • Smaller responses
  • Saving database lookups
  • Helps against zone information leaks

Inexistent subdomain
dig +nocmd +dnssec +tcp asdf.cloudflare.com CAA @ns3.cloudflare.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48756
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 65535
;; QUESTION SECTION:
;asdf.cloudflare.com. IN CAA

;; AUTHORITY SECTION:
cloudflare.com. 300 IN SOA ns3.cloudflare.com. dns.cloudflare.com. 2030315145 10000 2400 604800 300
asdf.cloudflare.com. 300 IN NSEC \000.asdf.cloudflare.com. RRSIG NSEC
cloudflare.com. 300 IN RRSIG SOA 13 2 300 20190304111223 20190302091223 34505 cloudflare.com. f1Xu9zI/JBHLKdJaYPf2AzclRxeK4/UvL5UIPbn09MaTRz6KvVMaw1PB U5R330so/Mz95KDe+vLb9aYypikzwQ==
asdf.cloudflare.com. 300 IN RRSIG NSEC 13 3 300 20190304111223 20190302091223 34505 cloudflare.com. UYbjOR5dIWUFbjzV6DWNzAvfai2fRNSuqm7wYNLZAScnLSQL6+Vs6s4h vO01nmSSEUus6Sfnd4Dc33lq6P/SMQ==

;; Query time: 40 msec
;; SERVER: 2400:cb00:2049:1::a29f:21#53(2400:cb00:2049:1::a29f:21)
;; WHEN: So Mär 03 11:12:23 CET 2019
;; MSG SIZE rcvd: 355

Existing subdomain (AAAA/A) with inexistent record type CAA
dig +nocmd +dnssec +tcp www.cloudflare.com CAA @ns3.cloudflare.com
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62831
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 65535
;; QUESTION SECTION:
;www.cloudflare.com. IN CAA

;; AUTHORITY SECTION:
cloudflare.com. 300 IN SOA ns3.cloudflare.com. dns.cloudflare.com. 2030315145 10000 2400 604800 300
www.cloudflare.com. 300 IN NSEC \000.www.cloudflare.com. A HINFO MX TXT AAAA LOC SRV CERT SSHFP RRSIG NSEC TLSA HIP OPENPGPKEY SPF
cloudflare.com. 300 IN RRSIG SOA 13 2 300 20190304132719 20190302112719 34505 cloudflare.com. tiL8RvnpsVz7yTtjJaqUFv8rCckbnzxT5leB4lfe5gTel7zPJugH0m5b FdqY/+7cLwT4ydXBt+SaAw30lV25rQ==
www.cloudflare.com. 300 IN RRSIG NSEC 13 3 300 20190304132719 20190302112719 34505 cloudflare.com. ZaP/GCpG+0JZ4NDRLuPjkAdy+kGHGaYvEohKKWFUczKEHjSMFJ1sQ2ty PV5X8OZITwnpgG5yueINQ8X6EFrFVA==

;; Query time: 37 msec
;; SERVER: 2400:cb00:2049:1::a29f:21#53(2400:cb00:2049:1::a29f:21)
;; WHEN: So Mär 03 13:27:19 CET 2019
;; MSG SIZE rcvd: 360

@bluejekyll
Copy link
Member

It appears that one issue we have is that the NSEC record isn't marking itself as covered. Based on that result, It looks like cloudflare is generating a null record to mark that thee is no subzone under the www record, which might be to attempt to prevent zone walking?

What I see in the initial NXDOMAIN response is similarly interesting, because it appears they're generating an NSEC record on the fly for that query. Both of these are interesting, and would take a bit longer for a patch. I'll need to review what cloudflare is doing here, and see if we can use similar techniques (though generating NSEC on the fly could be a source of DOS attacks).

@bluejekyll
Copy link
Member

Ok, I pushed the fix for the NSEC record not covering itself.

@Darkspirit
Copy link
Contributor Author

Looks unchanged: http://dnsviz.net/d/www2.ikenmeyer.eu/dnssec/

(terrax.net is no longer a PowerDNS example as everything has been switched to Trust-DNS by now. Other PowerDNS example: http://dnsviz.net/d/asdf.powerdns.org/dnssec/)

@bluejekyll
Copy link
Member

paying more attention to my test cases, I appear to have broken something. I'll work to get to the bottom of this.

@bluejekyll
Copy link
Member

bluejekyll commented Mar 5, 2019

Ok, I patched up the construction of the NSEC records, but I'm not sure it will fix the original issue, but it does resolve one that was introduced in this patch. I'm thinking that we might want to look into implementing the same DNSSEC mechanism as cloudflare: https://blog.cloudflare.com/dnssec-done-right/

edit: opened #706 for this

@Darkspirit
Copy link
Contributor Author

Same as before.
Cloudflare: Yeah, removal of RSA signing support and deprecation of ANY queries were likewise good.

@bluejekyll
Copy link
Member

bluejekyll commented Mar 5, 2019

I’m wondering if there’s a bug in the returned NSEC records and their ordering with the _dmarc record in you example zones. I’ll investigate that code a little more.

edit: ok, yes, I think I finally tracked down this issue and have reproducible test case. but I've run out of time to fix it this morning.

@bluejekyll
Copy link
Member

bluejekyll commented Mar 6, 2019

Ok, @Darkspirit, I'm hoping the patch I just pushed resolves all the remaining issues.

@Darkspirit
Copy link
Contributor Author

I have no idea and it's still broken. But PowerDNS and ISC first respond with their SOA.

shrinked ikenmeyer.com zone:

@ 86400 IN SOA ns1.darkspirit.eu. hostmaster.terrax.net. (
 201903062       ; Serial
 3600            ; Refresh
 600             ; Retry
 86400           ; Expire
 600)            ; Negative TTL
@ 600 IN NS ns1.darkspirit.eu.
@ 600 IN NS ns2.darkspirit.eu.
www2 60 IN AAAA 2001:67c:1400:2190::1

http://dnsviz.net/d/asdf.ikenmeyer.com/analyze/
https://dnssec-debugger.verisignlabs.com/asdf.ikenmeyer.com

No NSEC record could prove that no records of type A for asdf.ikenmeyer.com exist

dig +nocmd +dnssec +tcp asdf.ikenmeyer.com A @ns1.darkspirit.eu
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42459
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; OPT=5: 08 0d 0e 0f ("....")
; OPT=6: 08 0d 0e 0f ("....")
;; QUESTION SECTION:
;asdf.ikenmeyer.com. IN A

;; AUTHORITY SECTION:
ikenmeyer.com. 600 IN NSEC www2.ikenmeyer.com. NS SOA NSEC DNSKEY
ikenmeyer.com. 600 IN RRSIG NSEC 14 2 600 20200304190054 20190306190054 62592 ikenmeyer.com. UkOIgkHg3iDsLGZtfyNBBNx5txnc29IgAj/HO4PvUG700aMlUpcgbJgh rnF/az5aFyvd5dgmRRxORkwUWBWhjEaDgVn90GLt2o/NqMggztyopTxo bgDwNACB2fpWDAT6
ikenmeyer.com. 86400 IN SOA ns1.darkspirit.eu. hostmaster.terrax.net. 201903063 3600 600 86400 600
ikenmeyer.com. 600 IN RRSIG SOA 14 2 86400 20200304190054 20190306190054 62592 ikenmeyer.com. sJc8rozJC+1G2WPIhZdLfZh1IIOQwBSJF71DPcfgRT3V3C0yTOoixmDy 5D95FwquQjwk2x0DcIXB2hD9wWhOzHrX5MQVVKrw0g4q5df52jybJLjT HzO0CirgRQqFYoij

;; Query time: 47 msec
;; SERVER: 2001:67c:1400:2190::1#53(2001:67c:1400:2190::1)
;; WHEN: Mi Mär 06 20:05:14 CET 2019
;; MSG SIZE rcvd: 447


dig +nocmd +dnssec +tcp asdf.isc.org A @ams.sns-pb.isc.org.
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 57473
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;asdf.isc.org. IN A

;; AUTHORITY SECTION:
isc.org. 3600 IN SOA ns-int.isc.org. hostmaster.isc.org. 2019030500 7200 3600 24796800 3600
isc.org. 3600 IN RRSIG SOA 5 2 7200 20190403233441 20190304233441 28347 isc.org. dPtYu/tuVz0w7x3ecqAaCnPRRrTKZ2ule69s3+cA2ps9jk1jyzogEcBd Fr6PRWl/mUGsWP60uYl1q7QgNCoegnMfhsQyx622IQnolquiwFN2yT/o CvHUn68BFKP042XMEU8jAfIvewdCPAzxqqHYkueMkXNMnOM4f8Vuhdie pKM=
isc.org. 3600 IN NSEC _adsp._domainkey.isc.org. A NS SOA MX TXT AAAA NAPTR RRSIG NSEC DNSKEY SPF CAA
isc.org. 3600 IN RRSIG NSEC 5 2 3600 20190403233441 20190304233441 28347 isc.org. wy4mgsRdlRu7KSQM83QZxitjBKAA7JSaWSC+SFK04MEbIAEOhJHg0LTO CrEjP1qbjG5TEXrFgz0JUlbkbrjOBQ/iZUrwBcMPG4uchtF2s6CDkijx hAY1IFlOwJoNQX84lATiv5ZuqIgSk+sYNmWcigMpbSx6vdvJINpR8/1F VMc=
archpalimp.isc.org. 3600 IN NSEC asp-gw.isc.org. A RRSIG NSEC
archpalimp.isc.org. 3600 IN RRSIG NSEC 5 3 3600 20190403233441 20190304233441 28347 isc.org. x6S2oWwS5BLPVeKGsCRJLmtedNakbhkpfLIvnZguOBcR3Us9ounkwjig qycfn8/Jb8MlWnqm8I+u2vHDOcUBZPnJgEBSewWXk3ihLw1EvejbXCsu g4bOL2A+E6zTo1gYwfAy9AutMyTDmFtAf/E210lWTJG5Y5tG22Rs/agq rEk=

;; Query time: 28 msec
;; SERVER: 2001:500:60::30#53(2001:500:60::30)
;; WHEN: Mi Mär 06 20:04:58 CET 2019
;; MSG SIZE rcvd: 699


dig +nocmd +dnssec +tcp asdf.powerdns.org A @xs.powerdns.com.
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 15107
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1680
;; QUESTION SECTION:
;asdf.powerdns.org. IN A

;; AUTHORITY SECTION:
powerdns.org. 3600 IN SOA ns1.ds9a.nl. hostmaster.powerdns.org. 18 10800 3600 604800 3600
powerdns.org. 3600 IN RRSIG SOA 13 2 3600 20190314000000 20190221000000 13432 powerdns.org. cu4p6HBsfCz4L756LkNuzzpF+iS+6jHQv3Q3ANBgSP0GEBznaxQ324DA ezrZspLFFHG7FagNslFhBHrOCvTyjA==
powerdns.org. 3600 IN NSEC doh.powerdns.org. A NS SOA AAAA RRSIG NSEC DNSKEY CAA
powerdns.org. 3600 IN RRSIG NSEC 13 2 3600 20190314000000 20190221000000 13432 powerdns.org. FVTM97g5O3I52FEH/vgytdRhRgn+arjWg8dgkX+TLbaHSnnGKIkDc1Gk UfeSvugPImKToD71CYyHYXdWOr1zqg==

;; Query time: 34 msec
;; SERVER: 2001:888:2000:1d::2#53(2001:888:2000:1d::2)
;; WHEN: Mi Mär 06 20:06:43 CET 2019
;; MSG SIZE rcvd: 362

@Darkspirit
Copy link
Contributor Author

Darkspirit commented Mar 7, 2019

It seems putting the SOA first was not enough to fix the problem. What a beast.

@bluejekyll
Copy link
Member

bluejekyll commented Mar 7, 2019

Wait, is the status code wrong? trust-dns is responding with a NOERROR, the other examples you have there are NXDOMAIN...

edit: yes, see examples here: https://tools.ietf.org/html/rfc4035

I'm not sure how I misread that and was intentionally making that switch... I even had a test validating that. Interesting.

@bluejekyll
Copy link
Member

bluejekyll commented Mar 7, 2019

Just pushed the change, 8th time's the charm?

@Darkspirit
Copy link
Contributor Author

Darkspirit commented Mar 7, 2019

Mostly! :) But dnsviz complains here:

@bluejekyll
Copy link
Member

At least we’re finally making progress!

This appears to be a general issue with NXDOMAIN vs. NOERROR responses. It might take me a bit to figure out how to resolve this one.

@bluejekyll
Copy link
Member

Just pushed a patch, @Darkspirit, that should resolve the most recent issue you found.

@Darkspirit
Copy link
Contributor Author

Thank you, it looks like everything is fixed, I haven't found other bugs so far! :)

@bluejekyll
Copy link
Member

Thank you for verifying and working with me on this!

@bluejekyll
Copy link
Member

bluejekyll commented Mar 8, 2019

This one is still reporting an error: http://dnsviz.net/d/terrax._domainkey.ikenmeyer.eu/XIFnsQ/dnssec/

Edit: oh I’m guessing you haven’t updated that zone yet.

@Darkspirit
Copy link
Contributor Author

Darkspirit commented Mar 8, 2019

That's just a link to the (old) cached result.
It's fine now: http://dnsviz.net/d/terrax._domainkey.ikenmeyer.eu/dnssec/

@bluejekyll
Copy link
Member

Ok, I want to clean up a few things, then I'll merge this in. Thanks, again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants