aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--middleware/file/closest.go42
-rw-r--r--middleware/file/dnssec_test.go27
-rw-r--r--middleware/file/lookup.go3
3 files changed, 70 insertions, 2 deletions
diff --git a/middleware/file/closest.go b/middleware/file/closest.go
index 8f9d9a8ba..0c5fd722d 100644
--- a/middleware/file/closest.go
+++ b/middleware/file/closest.go
@@ -20,3 +20,45 @@ func (z *Zone) ClosestEncloser(rr dns.RR) string {
return z.SOA.Header().Name
}
+
+// nameErrorProof finds the closest encloser and return an NSEC that proofs
+// the wildcard does not exist and an NSEC that proofs the name does no exist.
+func (z *Zone) nameErrorProof(rr dns.RR) []dns.RR {
+ elem := z.Tree.Prev(rr)
+ if elem == nil {
+ return nil
+ }
+ nsec := z.lookupNSEC(elem, true)
+ nsecIndex := 0
+ for i := 0; i < len(nsec); i++ {
+ if nsec[i].Header().Rrtype == dns.TypeNSEC {
+ nsecIndex = i
+ break
+ }
+ }
+
+ ce := z.ClosestEncloser(rr)
+ wildcard := "*." + ce
+ rr.Header().Name = wildcard
+ elem = z.Tree.Prev(rr)
+ if elem == nil {
+ // Root?
+ return nil
+ }
+ nsec1 := z.lookupNSEC(elem, true)
+ nsec1Index := 0
+ for i := 0; i < len(nsec1); i++ {
+ if nsec1[i].Header().Rrtype == dns.TypeNSEC {
+ nsec1Index = i
+ break
+ }
+ }
+
+ // Check for duplicate NSEC.
+ if nsec[nsecIndex].Header().Name == nsec1[nsec1Index].Header().Name &&
+ nsec[nsecIndex].(*dns.NSEC).NextDomain == nsec1[nsec1Index].(*dns.NSEC).NextDomain {
+ return nsec
+ }
+
+ return append(nsec, nsec1...)
+}
diff --git a/middleware/file/dnssec_test.go b/middleware/file/dnssec_test.go
index ed8b6a607..dc19235da 100644
--- a/middleware/file/dnssec_test.go
+++ b/middleware/file/dnssec_test.go
@@ -64,6 +64,33 @@ var dnssecTestCases = []coretest.Case{
Qname: "b.miek.nl.", Qtype: dns.TypeA, Do: true,
Rcode: dns.RcodeNameError,
Ns: []dns.RR{
+ coretest.NSEC("archive.miek.nl. 14400 IN NSEC go.dns.miek.nl. CNAME RRSIG NSEC"),
+ coretest.RRSIG("archive.miek.nl. 14400 IN RRSIG NSEC 8 3 14400 20160426031301 20160327031301 12051 miek.nl. jEpx8lcp4do5fWXg="),
+ coretest.NSEC("miek.nl. 14400 IN NSEC a.miek.nl. A NS SOA MX AAAA RRSIG NSEC DNSKEY"),
+ coretest.RRSIG("miek.nl. 14400 IN RRSIG NSEC 8 2 14400 20160426031301 20160327031301 12051 miek.nl. mFfc3r/9PSC1H6oSpdC"),
+ coretest.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
+ coretest.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
+ },
+ },
+ {
+ Qname: "b.blaat.miek.nl.", Qtype: dns.TypeA, Do: true,
+ Rcode: dns.RcodeNameError,
+ Ns: []dns.RR{
+ coretest.NSEC("archive.miek.nl. 14400 IN NSEC go.dns.miek.nl. CNAME RRSIG NSEC"),
+ coretest.RRSIG("archive.miek.nl. 14400 IN RRSIG NSEC 8 3 14400 20160426031301 20160327031301 12051 miek.nl. jEpx8lcp4do5fWXg="),
+ coretest.NSEC("miek.nl. 14400 IN NSEC a.miek.nl. A NS SOA MX AAAA RRSIG NSEC DNSKEY"),
+ coretest.RRSIG("miek.nl. 14400 IN RRSIG NSEC 8 2 14400 20160426031301 20160327031301 12051 miek.nl. mFfc3r/9PSC1H6oSpdC"),
+ coretest.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
+ coretest.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
+ },
+ },
+ {
+ Qname: "b.a.miek.nl.", Qtype: dns.TypeA, Do: true,
+ Rcode: dns.RcodeNameError,
+ Ns: []dns.RR{
+ // dedupped NSEC, because 1 nsec tells all
+ coretest.NSEC("a.miek.nl. 14400 IN NSEC archive.miek.nl. A AAAA RRSIG NSEC"),
+ coretest.RRSIG("a.miek.nl. 14400 IN RRSIG NSEC 8 3 14400 20160426031301 20160327031301 12051 miek.nl. GqnF6cut/RRGPQ1QGQE1ipmSHEao="),
coretest.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
coretest.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go
index 10f308cf1..7c4d92abe 100644
--- a/middleware/file/lookup.go
+++ b/middleware/file/lookup.go
@@ -72,8 +72,7 @@ func (z *Zone) nameError(elem *tree.Elem, rr dns.RR, do bool) ([]dns.RR, []dns.R
ret := []dns.RR{z.SOA}
if do {
ret = append(ret, z.SIG...)
- // Now we need two NSEC, one to deny the wildcard and one to deny the name.
- // Needs closest encloser!!
+ ret = append(ret, z.nameErrorProof(rr)...)
}
return nil, ret, nil, NameError
}