diff --git a/caddy/https/https.go b/caddy/https/https.go index 776425bf..cfff2868 100644 --- a/caddy/https/https.go +++ b/caddy/https/https.go @@ -95,7 +95,7 @@ func Deactivate() (err error) { } // MarkQualified scans each config and, if it qualifies for managed -// TLS, it sets the Marked field of the TLSConfig to true. +// TLS, it sets the Managed field of the TLSConfig to true. func MarkQualified(configs []server.Config) { for i := 0; i < len(configs); i++ { if ConfigQualifies(configs[i]) { @@ -152,9 +152,10 @@ func ObtainCerts(configs []server.Config, allowPrompts, proxyACME bool) error { return nil } -// groupConfigsByEmail groups configs by the email address to be used by its -// ACME client. It only includes configs that are marked as fully managed. -// If userPresent is true, the operator MAY be prompted for an email address. +// groupConfigsByEmail groups configs by the email address to be used by an +// ACME client. It only groups configs that have TLS enabled and that are +// marked as Managed. If userPresent is true, the operator MAY be prompted +// for an email address. func groupConfigsByEmail(configs []server.Config, userPresent bool) map[string][]server.Config { initMap := make(map[string][]server.Config) for _, cfg := range configs { @@ -214,7 +215,7 @@ func hostHasOtherPort(allConfigs []server.Config, thisConfigIdx int, otherPort s // all configs. func MakePlaintextRedirects(allConfigs []server.Config) []server.Config { for i, cfg := range allConfigs { - if cfg.TLS.Managed && + if (cfg.TLS.Managed || cfg.TLS.OnDemand) && !hostHasOtherPort(allConfigs, i, "80") && (cfg.Port == "443" || !hostHasOtherPort(allConfigs, i, "443")) { allConfigs = append(allConfigs, redirPlaintextHost(cfg)) @@ -224,10 +225,11 @@ func MakePlaintextRedirects(allConfigs []server.Config) []server.Config { } // ConfigQualifies returns true if cfg qualifies for -// fully managed TLS. It does NOT check to see if a +// fully managed TLS (but not on-demand TLS, which is +// not considered here). It does NOT check to see if a // cert and key already exist for the config. If the // config does qualify, you should set cfg.TLS.Managed -// to true and use that instead, because the process of +// to true and check that instead, because the process of // setting up the config may make it look like it // doesn't qualify even though it originally did. func ConfigQualifies(cfg server.Config) bool { @@ -238,10 +240,8 @@ func ConfigQualifies(cfg server.Config) bool { cfg.Port != "80" && cfg.TLS.LetsEncryptEmail != "off" && - // we get can't certs for some kinds of hostnames, - // but we CAN get certs at request-time even if - // the hostname in the config is empty right now. - (cfg.Host == "" || HostQualifies(cfg.Host)) + // we get can't certs for some kinds of hostnames + HostQualifies(cfg.Host) } // HostQualifies returns true if the hostname alone diff --git a/caddy/https/https_test.go b/caddy/https/https_test.go index e4efd237..d724635b 100644 --- a/caddy/https/https_test.go +++ b/caddy/https/https_test.go @@ -46,7 +46,7 @@ func TestConfigQualifies(t *testing.T) { cfg server.Config expect bool }{ - {server.Config{Host: ""}, true}, + {server.Config{Host: ""}, false}, {server.Config{Host: "localhost"}, false}, {server.Config{Host: "123.44.3.21"}, false}, {server.Config{Host: "example.com"}, true}, @@ -302,6 +302,7 @@ func TestGroupConfigsByEmail(t *testing.T) { func TestMarkQualified(t *testing.T) { // TODO: TestConfigQualifies and this test share the same config list... configs := []server.Config{ + {Host: ""}, {Host: "localhost"}, {Host: "123.44.3.21"}, {Host: "example.com"}, @@ -313,9 +314,8 @@ func TestMarkQualified(t *testing.T) { {Host: "example.com", Port: "1234"}, {Host: "example.com", Scheme: "https"}, {Host: "example.com", Port: "80", Scheme: "https"}, - {Host: ""}, } - expectedManagedCount := 5 + expectedManagedCount := 4 MarkQualified(configs) diff --git a/caddy/https/setup.go b/caddy/https/setup.go index 2500bce0..ebf46d24 100644 --- a/caddy/https/setup.go +++ b/caddy/https/setup.go @@ -83,6 +83,7 @@ func Setup(c *setup.Controller) (middleware.Middleware, error) { c.TLS.Manual = true case "max_certs": c.Args(&maxCerts) + c.TLS.OnDemand = true default: return nil, c.Errf("Unknown keyword '%s'", c.Val()) } @@ -93,21 +94,18 @@ func Setup(c *setup.Controller) (middleware.Middleware, error) { return nil, c.ArgErr() } - if c.TLS.Manual && maxCerts != "" { - return nil, c.Err("Cannot limit certificate count (max_certs) for manual TLS configurations") - } - + // set certificate limit if on-demand TLS is enabled if maxCerts != "" { maxCertsNum, err := strconv.Atoi(maxCerts) - if err != nil || maxCertsNum < 0 { + if err != nil || maxCertsNum < 1 { return nil, c.Err("max_certs must be a positive integer") } - if onDemandMaxIssue == 0 || int32(maxCertsNum) < onDemandMaxIssue { // keep the minimum; TODO: This is global; should be per-server or per-vhost... + if onDemandMaxIssue == 0 || int32(maxCertsNum) < onDemandMaxIssue { // keep the minimum; TODO: We have to do this because it is global; should be per-server or per-vhost... onDemandMaxIssue = int32(maxCertsNum) } } - // don't load certificates unless we're supposed to + // don't try to load certificates unless we're supposed to if !c.TLS.Enabled || !c.TLS.Manual { continue } diff --git a/server/config.go b/server/config.go index cae1edf5..9acdac7f 100644 --- a/server/config.go +++ b/server/config.go @@ -65,10 +65,11 @@ func (c Config) Address() string { // TLSConfig describes how TLS should be configured and used. type TLSConfig struct { - Enabled bool + Enabled bool // will be set to true if TLS is enabled LetsEncryptEmail string - Managed bool // will be set to true if config qualifies for automatic, managed TLS - Manual bool // will be set to true if user provides the cert and key files + Manual bool // will be set to true if user provides own certs and keys + Managed bool // will be set to true if config qualifies for automatic/managed HTTPS + OnDemand bool // will be set to true if user enables on-demand TLS (obtain certs during handshakes) Ciphers []uint16 ProtocolMinVersion uint16 ProtocolMaxVersion uint16 diff --git a/server/server.go b/server/server.go index 43b1d857..3b38e483 100644 --- a/server/server.go +++ b/server/server.go @@ -63,12 +63,14 @@ func New(addr string, configs []Config, gracefulTimeout time.Duration) (*Server, var useTLS, useOnDemandTLS bool if len(configs) > 0 { useTLS = configs[0].TLS.Enabled - host, _, err := net.SplitHostPort(addr) - if err != nil { - host = addr - } - if useTLS && host == "" && !configs[0].TLS.Manual { - useOnDemandTLS = true + if useTLS { + host, _, err := net.SplitHostPort(addr) + if err != nil { + host = addr + } + if host == "" && configs[0].TLS.OnDemand { + useOnDemandTLS = true + } } }