From e684c7d8c4ff69d4bf9c313386a12aa8783c06be Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Mon, 12 Jun 2023 16:04:54 +0000 Subject: [PATCH] Follow CNAME chain to find correct target To prevent abusive response from some malicious DNS server, ctrld ignores the response if the target does not match question domain. However, that would break CNAME chain, which is allowed the mismatch happens. --- resolver.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/resolver.go b/resolver.go index 3162d62..f61c9bc 100644 --- a/resolver.go +++ b/resolver.go @@ -159,15 +159,27 @@ func lookupIP(domain string, timeout int, withBootstrapDNS bool) (ips []string) timeoutMs = timeout } questionDomain := dns.Fqdn(domain) - ipFromRecord := func(record dns.RR) string { + + // Getting the real target domain name from CNAME if presents. + targetDomain := func(answers []dns.RR) string { + for _, a := range answers { + switch ar := a.(type) { + case *dns.CNAME: + return ar.Target + } + } + return questionDomain + } + // Getting ip address from A or AAAA record. + ipFromRecord := func(record dns.RR, target string) string { switch ar := record.(type) { case *dns.A: - if ar.Hdr.Name != questionDomain { + if ar.Hdr.Name != target { return "" } return ar.A.String() case *dns.AAAA: - if ar.Hdr.Name != questionDomain { + if ar.Hdr.Name != target { return "" } return ar.AAAA.String() @@ -195,8 +207,9 @@ func lookupIP(domain string, timeout int, withBootstrapDNS bool) (ips []string) ProxyLog.Error().Msg("no answer from OS resolver") return } + target := targetDomain(r.Answer) for _, a := range r.Answer { - if ip := ipFromRecord(a); ip != "" { + if ip := ipFromRecord(a, target); ip != "" { ips = append(ips, ip) } }