mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Fix HTTPS config for empty/no Caddyfile
This fixes a regression introduced in recent commits that enabled TLS on the default ":2015" config. This fix is possible because On-Demand TLS is no longer implicit; it must be explicitly enabled by the user by setting a maximum number of certificates to issue.
This commit is contained in:
parent
04c7c442c5
commit
a11e14aca8
5 changed files with 31 additions and 30 deletions
|
@ -95,7 +95,7 @@ func Deactivate() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkQualified scans each config and, if it qualifies for managed
|
// 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) {
|
func MarkQualified(configs []server.Config) {
|
||||||
for i := 0; i < len(configs); i++ {
|
for i := 0; i < len(configs); i++ {
|
||||||
if ConfigQualifies(configs[i]) {
|
if ConfigQualifies(configs[i]) {
|
||||||
|
@ -152,9 +152,10 @@ func ObtainCerts(configs []server.Config, allowPrompts, proxyACME bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// groupConfigsByEmail groups configs by the email address to be used by its
|
// groupConfigsByEmail groups configs by the email address to be used by an
|
||||||
// ACME client. It only includes configs that are marked as fully managed.
|
// ACME client. It only groups configs that have TLS enabled and that are
|
||||||
// If userPresent is true, the operator MAY be prompted for an email address.
|
// 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 {
|
func groupConfigsByEmail(configs []server.Config, userPresent bool) map[string][]server.Config {
|
||||||
initMap := make(map[string][]server.Config)
|
initMap := make(map[string][]server.Config)
|
||||||
for _, cfg := range configs {
|
for _, cfg := range configs {
|
||||||
|
@ -214,7 +215,7 @@ func hostHasOtherPort(allConfigs []server.Config, thisConfigIdx int, otherPort s
|
||||||
// all configs.
|
// all configs.
|
||||||
func MakePlaintextRedirects(allConfigs []server.Config) []server.Config {
|
func MakePlaintextRedirects(allConfigs []server.Config) []server.Config {
|
||||||
for i, cfg := range allConfigs {
|
for i, cfg := range allConfigs {
|
||||||
if cfg.TLS.Managed &&
|
if (cfg.TLS.Managed || cfg.TLS.OnDemand) &&
|
||||||
!hostHasOtherPort(allConfigs, i, "80") &&
|
!hostHasOtherPort(allConfigs, i, "80") &&
|
||||||
(cfg.Port == "443" || !hostHasOtherPort(allConfigs, i, "443")) {
|
(cfg.Port == "443" || !hostHasOtherPort(allConfigs, i, "443")) {
|
||||||
allConfigs = append(allConfigs, redirPlaintextHost(cfg))
|
allConfigs = append(allConfigs, redirPlaintextHost(cfg))
|
||||||
|
@ -224,10 +225,11 @@ func MakePlaintextRedirects(allConfigs []server.Config) []server.Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigQualifies returns true if cfg qualifies for
|
// 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
|
// cert and key already exist for the config. If the
|
||||||
// config does qualify, you should set cfg.TLS.Managed
|
// 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
|
// setting up the config may make it look like it
|
||||||
// doesn't qualify even though it originally did.
|
// doesn't qualify even though it originally did.
|
||||||
func ConfigQualifies(cfg server.Config) bool {
|
func ConfigQualifies(cfg server.Config) bool {
|
||||||
|
@ -238,10 +240,8 @@ func ConfigQualifies(cfg server.Config) bool {
|
||||||
cfg.Port != "80" &&
|
cfg.Port != "80" &&
|
||||||
cfg.TLS.LetsEncryptEmail != "off" &&
|
cfg.TLS.LetsEncryptEmail != "off" &&
|
||||||
|
|
||||||
// we get can't certs for some kinds of hostnames,
|
// we get can't certs for some kinds of hostnames
|
||||||
// but we CAN get certs at request-time even if
|
HostQualifies(cfg.Host)
|
||||||
// the hostname in the config is empty right now.
|
|
||||||
(cfg.Host == "" || HostQualifies(cfg.Host))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HostQualifies returns true if the hostname alone
|
// HostQualifies returns true if the hostname alone
|
||||||
|
|
|
@ -46,7 +46,7 @@ func TestConfigQualifies(t *testing.T) {
|
||||||
cfg server.Config
|
cfg server.Config
|
||||||
expect bool
|
expect bool
|
||||||
}{
|
}{
|
||||||
{server.Config{Host: ""}, true},
|
{server.Config{Host: ""}, false},
|
||||||
{server.Config{Host: "localhost"}, false},
|
{server.Config{Host: "localhost"}, false},
|
||||||
{server.Config{Host: "123.44.3.21"}, false},
|
{server.Config{Host: "123.44.3.21"}, false},
|
||||||
{server.Config{Host: "example.com"}, true},
|
{server.Config{Host: "example.com"}, true},
|
||||||
|
@ -302,6 +302,7 @@ func TestGroupConfigsByEmail(t *testing.T) {
|
||||||
func TestMarkQualified(t *testing.T) {
|
func TestMarkQualified(t *testing.T) {
|
||||||
// TODO: TestConfigQualifies and this test share the same config list...
|
// TODO: TestConfigQualifies and this test share the same config list...
|
||||||
configs := []server.Config{
|
configs := []server.Config{
|
||||||
|
{Host: ""},
|
||||||
{Host: "localhost"},
|
{Host: "localhost"},
|
||||||
{Host: "123.44.3.21"},
|
{Host: "123.44.3.21"},
|
||||||
{Host: "example.com"},
|
{Host: "example.com"},
|
||||||
|
@ -313,9 +314,8 @@ func TestMarkQualified(t *testing.T) {
|
||||||
{Host: "example.com", Port: "1234"},
|
{Host: "example.com", Port: "1234"},
|
||||||
{Host: "example.com", Scheme: "https"},
|
{Host: "example.com", Scheme: "https"},
|
||||||
{Host: "example.com", Port: "80", Scheme: "https"},
|
{Host: "example.com", Port: "80", Scheme: "https"},
|
||||||
{Host: ""},
|
|
||||||
}
|
}
|
||||||
expectedManagedCount := 5
|
expectedManagedCount := 4
|
||||||
|
|
||||||
MarkQualified(configs)
|
MarkQualified(configs)
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ func Setup(c *setup.Controller) (middleware.Middleware, error) {
|
||||||
c.TLS.Manual = true
|
c.TLS.Manual = true
|
||||||
case "max_certs":
|
case "max_certs":
|
||||||
c.Args(&maxCerts)
|
c.Args(&maxCerts)
|
||||||
|
c.TLS.OnDemand = true
|
||||||
default:
|
default:
|
||||||
return nil, c.Errf("Unknown keyword '%s'", c.Val())
|
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()
|
return nil, c.ArgErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.TLS.Manual && maxCerts != "" {
|
// set certificate limit if on-demand TLS is enabled
|
||||||
return nil, c.Err("Cannot limit certificate count (max_certs) for manual TLS configurations")
|
|
||||||
}
|
|
||||||
|
|
||||||
if maxCerts != "" {
|
if maxCerts != "" {
|
||||||
maxCertsNum, err := strconv.Atoi(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")
|
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)
|
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 {
|
if !c.TLS.Enabled || !c.TLS.Manual {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,10 +65,11 @@ func (c Config) Address() string {
|
||||||
|
|
||||||
// TLSConfig describes how TLS should be configured and used.
|
// TLSConfig describes how TLS should be configured and used.
|
||||||
type TLSConfig struct {
|
type TLSConfig struct {
|
||||||
Enabled bool
|
Enabled bool // will be set to true if TLS is enabled
|
||||||
LetsEncryptEmail string
|
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 own certs and keys
|
||||||
Manual bool // will be set to true if user provides the cert and key files
|
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
|
Ciphers []uint16
|
||||||
ProtocolMinVersion uint16
|
ProtocolMinVersion uint16
|
||||||
ProtocolMaxVersion uint16
|
ProtocolMaxVersion uint16
|
||||||
|
|
|
@ -63,14 +63,16 @@ func New(addr string, configs []Config, gracefulTimeout time.Duration) (*Server,
|
||||||
var useTLS, useOnDemandTLS bool
|
var useTLS, useOnDemandTLS bool
|
||||||
if len(configs) > 0 {
|
if len(configs) > 0 {
|
||||||
useTLS = configs[0].TLS.Enabled
|
useTLS = configs[0].TLS.Enabled
|
||||||
|
if useTLS {
|
||||||
host, _, err := net.SplitHostPort(addr)
|
host, _, err := net.SplitHostPort(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
host = addr
|
host = addr
|
||||||
}
|
}
|
||||||
if useTLS && host == "" && !configs[0].TLS.Manual {
|
if host == "" && configs[0].TLS.OnDemand {
|
||||||
useOnDemandTLS = true
|
useOnDemandTLS = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s := &Server{
|
s := &Server{
|
||||||
Server: &http.Server{
|
Server: &http.Server{
|
||||||
|
|
Loading…
Reference in a new issue