Skip to content

Commit 1d450af

Browse files
maximilizemaximilize0xERR0R
authored
fix(resolver): match custom DNS PTR queries case insensitively (#2191)
reverseAddresses is keyed by the output of dns.ReverseAddr, which is always lower case, but handleReverseDNS looked the question name up verbatim. A PTR query that uses different case (upper case hex nibbles in ip6.arpa, an upper case IN-ADDR.ARPA suffix, or 0x20 encoding) then missed the mapping and fell through to the next resolver. DNS names are case insensitive, and the forward path already normalizes both the keys and the lookup via util.ExtractDomainOnly, so this only brings the reverse path in line. Signed-off-by: maximilize <max@maxmax.ch> Co-authored-by: maximilize <max@maxmax.ch> Co-authored-by: Dimitri Herzog <dimitri.herzog@gmail.com>
1 parent 288ff55 commit 1d450af

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

resolver/custom_dns_resolver.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ func (r *CustomDNSResolver) LookupReverse(ip net.IP) []string {
107107
func (r *CustomDNSResolver) handleReverseDNS(request *model.Request) *model.Response {
108108
question := request.Req.Question[0]
109109
if question.Qtype == dns.TypePTR {
110-
urls, found := r.reverseAddresses[question.Name]
110+
// reverseAddresses is keyed by dns.ReverseAddr output, which is lower case:
111+
// DNS names are case insensitive, so normalize before looking up.
112+
urls, found := r.reverseAddresses[strings.ToLower(question.Name)]
111113
if found {
112114
answers := make([]dns.RR, 0, len(urls))
113115
for _, url := range urls {

resolver/custom_dns_resolver_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,50 @@ var _ = Describe("CustomDNSResolver", func() {
486486
})
487487
})
488488
})
489+
When("Reverse DNS request uses a different case", func() {
490+
It("should resolve the defined domain name", func() {
491+
By("ipv4", func() {
492+
Expect(sut.Resolve(ctx, newRequest("123.143.168.192.IN-ADDR.ARPA.", PTR))).
493+
Should(
494+
SatisfyAll(
495+
WithTransform(ToAnswer, SatisfyAll(
496+
HaveLen(2),
497+
ContainElements(
498+
BeDNSRecord("123.143.168.192.IN-ADDR.ARPA.", PTR, "custom.domain."),
499+
BeDNSRecord("123.143.168.192.IN-ADDR.ARPA.", PTR, "multiple.ips.")),
500+
)),
501+
HaveResponseType(ResponseTypeCUSTOMDNS),
502+
HaveReason("CUSTOM DNS"),
503+
HaveReturnCode(dns.RcodeSuccess),
504+
))
505+
506+
// will not delegate to next resolver
507+
m.AssertNotCalled(GinkgoT(), "Resolve", mock.Anything)
508+
})
509+
510+
By("ipv6", func() {
511+
Expect(sut.Resolve(ctx, newRequest("4.3.3.7.0.7.3.0.E.2.A.8.0.0.0.0.0.0.0.0.3.A.5.8.8.B.D.0.1.0.0.2.IP6.ARPA.",
512+
PTR))).
513+
Should(
514+
SatisfyAll(
515+
WithTransform(ToAnswer, SatisfyAll(
516+
HaveLen(2),
517+
ContainElements(
518+
BeDNSRecord("4.3.3.7.0.7.3.0.E.2.A.8.0.0.0.0.0.0.0.0.3.A.5.8.8.B.D.0.1.0.0.2.IP6.ARPA.",
519+
PTR, "ip6.domain."),
520+
BeDNSRecord("4.3.3.7.0.7.3.0.E.2.A.8.0.0.0.0.0.0.0.0.3.A.5.8.8.B.D.0.1.0.0.2.IP6.ARPA.",
521+
PTR, "multiple.ips.")),
522+
)),
523+
HaveResponseType(ResponseTypeCUSTOMDNS),
524+
HaveReason("CUSTOM DNS"),
525+
HaveReturnCode(dns.RcodeSuccess),
526+
))
527+
528+
// will not delegate to next resolver
529+
m.AssertNotCalled(GinkgoT(), "Resolve", mock.Anything)
530+
})
531+
})
532+
})
489533
When("Domain mapping is defined", func() {
490534
It("subdomain must also match", func() {
491535
Expect(sut.Resolve(ctx, newRequest("ABC.CUSTOM.DOMAIN.", A))).

0 commit comments

Comments
 (0)