From bfde429b8ee27fee05e66fa6abe8283cd853ab96 Mon Sep 17 00:00:00 2001 From: Gurvinder Singh Date: Thu, 21 Jun 2018 21:48:16 +0200 Subject: [PATCH] add support CNAME for dns-01 challenge Domain for which certificate is asked for can have a CNAME, so we should check it. If domain has a CNAME, create the challange TXT record in the alias domain. This is useful in the scenario where a company like us is using some DNS provider which is not supported dynamically. We can then create a CNAME for records like _acme-challenge.example.com -> example.aws.hosted.com So this will allow us getting cert for *.example.com with creating txt record in route53 for above exxample. --- pkg/issuer/acme/dns/util/dns.go | 15 +++++++++++++-- pkg/issuer/acme/dns/util/wait.go | 25 ++++++++++++++++--------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/pkg/issuer/acme/dns/util/dns.go b/pkg/issuer/acme/dns/util/dns.go index 03a94e8a2..c8939e15f 100644 --- a/pkg/issuer/acme/dns/util/dns.go +++ b/pkg/issuer/acme/dns/util/dns.go @@ -1,9 +1,20 @@ package util -import "fmt" +import ( + "fmt" + + "github.com/miekg/dns" +) // DNS01Record returns a DNS record which will fulfill the `dns-01` challenge // TODO: move this into a non-generic place by resolving import cycle in dns package func DNS01Record(domain, value string) (string, string, int) { - return fmt.Sprintf("_acme-challenge.%s.", domain), value, 60 + fqdn := fmt.Sprintf("_acme-challenge.%s.", domain) + + // Check if the domain has CNAME then return that + r, err := dnsQuery(fqdn, dns.TypeCNAME, RecursiveNameservers, true) + if err == nil && r.Rcode == dns.RcodeSuccess { + fqdn = updateDomainWithCName(r, fqdn) + } + return fqdn, value, 60 } diff --git a/pkg/issuer/acme/dns/util/wait.go b/pkg/issuer/acme/dns/util/wait.go index 04f01d5d7..00e8361ee 100644 --- a/pkg/issuer/acme/dns/util/wait.go +++ b/pkg/issuer/acme/dns/util/wait.go @@ -50,6 +50,21 @@ func getNameservers(path string, defaults []string) []string { return systemNameservers } +// 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 { + glog.Infof("Updating FQDN: %s with it's CNAME: %s", fqdn, cn.Target) + fqdn = cn.Target + break + } + } + } + + return fqdn +} + // checkDNSPropagation checks if the expected TXT record has been propagated to all authoritative nameservers. func checkDNSPropagation(fqdn, value string) (bool, error) { // Initial attempt to resolve at the recursive NS @@ -58,15 +73,7 @@ func checkDNSPropagation(fqdn, value string) (bool, error) { return false, err } 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)