Fixing SOA record to use alt domain when alt domain in use (#10431)

This commit is contained in:
Joshua Montgomery 2021-10-05 07:47:27 -07:00 committed by GitHub
parent 6b0b6a7445
commit 5446009299
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 15 deletions

View File

@ -1,5 +1,9 @@
## UNRELEASED ## UNRELEASED
BUG FIXES:
* Fixing SOA record to return proper domain when alt domain in use. [[GH-10431]](https://github.com/hashicorp/consul/pull/10431)
## 1.11.0-alpha (September 16, 2021) ## 1.11.0-alpha (September 16, 2021)
SECURITY: SECURITY:

View File

@ -373,7 +373,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
// Only add the SOA if requested // Only add the SOA if requested
if req.Question[0].Qtype == dns.TypeSOA { if req.Question[0].Qtype == dns.TypeSOA {
d.addSOA(cfg, m) d.addSOA(cfg, m, q.Name)
} }
datacenter := d.agent.config.Datacenter datacenter := d.agent.config.Datacenter
@ -486,7 +486,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) {
switch req.Question[0].Qtype { switch req.Question[0].Qtype {
case dns.TypeSOA: case dns.TypeSOA:
ns, glue := d.nameservers(cfg, maxRecursionLevelDefault) ns, glue := d.nameservers(cfg, maxRecursionLevelDefault)
m.Answer = append(m.Answer, d.soa(cfg)) m.Answer = append(m.Answer, d.soa(cfg, q.Name))
m.Ns = append(m.Ns, ns...) m.Ns = append(m.Ns, ns...)
m.Extra = append(m.Extra, glue...) m.Extra = append(m.Extra, glue...)
m.SetRcode(req, dns.RcodeSuccess) m.SetRcode(req, dns.RcodeSuccess)
@ -504,7 +504,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) {
err = d.dispatch(resp.RemoteAddr(), req, m, maxRecursionLevelDefault) err = d.dispatch(resp.RemoteAddr(), req, m, maxRecursionLevelDefault)
rCode := rCodeFromError(err) rCode := rCodeFromError(err)
if rCode == dns.RcodeNameError || errors.Is(err, errNoData) { if rCode == dns.RcodeNameError || errors.Is(err, errNoData) {
d.addSOA(cfg, m) d.addSOA(cfg, m, q.Name)
} }
m.SetRcode(req, rCode) m.SetRcode(req, rCode)
} }
@ -518,18 +518,23 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) {
} }
} }
func (d *DNSServer) soa(cfg *dnsConfig) *dns.SOA { func (d *DNSServer) soa(cfg *dnsConfig, questionName string) *dns.SOA {
domain := d.domain
if d.altDomain != "" && strings.HasSuffix(questionName, "."+d.altDomain) {
domain = d.altDomain
}
return &dns.SOA{ return &dns.SOA{
Hdr: dns.RR_Header{ Hdr: dns.RR_Header{
Name: d.domain, Name: domain,
Rrtype: dns.TypeSOA, Rrtype: dns.TypeSOA,
Class: dns.ClassINET, Class: dns.ClassINET,
// Has to be consistent with MinTTL to avoid invalidation // Has to be consistent with MinTTL to avoid invalidation
Ttl: cfg.SOAConfig.Minttl, Ttl: cfg.SOAConfig.Minttl,
}, },
Ns: "ns." + d.domain, Ns: "ns." + domain,
Serial: uint32(time.Now().Unix()), Serial: uint32(time.Now().Unix()),
Mbox: "hostmaster." + d.domain, Mbox: "hostmaster." + domain,
Refresh: cfg.SOAConfig.Refresh, Refresh: cfg.SOAConfig.Refresh,
Retry: cfg.SOAConfig.Retry, Retry: cfg.SOAConfig.Retry,
Expire: cfg.SOAConfig.Expire, Expire: cfg.SOAConfig.Expire,
@ -538,8 +543,8 @@ func (d *DNSServer) soa(cfg *dnsConfig) *dns.SOA {
} }
// addSOA is used to add an SOA record to a message for the given domain // addSOA is used to add an SOA record to a message for the given domain
func (d *DNSServer) addSOA(cfg *dnsConfig, msg *dns.Msg) { func (d *DNSServer) addSOA(cfg *dnsConfig, msg *dns.Msg, questionName string) {
msg.Ns = append(msg.Ns, d.soa(cfg)) msg.Ns = append(msg.Ns, d.soa(cfg, questionName))
} }
// nameservers returns the names and ip addresses of up to three random servers // nameservers returns the names and ip addresses of up to three random servers
@ -600,6 +605,12 @@ func (d *DNSServer) nameservers(cfg *dnsConfig, maxRecursionLevel int) (ns []dns
return return
} }
func (d *DNSServer) invalidQuery(req, resp *dns.Msg, cfg *dnsConfig, qName string) {
d.logger.Warn("QName invalid", "qname", qName)
d.addSOA(cfg, resp, qName)
resp.SetRcode(req, dns.RcodeNameError)
}
func (d *DNSServer) parseDatacenter(labels []string, datacenter *string) bool { func (d *DNSServer) parseDatacenter(labels []string, datacenter *string) bool {
switch len(labels) { switch len(labels) {
case 1: case 1:

View File

@ -6528,14 +6528,17 @@ func TestDNS_AltDomains_SOA(t *testing.T) {
defer a.Shutdown() defer a.Shutdown()
testrpc.WaitForLeader(t, a.RPC, "dc1") testrpc.WaitForLeader(t, a.RPC, "dc1")
questions := []string{ questions := []struct {
"test-node.node.consul.", ask string
"test-node.node.test-domain.", want_domain string
}{
{"test-node.node.consul.", "consul."},
{"test-node.node.test-domain.", "test-domain."},
} }
for _, question := range questions { for _, question := range questions {
m := new(dns.Msg) m := new(dns.Msg)
m.SetQuestion(question, dns.TypeSOA) m.SetQuestion(question.ask, dns.TypeSOA)
c := new(dns.Client) c := new(dns.Client)
in, _, err := c.Exchange(m, a.DNSAddr()) in, _, err := c.Exchange(m, a.DNSAddr())
@ -6552,10 +6555,10 @@ func TestDNS_AltDomains_SOA(t *testing.T) {
t.Fatalf("Bad: %#v", in.Answer[0]) t.Fatalf("Bad: %#v", in.Answer[0])
} }
if got, want := soaRec.Hdr.Name, "consul."; got != want { if got, want := soaRec.Hdr.Name, question.want_domain; got != want {
t.Fatalf("SOA name invalid, got %q want %q", got, want) t.Fatalf("SOA name invalid, got %q want %q", got, want)
} }
if got, want := soaRec.Ns, "ns.consul."; got != want { if got, want := soaRec.Ns, ("ns." + question.want_domain); got != want {
t.Fatalf("SOA ns invalid, got %q want %q", got, want) t.Fatalf("SOA ns invalid, got %q want %q", got, want)
} }
} }