Positive wildcare replies
Reply to queries when you have a wildcard in the zone. This works for DNS and DNSSEC. Thing missing is NODATA responses for that specific wildcard. Add wildcard_test.go as well.
This commit is contained in:
parent
24394f0d4d
commit
09c94fa443
3 changed files with 86 additions and 12 deletions
|
@ -37,6 +37,7 @@ func (z *Zone) nameErrorProof(rr dns.RR) []dns.RR {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We do this lookup twice, once for wildcard and once for the name proof. TODO(miek): fix
|
||||||
ce := z.ClosestEncloser(rr)
|
ce := z.ClosestEncloser(rr)
|
||||||
wildcard := "*." + ce
|
wildcard := "*." + ce
|
||||||
rr.Header().Name = wildcard
|
rr.Header().Name = wildcard
|
||||||
|
|
|
@ -37,7 +37,7 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR,
|
||||||
elem := z.Tree.Get(rr)
|
elem := z.Tree.Get(rr)
|
||||||
if elem == nil {
|
if elem == nil {
|
||||||
if elem == nil {
|
if elem == nil {
|
||||||
return z.nameError(elem, rr, do)
|
return z.nameError(rr, do)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,9 +55,7 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR,
|
||||||
if do {
|
if do {
|
||||||
sigs := elem.Types(dns.TypeRRSIG)
|
sigs := elem.Types(dns.TypeRRSIG)
|
||||||
sigs = signatureForSubType(sigs, qtype)
|
sigs = signatureForSubType(sigs, qtype)
|
||||||
if len(sigs) > 0 {
|
rrs = append(rrs, sigs...)
|
||||||
rrs = append(rrs, sigs...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rrs, nil, nil, Success
|
return rrs, nil, nil, Success
|
||||||
}
|
}
|
||||||
|
@ -68,7 +66,34 @@ func (z *Zone) noData(elem *tree.Elem, do bool) ([]dns.RR, []dns.RR, []dns.RR, R
|
||||||
return nil, append(soa, nsec...), nil, Success
|
return nil, append(soa, nsec...), nil, Success
|
||||||
}
|
}
|
||||||
|
|
||||||
func (z *Zone) nameError(elem *tree.Elem, rr dns.RR, do bool) ([]dns.RR, []dns.RR, []dns.RR, Result) {
|
func (z *Zone) nameError(rr dns.RR, do bool) ([]dns.RR, []dns.RR, []dns.RR, Result) {
|
||||||
|
// Is there a wildcard?
|
||||||
|
rr1 := dns.Copy(rr)
|
||||||
|
rr1.Header().Name = rr.Header().Name
|
||||||
|
rr1.Header().Rrtype = rr.Header().Rrtype
|
||||||
|
ce := z.ClosestEncloser(rr1)
|
||||||
|
rr1.Header().Name = "*." + ce
|
||||||
|
elem := z.Tree.Get(rr1)
|
||||||
|
|
||||||
|
if elem != nil {
|
||||||
|
ret := elem.Types(rr1.Header().Rrtype) // there can only be one of these (or zero)
|
||||||
|
switch {
|
||||||
|
case ret != nil:
|
||||||
|
if do {
|
||||||
|
sigs := elem.Types(dns.TypeRRSIG)
|
||||||
|
sigs = signatureForSubType(sigs, rr.Header().Rrtype)
|
||||||
|
ret = append(ret, sigs...)
|
||||||
|
}
|
||||||
|
ret = wildcardReplace(rr, ce, ret)
|
||||||
|
return ret, nil, nil, Success
|
||||||
|
case ret == nil:
|
||||||
|
// nodata, nsec from the wildcard - type does not exist
|
||||||
|
// nsec proof that name does not exist
|
||||||
|
// TODO(miek)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// name error
|
||||||
ret := []dns.RR{z.SOA}
|
ret := []dns.RR{z.SOA}
|
||||||
if do {
|
if do {
|
||||||
ret = append(ret, z.SIG...)
|
ret = append(ret, z.SIG...)
|
||||||
|
@ -140,3 +165,26 @@ func signatureForSubType(rrs []dns.RR, subtype uint16) []dns.RR {
|
||||||
}
|
}
|
||||||
return sigs
|
return sigs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wildcardReplace replaces the first wildcard with label.
|
||||||
|
func wildcardReplace(rr dns.RR, ce string, rrs []dns.RR) []dns.RR {
|
||||||
|
// Get how many labels the ce is off from the fullname, this is how much of the
|
||||||
|
// original rr's '*' we must replace.
|
||||||
|
labels := dns.CountLabel(rr.Header().Name) - dns.CountLabel(ce) // can not be 0, TODO(miek): check
|
||||||
|
|
||||||
|
indexes := dns.Split(rr.Header().Name)
|
||||||
|
if labels >= len(indexes) {
|
||||||
|
// TODO(miek): yes then what?
|
||||||
|
// Is the == right here?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
replacement := rr.Header().Name[:indexes[labels]]
|
||||||
|
|
||||||
|
// need to copy here, otherwise we change in zone stuff
|
||||||
|
ret := make([]dns.RR, len(rrs))
|
||||||
|
for i, r := range rrs {
|
||||||
|
ret[i] = dns.Copy(r)
|
||||||
|
ret[i].Header().Name = replacement + r.Header().Name[2:]
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
|
@ -12,15 +12,40 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dnssecWildcardTestCases = []coretest.Case{
|
var wildcardTestCases = []coretest.Case{
|
||||||
{
|
{
|
||||||
Qname: "blaat.dnssex.nl.", Qtype: dns.TypeTXT, Do: true,
|
Qname: "wild.dnssex.nl.", Qtype: dns.TypeTXT,
|
||||||
Answer: []dns.RR{},
|
Answer: []dns.RR{
|
||||||
|
coretest.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Qname: "wild.dnssex.nl.", Qtype: dns.TypeTXT, Do: true,
|
||||||
|
Answer: []dns.RR{
|
||||||
|
coretest.RRSIG("wild.dnssex.nl. 1800 IN RRSIG TXT 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. FUZSTyvZfeuuOpCm"),
|
||||||
|
coretest.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// nodata reponse
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
Qname: "wild.dnssex.nl.", Qtype: dns.TypeSRV,
|
||||||
|
Answer: []dns.RR{
|
||||||
|
coretest.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "wild.dnssex.nl.", Qtype: dns.TypeSRV, Do: true,
|
||||||
|
Answer: []dns.RR{
|
||||||
|
coretest.RRSIG("wild.dnssex.nl. 1800 IN RRSIG TXT 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. FUZSTyvZfeuuOpCm"),
|
||||||
|
coretest.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
func testLookupDNSSECWildcard(t *testing.T) {
|
func TestLookupWildcard(t *testing.T) {
|
||||||
zone, err := Parse(strings.NewReader(dbMiekNL_signed), testzone1, "stdin")
|
zone, err := Parse(strings.NewReader(dbDnssexNl_signed), testzone1, "stdin")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expect no error when reading zone, got %q", err)
|
t.Fatalf("expect no error when reading zone, got %q", err)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +53,7 @@ func testLookupDNSSECWildcard(t *testing.T) {
|
||||||
fm := File{Next: coretest.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{testzone1: zone}, Names: []string{testzone1}}}
|
fm := File{Next: coretest.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{testzone1: zone}, Names: []string{testzone1}}}
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
for _, tc := range dnssecWildcardTestCases {
|
for _, tc := range wildcardTestCases {
|
||||||
m := tc.Msg()
|
m := tc.Msg()
|
||||||
|
|
||||||
rec := middleware.NewResponseRecorder(&middleware.TestResponseWriter{})
|
rec := middleware.NewResponseRecorder(&middleware.TestResponseWriter{})
|
||||||
|
@ -77,7 +102,7 @@ func testLookupDNSSECWildcard(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dbMiekNL_wildcard_signed = `
|
const dbDnssexNl_signed = `
|
||||||
; File written on Tue Mar 29 21:02:24 2016
|
; File written on Tue Mar 29 21:02:24 2016
|
||||||
; dnssec_signzone version 9.10.3-P4-Ubuntu
|
; dnssec_signzone version 9.10.3-P4-Ubuntu
|
||||||
dnssex.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. (
|
dnssex.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. (
|
||||||
|
|
Loading…
Add table
Reference in a new issue