Skip to content

Commit

Permalink
Fix zone detection for cross-zone cnames (go-acme#449)
Browse files Browse the repository at this point in the history
* Fix zone detection for cross-zone cnames

CNAMEs cannot co-exist with SOA records so responses with
a CNAME should be skipped.

The `cross-zone-example.assets.sh.` is currently hosted by
me (@fd) and will continue to exist for as long as the assets.sh
domain exists. (The assets.sh domain is used as a CDN and is unlikely
to go away.)

See go-acme#330

* Extracted CNAME checking to simplify the FindZoneByFqdn control flow.
  • Loading branch information
fd authored and xenolf committed Nov 15, 2017
1 parent 922235d commit b929aa5
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
17 changes: 17 additions & 0 deletions acme/dns_challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) {

// Check if we got a SOA RR in the answer section
if in.Rcode == dns.RcodeSuccess {

// CNAME records cannot/should not exist at the root of a zone.
// So we skip a domain when a CNAME is found.
if dnsMsgContainsCNAME(in) {
continue
}

for _, ans := range in.Answer {
if soa, ok := ans.(*dns.SOA); ok {
zone := soa.Hdr.Name
Expand All @@ -268,6 +275,16 @@ func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) {
return "", fmt.Errorf("Could not find the start of authority")
}

// dnsMsgContainsCNAME checks for a CNAME answer in msg
func dnsMsgContainsCNAME(msg *dns.Msg) bool {
for _, ans := range msg.Answer {
if _, ok := ans.(*dns.CNAME); ok {
return true
}
}
return false
}

// ClearFqdnCache clears the cache of fqdn to zone mappings. Primarily used in testing.
func ClearFqdnCache() {
fqdnToZone = map[string]string{}
Expand Down
7 changes: 4 additions & 3 deletions acme/dns_challenge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ var findZoneByFqdnTests = []struct {
fqdn string
zone string
}{
{"mail.google.com.", "google.com."}, // domain is a CNAME
{"foo.google.com.", "google.com."}, // domain is a non-existent subdomain
{"example.com.ac.", "ac."}, // domain is a eTLD
{"mail.google.com.", "google.com."}, // domain is a CNAME
{"foo.google.com.", "google.com."}, // domain is a non-existent subdomain
{"example.com.ac.", "ac."}, // domain is a eTLD
{"cross-zone-example.assets.sh.", "assets.sh."}, // domain is a cross-zone CNAME
}

var checkAuthoritativeNssTests = []struct {
Expand Down

0 comments on commit b929aa5

Please sign in to comment.