From 3eaca6a318c47e7433ceaa94f1a5aa14d4442681 Mon Sep 17 00:00:00 2001 From: Louis Taylor Date: Thu, 5 Jul 2018 12:40:53 +0100 Subject: [PATCH] Add flag for custom dns01 nameservers --- cmd/controller/app/controller.go | 12 ++++++++++++ cmd/controller/app/options/options.go | 8 ++++++++ pkg/issuer/acme/acme.go | 8 ++++++-- pkg/issuer/acme/dns/dns.go | 8 +++++--- pkg/issuer/acme/dns/util/wait.go | 6 +++--- pkg/issuer/context.go | 2 ++ 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/cmd/controller/app/controller.go b/cmd/controller/app/controller.go index 66f6772d2..9b75342cd 100644 --- a/cmd/controller/app/controller.go +++ b/cmd/controller/app/controller.go @@ -3,6 +3,7 @@ package app import ( "fmt" "os" + "strings" "sync" "time" @@ -23,6 +24,7 @@ import ( informers "github.com/jetstack/cert-manager/pkg/client/informers/externalversions" "github.com/jetstack/cert-manager/pkg/controller" "github.com/jetstack/cert-manager/pkg/issuer" + dnsutil "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" "github.com/jetstack/cert-manager/pkg/util/kube" kubeinformers "k8s.io/client-go/informers" ) @@ -95,6 +97,15 @@ func buildControllerContext(opts *options.ControllerOptions) (*controller.Contex return nil, nil, fmt.Errorf("error creating kubernetes client: %s", err.Error()) } + nameservers := []string{} + if opts.DNS01Nameservers != "" { + nameservers = strings.Split(opts.DNS01Nameservers, ",") + } else { + nameservers = dnsutil.RecursiveNameservers + } + + glog.Infof("Using the following nameservers for DNS01 checks: %v", nameservers) + // Create event broadcaster // Add cert-manager types to the default Kubernetes Scheme so Events can be // logged properly @@ -123,6 +134,7 @@ func buildControllerContext(opts *options.ControllerOptions) (*controller.Contex ACMEHTTP01SolverImage: opts.ACMEHTTP01SolverImage, ClusterIssuerAmbientCredentials: opts.ClusterIssuerAmbientCredentials, IssuerAmbientCredentials: opts.IssuerAmbientCredentials, + DNS01Nameservers: nameservers, }), ClusterResourceNamespace: opts.ClusterResourceNamespace, DefaultIssuerName: opts.DefaultIssuerName, diff --git a/cmd/controller/app/options/options.go b/cmd/controller/app/options/options.go index aa61e2e6e..324f28905 100644 --- a/cmd/controller/app/options/options.go +++ b/cmd/controller/app/options/options.go @@ -29,6 +29,9 @@ type ControllerOptions struct { DefaultIssuerKind string DefaultACMEIssuerChallengeType string DefaultACMEIssuerDNS01ProviderName string + + // DNS01Nameservers allows specifying a list of custom nameservers to perform DNS checks + DNS01Nameservers string } const ( @@ -48,6 +51,8 @@ const ( defaultTLSACMEIssuerKind = "Issuer" defaultACMEIssuerChallengeType = "http01" defaultACMEIssuerDNS01ProviderName = "" + + defaultDNS01Nameservers = "" ) var ( @@ -69,6 +74,7 @@ func NewControllerOptions() *ControllerOptions { DefaultIssuerKind: defaultTLSACMEIssuerKind, DefaultACMEIssuerChallengeType: defaultACMEIssuerChallengeType, DefaultACMEIssuerDNS01ProviderName: defaultACMEIssuerDNS01ProviderName, + DNS01Nameservers: defaultDNS01Nameservers, } } @@ -120,6 +126,8 @@ func (s *ControllerOptions) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.DefaultACMEIssuerDNS01ProviderName, "default-acme-issuer-dns01-provider-name", defaultACMEIssuerDNS01ProviderName, ""+ "Required if --default-acme-issuer-challenge-type is set to dns01. The DNS01 provider to use for ingresses using ACME dns01 "+ "validation that do not explicitly state a dns provider.") + fs.StringVar(&s.DNS01Nameservers, "dns01-nameservers", defaultDNS01Nameservers, ""+ + "A list of comma seperated DNS servers used for DNS01 check requests") } func (o *ControllerOptions) Validate() error { diff --git a/pkg/issuer/acme/acme.go b/pkg/issuer/acme/acme.go index 14d154f2b..cb28866f0 100644 --- a/pkg/issuer/acme/acme.go +++ b/pkg/issuer/acme/acme.go @@ -62,6 +62,8 @@ type Acme struct { // variables. // Currently, only AWS ambient credential control is implemented. ambientCredentials bool + + dns01Nameservers []string } // solver solves ACME challenges by presenting the given token and key in an @@ -90,7 +92,8 @@ func New(issuer v1alpha1.GenericIssuer, podsLister corelisters.PodLister, servicesLister corelisters.ServiceLister, ingressLister extlisters.IngressLister, - ambientCreds bool) (issuer.Interface, error) { + ambientCreds bool, + dns01Nameservers []string) (issuer.Interface, error) { if issuer.GetSpec().ACME == nil { return nil, fmt.Errorf("acme config may not be empty") } @@ -115,7 +118,7 @@ func New(issuer v1alpha1.GenericIssuer, servicesLister: servicesLister, ingressLister: ingressLister, - dnsSolver: dns.NewSolver(issuer, client, secretsLister, resourceNamespace, ambientCreds), + dnsSolver: dns.NewSolver(issuer, client, secretsLister, resourceNamespace, ambientCreds, dns01Nameservers), httpSolver: http.NewSolver(issuer, client, podsLister, servicesLister, ingressLister, acmeHTTP01SolverImage), issuerResourcesNamespace: resourceNamespace, } @@ -235,6 +238,7 @@ func init() { ctx.KubeSharedInformerFactory.Core().V1().Services().Lister(), ctx.KubeSharedInformerFactory.Extensions().V1beta1().Ingresses().Lister(), ambientCreds, + ctx.DNS01Nameservers, ) }) } diff --git a/pkg/issuer/acme/dns/dns.go b/pkg/issuer/acme/dns/dns.go index be8f69aa1..98f50482f 100644 --- a/pkg/issuer/acme/dns/dns.go +++ b/pkg/issuer/acme/dns/dns.go @@ -52,6 +52,7 @@ type Solver struct { resourceNamespace string dnsProviderConstructors dnsProviderConstructors ambientCredentials bool + dns01Nameservers []string } func (s *Solver) Present(ctx context.Context, _ *v1alpha1.Certificate, ch v1alpha1.ACMEOrderChallenge) error { @@ -75,9 +76,9 @@ func (s *Solver) Present(ctx context.Context, _ *v1alpha1.Certificate, ch v1alph func (s *Solver) Check(ch v1alpha1.ACMEOrderChallenge) (bool, error) { fqdn, value, ttl := util.DNS01Record(ch.Domain, ch.Key) - glog.Infof("Checking DNS propagation for %q using name servers: %v", ch.Domain, util.RecursiveNameservers) + glog.Infof("Checking DNS propagation for %q using name servers: %v", ch.Domain, s.dns01Nameservers) - ok, err := util.PreCheckDNS(fqdn, value) + ok, err := util.PreCheckDNS(fqdn, value, s.dns01Nameservers) if err != nil { return false, err } @@ -245,7 +246,7 @@ func (s *Solver) solverForIssuerProvider(providerName string) (solver, error) { return impl, nil } -func NewSolver(issuer v1alpha1.GenericIssuer, client kubernetes.Interface, secretLister corev1listers.SecretLister, resourceNamespace string, ambientCredentials bool) *Solver { +func NewSolver(issuer v1alpha1.GenericIssuer, client kubernetes.Interface, secretLister corev1listers.SecretLister, resourceNamespace string, ambientCredentials bool, dns01Nameservers []string) *Solver { return &Solver{ issuer, client, @@ -258,6 +259,7 @@ func NewSolver(issuer v1alpha1.GenericIssuer, client kubernetes.Interface, secre azuredns.NewDNSProviderCredentials, }, ambientCredentials, + dns01Nameservers, } } diff --git a/pkg/issuer/acme/dns/util/wait.go b/pkg/issuer/acme/dns/util/wait.go index 04f01d5d7..d337ef4bc 100644 --- a/pkg/issuer/acme/dns/util/wait.go +++ b/pkg/issuer/acme/dns/util/wait.go @@ -10,7 +10,7 @@ import ( "github.com/miekg/dns" ) -type preCheckDNSFunc func(fqdn, value string) (bool, error) +type preCheckDNSFunc func(fqdn, value string, nameservers []string) (bool, error) var ( // PreCheckDNS checks DNS propagation before notifying ACME that @@ -51,9 +51,9 @@ func getNameservers(path string, defaults []string) []string { } // checkDNSPropagation checks if the expected TXT record has been propagated to all authoritative nameservers. -func checkDNSPropagation(fqdn, value string) (bool, error) { +func checkDNSPropagation(fqdn, value string, nameservers []string) (bool, error) { // Initial attempt to resolve at the recursive NS - r, err := dnsQuery(fqdn, dns.TypeTXT, RecursiveNameservers, true) + r, err := dnsQuery(fqdn, dns.TypeTXT, nameservers, true) if err != nil { return false, err } diff --git a/pkg/issuer/context.go b/pkg/issuer/context.go index df632bcde..290c6b219 100644 --- a/pkg/issuer/context.go +++ b/pkg/issuer/context.go @@ -43,4 +43,6 @@ type Context struct { // IssuerAmbientCredentials controls whether an issuer should pick up ambient // credentials, such as those from metadata services, to construct clients. IssuerAmbientCredentials bool + + DNS01Nameservers []string }