From 13781e67ab1b2553598d0dd1a7153ce3cdbd4879 Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Mon, 16 Nov 2020 11:05:55 -0700 Subject: caddytls: Support multiple issuers (#3862) * caddytls: Support multiple issuers Defaults are Let's Encrypt and ZeroSSL. There are probably bugs. * Commit updated integration tests, d'oh * Update go.mod --- modules/caddyhttp/autohttps.go | 61 +++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 21 deletions(-) (limited to 'modules/caddyhttp/autohttps.go') diff --git a/modules/caddyhttp/autohttps.go b/modules/caddyhttp/autohttps.go index 0780981..805a37c 100644 --- a/modules/caddyhttp/autohttps.go +++ b/modules/caddyhttp/autohttps.go @@ -241,7 +241,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er // we now have a list of all the unique names for which we need certs; // turn the set into a slice so that phase 2 can use it app.allCertDomains = make([]string, 0, len(uniqueDomainsForCerts)) - var internal, external []string + var internal []string uniqueDomainsLoop: for d := range uniqueDomainsForCerts { // whether or not there is already an automation policy for this @@ -264,15 +264,13 @@ uniqueDomainsLoop: // if no automation policy exists for the name yet, we // will associate it with an implicit one - if certmagic.SubjectQualifiesForPublicCert(d) { - external = append(external, d) - } else { + if !certmagic.SubjectQualifiesForPublicCert(d) { internal = append(internal, d) } } // ensure there is an automation policy to handle these certs - err := app.createAutomationPolicies(ctx, external, internal) + err := app.createAutomationPolicies(ctx, internal) if err != nil { return err } @@ -430,7 +428,7 @@ redirServersLoop: // automation policy exists, it will be shallow-copied and used as the // base for the new ones (this is important for preserving behavior the // user intends to be "defaults"). -func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, internalNames []string) error { +func (app *App) createAutomationPolicies(ctx caddy.Context, internalNames []string) error { // before we begin, loop through the existing automation policies // and, for any ACMEIssuers we find, make sure they're filled in // with default values that might be specified in our HTTP app; also @@ -447,16 +445,23 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna // set up default issuer -- honestly, this is only // really necessary because the HTTP app is opinionated // and has settings which could be inferred as new - // defaults for the ACMEIssuer in the TLS app - if ap.Issuer == nil { - ap.Issuer = new(caddytls.ACMEIssuer) - } - if acmeIssuer, ok := ap.Issuer.(acmeCapable); ok { - err := app.fillInACMEIssuer(acmeIssuer.GetACMEIssuer()) + // defaults for the ACMEIssuer in the TLS app (such as + // what the HTTP and HTTPS ports are) + if ap.Issuers == nil { + var err error + ap.Issuers, err = caddytls.DefaultIssuers(ctx) if err != nil { return err } } + for _, iss := range ap.Issuers { + if acmeIssuer, ok := iss.(acmeCapable); ok { + err := app.fillInACMEIssuer(acmeIssuer.GetACMEIssuer()) + if err != nil { + return err + } + } + } // while we're here, is this the catch-all/base policy? if !foundBasePolicy && len(ap.Subjects) == 0 { @@ -471,11 +476,14 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna } // if the basePolicy has an existing ACMEIssuer (particularly to - // include any type that embeds/wraps an ACMEIssuer), let's use it, - // otherwise we'll make one + // include any type that embeds/wraps an ACMEIssuer), let's use it + // (I guess we just use the first one?), otherwise we'll make one var baseACMEIssuer *caddytls.ACMEIssuer - if acmeWrapper, ok := basePolicy.Issuer.(acmeCapable); ok { - baseACMEIssuer = acmeWrapper.GetACMEIssuer() + for _, iss := range basePolicy.Issuers { + if acmeWrapper, ok := iss.(acmeCapable); ok { + baseACMEIssuer = acmeWrapper.GetACMEIssuer() + break + } } if baseACMEIssuer == nil { // note that this happens if basePolicy.Issuer is nil @@ -485,7 +493,7 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna // if there was a base policy to begin with, we already // filled in its issuer's defaults; if there wasn't, we - // stil need to do that + // still need to do that if !foundBasePolicy { err := app.fillInACMEIssuer(baseACMEIssuer) if err != nil { @@ -494,8 +502,20 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna } // never overwrite any other issuer that might already be configured - if basePolicy.Issuer == nil { - basePolicy.Issuer = baseACMEIssuer + if basePolicy.Issuers == nil { + var err error + basePolicy.Issuers, err = caddytls.DefaultIssuers(ctx) + if err != nil { + return err + } + for _, iss := range basePolicy.Issuers { + if acmeIssuer, ok := iss.(acmeCapable); ok { + err := app.fillInACMEIssuer(acmeIssuer.GetACMEIssuer()) + if err != nil { + return err + } + } + } } if !foundBasePolicy { @@ -549,8 +569,7 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna // of names that would normally use the production API; // anyway, that gets into the weeds a bit... newPolicy.Subjects = internalNames - newPolicy.Issuer = internalIssuer - + newPolicy.Issuers = []certmagic.Issuer{internalIssuer} err := app.tlsApp.AddAutomationPolicy(newPolicy) if err != nil { return err -- cgit v1.2.3