diff --git a/challenge/dns01/cname.go b/challenge/dns01/cname.go new file mode 100644 index 00000000..619c8476 --- /dev/null +++ b/challenge/dns01/cname.go @@ -0,0 +1,16 @@ +package dns01 + +import "github.com/miekg/dns" + +// Update FQDN with CNAME if any +func updateDomainWithCName(r *dns.Msg, fqdn string) string { + for _, rr := range r.Answer { + if cn, ok := rr.(*dns.CNAME); ok { + if cn.Hdr.Name == fqdn { + return cn.Target + } + } + } + + return fqdn +} diff --git a/challenge/dns01/dns_challenge.go b/challenge/dns01/dns_challenge.go index b780d8f2..68c79589 100644 --- a/challenge/dns01/dns_challenge.go +++ b/challenge/dns01/dns_challenge.go @@ -4,8 +4,11 @@ import ( "crypto/sha256" "encoding/base64" "fmt" + "os" + "strconv" "time" + "github.com/miekg/dns" "github.com/xenolf/lego/acme" "github.com/xenolf/lego/acme/api" "github.com/xenolf/lego/challenge" @@ -172,5 +175,14 @@ func GetRecord(domain, keyAuth string) (fqdn string, value string) { // base64URL encoding without padding value = base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size]) fqdn = fmt.Sprintf("_acme-challenge.%s.", domain) + + if ok, _ := strconv.ParseBool(os.Getenv("LEGO_EXPERIMENTAL_CNAME_SUPPORT")); ok { + r, err := dnsQuery(fqdn, dns.TypeCNAME, recursiveNameservers, true) + // Check if the domain has CNAME then return that + if err == nil && r.Rcode == dns.RcodeSuccess { + fqdn = updateDomainWithCName(r, fqdn) + } + } + return } diff --git a/challenge/dns01/precheck.go b/challenge/dns01/precheck.go index 63b72cef..c3389110 100644 --- a/challenge/dns01/precheck.go +++ b/challenge/dns01/precheck.go @@ -60,15 +60,7 @@ func (p preCheck) checkDNSPropagation(fqdn, value string) (bool, error) { } if r.Rcode == dns.RcodeSuccess { - // If we see a CNAME here then use the alias - for _, rr := range r.Answer { - if cn, ok := rr.(*dns.CNAME); ok { - if cn.Hdr.Name == fqdn { - fqdn = cn.Target - break - } - } - } + fqdn = updateDomainWithCName(r, fqdn) } authoritativeNss, err := lookupNameservers(fqdn)