forked from TrueCloudLab/lego
Resolve CNAME when creating dns-01 challenge (#791)
* Resolve CNAME when creating dns-01 challenge It may be desirable to host the dns-01 challenge in a zone other than the one where the challenge is presented. For example, when validating a.example.com, the challenge may need to live on example.org. This change resolves CNAMEs encountered when determining the FQDN of the challenge, and replaces them with the alias. This PR is based on the original work in #584. Co-authored-by: Gurvinder Singh <gurvinder.singh@uninett.no> * review: feature-flip. * review: restore acmedns test.
This commit is contained in:
parent
9409b92ed5
commit
348b6f3721
3 changed files with 29 additions and 9 deletions
16
challenge/dns01/cname.go
Normal file
16
challenge/dns01/cname.go
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -4,8 +4,11 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
"github.com/xenolf/lego/acme"
|
"github.com/xenolf/lego/acme"
|
||||||
"github.com/xenolf/lego/acme/api"
|
"github.com/xenolf/lego/acme/api"
|
||||||
"github.com/xenolf/lego/challenge"
|
"github.com/xenolf/lego/challenge"
|
||||||
|
@ -172,5 +175,14 @@ func GetRecord(domain, keyAuth string) (fqdn string, value string) {
|
||||||
// base64URL encoding without padding
|
// base64URL encoding without padding
|
||||||
value = base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])
|
value = base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])
|
||||||
fqdn = fmt.Sprintf("_acme-challenge.%s.", domain)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,15 +60,7 @@ func (p preCheck) checkDNSPropagation(fqdn, value string) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Rcode == dns.RcodeSuccess {
|
if r.Rcode == dns.RcodeSuccess {
|
||||||
// If we see a CNAME here then use the alias
|
fqdn = updateDomainWithCName(r, fqdn)
|
||||||
for _, rr := range r.Answer {
|
|
||||||
if cn, ok := rr.(*dns.CNAME); ok {
|
|
||||||
if cn.Hdr.Name == fqdn {
|
|
||||||
fqdn = cn.Target
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
authoritativeNss, err := lookupNameservers(fqdn)
|
authoritativeNss, err := lookupNameservers(fqdn)
|
||||||
|
|
Loading…
Reference in a new issue