Add flag for custom dns01 nameservers

This commit is contained in:
Louis Taylor 2018-07-05 12:40:53 +01:00
parent 5f629aa4c5
commit 3eaca6a318
No known key found for this signature in database
GPG Key ID: 8E81A6DAE13E7098
6 changed files with 36 additions and 8 deletions

View File

@ -3,6 +3,7 @@ package app
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"sync" "sync"
"time" "time"
@ -23,6 +24,7 @@ import (
informers "github.com/jetstack/cert-manager/pkg/client/informers/externalversions" informers "github.com/jetstack/cert-manager/pkg/client/informers/externalversions"
"github.com/jetstack/cert-manager/pkg/controller" "github.com/jetstack/cert-manager/pkg/controller"
"github.com/jetstack/cert-manager/pkg/issuer" "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" "github.com/jetstack/cert-manager/pkg/util/kube"
kubeinformers "k8s.io/client-go/informers" 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()) 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 // Create event broadcaster
// Add cert-manager types to the default Kubernetes Scheme so Events can be // Add cert-manager types to the default Kubernetes Scheme so Events can be
// logged properly // logged properly
@ -123,6 +134,7 @@ func buildControllerContext(opts *options.ControllerOptions) (*controller.Contex
ACMEHTTP01SolverImage: opts.ACMEHTTP01SolverImage, ACMEHTTP01SolverImage: opts.ACMEHTTP01SolverImage,
ClusterIssuerAmbientCredentials: opts.ClusterIssuerAmbientCredentials, ClusterIssuerAmbientCredentials: opts.ClusterIssuerAmbientCredentials,
IssuerAmbientCredentials: opts.IssuerAmbientCredentials, IssuerAmbientCredentials: opts.IssuerAmbientCredentials,
DNS01Nameservers: nameservers,
}), }),
ClusterResourceNamespace: opts.ClusterResourceNamespace, ClusterResourceNamespace: opts.ClusterResourceNamespace,
DefaultIssuerName: opts.DefaultIssuerName, DefaultIssuerName: opts.DefaultIssuerName,

View File

@ -29,6 +29,9 @@ type ControllerOptions struct {
DefaultIssuerKind string DefaultIssuerKind string
DefaultACMEIssuerChallengeType string DefaultACMEIssuerChallengeType string
DefaultACMEIssuerDNS01ProviderName string DefaultACMEIssuerDNS01ProviderName string
// DNS01Nameservers allows specifying a list of custom nameservers to perform DNS checks
DNS01Nameservers string
} }
const ( const (
@ -48,6 +51,8 @@ const (
defaultTLSACMEIssuerKind = "Issuer" defaultTLSACMEIssuerKind = "Issuer"
defaultACMEIssuerChallengeType = "http01" defaultACMEIssuerChallengeType = "http01"
defaultACMEIssuerDNS01ProviderName = "" defaultACMEIssuerDNS01ProviderName = ""
defaultDNS01Nameservers = ""
) )
var ( var (
@ -69,6 +74,7 @@ func NewControllerOptions() *ControllerOptions {
DefaultIssuerKind: defaultTLSACMEIssuerKind, DefaultIssuerKind: defaultTLSACMEIssuerKind,
DefaultACMEIssuerChallengeType: defaultACMEIssuerChallengeType, DefaultACMEIssuerChallengeType: defaultACMEIssuerChallengeType,
DefaultACMEIssuerDNS01ProviderName: defaultACMEIssuerDNS01ProviderName, 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, ""+ 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 "+ "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.") "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 { func (o *ControllerOptions) Validate() error {

View File

@ -62,6 +62,8 @@ type Acme struct {
// variables. // variables.
// Currently, only AWS ambient credential control is implemented. // Currently, only AWS ambient credential control is implemented.
ambientCredentials bool ambientCredentials bool
dns01Nameservers []string
} }
// solver solves ACME challenges by presenting the given token and key in an // 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, podsLister corelisters.PodLister,
servicesLister corelisters.ServiceLister, servicesLister corelisters.ServiceLister,
ingressLister extlisters.IngressLister, ingressLister extlisters.IngressLister,
ambientCreds bool) (issuer.Interface, error) { ambientCreds bool,
dns01Nameservers []string) (issuer.Interface, error) {
if issuer.GetSpec().ACME == nil { if issuer.GetSpec().ACME == nil {
return nil, fmt.Errorf("acme config may not be empty") return nil, fmt.Errorf("acme config may not be empty")
} }
@ -115,7 +118,7 @@ func New(issuer v1alpha1.GenericIssuer,
servicesLister: servicesLister, servicesLister: servicesLister,
ingressLister: ingressLister, 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), httpSolver: http.NewSolver(issuer, client, podsLister, servicesLister, ingressLister, acmeHTTP01SolverImage),
issuerResourcesNamespace: resourceNamespace, issuerResourcesNamespace: resourceNamespace,
} }
@ -235,6 +238,7 @@ func init() {
ctx.KubeSharedInformerFactory.Core().V1().Services().Lister(), ctx.KubeSharedInformerFactory.Core().V1().Services().Lister(),
ctx.KubeSharedInformerFactory.Extensions().V1beta1().Ingresses().Lister(), ctx.KubeSharedInformerFactory.Extensions().V1beta1().Ingresses().Lister(),
ambientCreds, ambientCreds,
ctx.DNS01Nameservers,
) )
}) })
} }

View File

@ -52,6 +52,7 @@ type Solver struct {
resourceNamespace string resourceNamespace string
dnsProviderConstructors dnsProviderConstructors dnsProviderConstructors dnsProviderConstructors
ambientCredentials bool ambientCredentials bool
dns01Nameservers []string
} }
func (s *Solver) Present(ctx context.Context, _ *v1alpha1.Certificate, ch v1alpha1.ACMEOrderChallenge) error { 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) { func (s *Solver) Check(ch v1alpha1.ACMEOrderChallenge) (bool, error) {
fqdn, value, ttl := util.DNS01Record(ch.Domain, ch.Key) 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 { if err != nil {
return false, err return false, err
} }
@ -245,7 +246,7 @@ func (s *Solver) solverForIssuerProvider(providerName string) (solver, error) {
return impl, nil 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{ return &Solver{
issuer, issuer,
client, client,
@ -258,6 +259,7 @@ func NewSolver(issuer v1alpha1.GenericIssuer, client kubernetes.Interface, secre
azuredns.NewDNSProviderCredentials, azuredns.NewDNSProviderCredentials,
}, },
ambientCredentials, ambientCredentials,
dns01Nameservers,
} }
} }

View File

@ -10,7 +10,7 @@ import (
"github.com/miekg/dns" "github.com/miekg/dns"
) )
type preCheckDNSFunc func(fqdn, value string) (bool, error) type preCheckDNSFunc func(fqdn, value string, nameservers []string) (bool, error)
var ( var (
// PreCheckDNS checks DNS propagation before notifying ACME that // 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. // 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 // 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 { if err != nil {
return false, err return false, err
} }

View File

@ -43,4 +43,6 @@ type Context struct {
// IssuerAmbientCredentials controls whether an issuer should pick up ambient // IssuerAmbientCredentials controls whether an issuer should pick up ambient
// credentials, such as those from metadata services, to construct clients. // credentials, such as those from metadata services, to construct clients.
IssuerAmbientCredentials bool IssuerAmbientCredentials bool
DNS01Nameservers []string
} }