mirror of https://github.com/status-im/consul.git
Queries to the DNS server can contain an optional datacenter name in the query name. You can query for 'foo.service.consul' or 'foo.service.dc.consul' to get a response for either the default or a specific datacenter. Datacenter names cannot have dots, therefore the datacenter name can refer to only one element in the DNS query name. The DNS server allowed extra labels between the optional datacenter name and the domain and returned a valid response instead of returning NXDOMAIN. For example, if the domain is set to '.consul' then 'foo.service.dc1.extra.consul' should return NXDOMAIN because of 'extra' being between the datacenter name 'dc1' and the domain '.consul'. Fixes #3200
This commit is contained in:
parent
c7a65b4587
commit
350932161d
19
agent/dns.go
19
agent/dns.go
|
@ -369,6 +369,9 @@ func (d *DNSServer) dispatch(network string, req, resp *dns.Msg) {
|
||||||
// Split into the label parts
|
// Split into the label parts
|
||||||
labels := dns.SplitDomainName(qName)
|
labels := dns.SplitDomainName(qName)
|
||||||
|
|
||||||
|
// Provide a flag for remembering whether the datacenter name was parsed already.
|
||||||
|
var dcParsed bool
|
||||||
|
|
||||||
// The last label is either "node", "service", "query", "_<protocol>", or a datacenter name
|
// The last label is either "node", "service", "query", "_<protocol>", or a datacenter name
|
||||||
PARSE:
|
PARSE:
|
||||||
n := len(labels)
|
n := len(labels)
|
||||||
|
@ -475,6 +478,22 @@ PARSE:
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
// https://github.com/hashicorp/consul/issues/3200
|
||||||
|
//
|
||||||
|
// Since datacenter names cannot contain dots we can only allow one
|
||||||
|
// label between the query type and the domain to be the datacenter name.
|
||||||
|
// Since the datacenter name is optional and the parser strips off labels at the end until it finds a suitable
|
||||||
|
// query type label we return NXDOMAIN when we encounter another label
|
||||||
|
// which could be the datacenter name.
|
||||||
|
//
|
||||||
|
// If '.consul' is the domain then
|
||||||
|
// * foo.service.dc.consul is OK
|
||||||
|
// * foo.service.dc.stuff.consul is not OK
|
||||||
|
if dcParsed {
|
||||||
|
goto INVALID
|
||||||
|
}
|
||||||
|
dcParsed = true
|
||||||
|
|
||||||
// Store the DC, and re-parse
|
// Store the DC, and re-parse
|
||||||
datacenter = labels[n-1]
|
datacenter = labels[n-1]
|
||||||
labels = labels[:n-1]
|
labels = labels[:n-1]
|
||||||
|
|
|
@ -4154,6 +4154,9 @@ func TestDNS_InvalidQueries(t *testing.T) {
|
||||||
"node.consul.",
|
"node.consul.",
|
||||||
"service.consul.",
|
"service.consul.",
|
||||||
"query.consul.",
|
"query.consul.",
|
||||||
|
"foo.node.dc1.extra.consul.",
|
||||||
|
"foo.service.dc1.extra.consul.",
|
||||||
|
"foo.query.dc1.extra.consul.",
|
||||||
}
|
}
|
||||||
for _, question := range questions {
|
for _, question := range questions {
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
|
|
Loading…
Reference in New Issue