diff options
author | Matthew Holt <[email protected]> | 2015-11-18 10:05:13 -0700 |
---|---|---|
committer | Matthew Holt <[email protected]> | 2015-11-18 10:05:13 -0700 |
commit | e17d43b58a3b31f16e716791e16b69752f36a5ae (patch) | |
tree | 017f7451976905c2f28ffa21efa657369a19c4c6 | |
parent | 580b50ea20b6313d59a4eae469347bd3b418e4d3 (diff) | |
download | caddy-e17d43b58a3b31f16e716791e16b69752f36a5ae.tar.gz caddy-e17d43b58a3b31f16e716791e16b69752f36a5ae.zip |
Default host now empty string; default port now depends on host
Hosts which are eligible for automatic HTTPS have default port "https" but other hosts (wildcards, loopback, etc.) have the default port 2015. The default host of empty string should be more IPv6-compatible.
-rw-r--r-- | caddy/caddy.go | 2 | ||||
-rw-r--r-- | caddy/config.go | 20 | ||||
-rw-r--r-- | caddy/config_test.go | 25 | ||||
-rw-r--r-- | caddy/letsencrypt/letsencrypt.go | 26 | ||||
-rw-r--r-- | caddy/letsencrypt/letsencrypt_test.go | 28 |
5 files changed, 72 insertions, 29 deletions
diff --git a/caddy/caddy.go b/caddy/caddy.go index 8500d7945..e88876322 100644 --- a/caddy/caddy.go +++ b/caddy/caddy.go @@ -83,7 +83,7 @@ var ( const ( // DefaultHost is the default host. - DefaultHost = "0.0.0.0" + DefaultHost = "" // DefaultPort is the default port. DefaultPort = "2015" // DefaultRoot is the default root folder. diff --git a/caddy/config.go b/caddy/config.go index dacd57248..5819fea88 100644 --- a/caddy/config.go +++ b/caddy/config.go @@ -331,22 +331,18 @@ func validDirective(d string) bool { return false } -// NewDefault makes a default configuration, which -// is empty except for root, host, and port, -// which are essentials for serving the cwd. -func NewDefault() server.Config { - return server.Config{ - Root: Root, - Host: Host, - Port: Port, - } -} - // DefaultInput returns the default Caddyfile input // to use when it is otherwise empty or missing. +// It uses the default host and port (depends on +// host, e.g. localhost is 2015, otherwise https) and +// root. func DefaultInput() CaddyfileInput { + port := Port + if letsencrypt.HostQualifies(Host) { + port = "https" + } return CaddyfileInput{ - Contents: []byte(fmt.Sprintf("%s:%s\nroot %s", Host, Port, Root)), + Contents: []byte(fmt.Sprintf("%s:%s\nroot %s", Host, port, Root)), } } diff --git a/caddy/config_test.go b/caddy/config_test.go index 3df0b5cc9..3e70a9311 100644 --- a/caddy/config_test.go +++ b/caddy/config_test.go @@ -8,17 +8,26 @@ import ( "github.com/mholt/caddy/server" ) -func TestNewDefault(t *testing.T) { - config := NewDefault() +func TestDefaultInput(t *testing.T) { + if actual, expected := string(DefaultInput().Body()), ":2015\nroot ."; actual != expected { + t.Errorf("Host=%s; Port=%s; Root=%s;\nEXPECTED: '%s'\n ACTUAL: '%s'", Host, Port, Root, expected, actual) + } + + // next few tests simulate user providing -host flag - if actual, expected := config.Root, DefaultRoot; actual != expected { - t.Errorf("Root was %s but expected %s", actual, expected) + Host = "not-localhost.com" + if actual, expected := string(DefaultInput().Body()), "not-localhost.com:https\nroot ."; actual != expected { + t.Errorf("Host=%s; Port=%s; Root=%s;\nEXPECTED: '%s'\n ACTUAL: '%s'", Host, Port, Root, expected, actual) } - if actual, expected := config.Host, DefaultHost; actual != expected { - t.Errorf("Host was %s but expected %s", actual, expected) + + Host = "[::1]" + if actual, expected := string(DefaultInput().Body()), "[::1]:2015\nroot ."; actual != expected { + t.Errorf("Host=%s; Port=%s; Root=%s;\nEXPECTED: '%s'\n ACTUAL: '%s'", Host, Port, Root, expected, actual) } - if actual, expected := config.Port, DefaultPort; actual != expected { - t.Errorf("Port was %s but expected %s", actual, expected) + + Host = "127.0.1.1" + if actual, expected := string(DefaultInput().Body()), "127.0.1.1:2015\nroot ."; actual != expected { + t.Errorf("Host=%s; Port=%s; Root=%s;\nEXPECTED: '%s'\n ACTUAL: '%s'", Host, Port, Root, expected, actual) } } diff --git a/caddy/letsencrypt/letsencrypt.go b/caddy/letsencrypt/letsencrypt.go index 27c084b57..f3f9fde7a 100644 --- a/caddy/letsencrypt/letsencrypt.go +++ b/caddy/letsencrypt/letsencrypt.go @@ -166,17 +166,29 @@ func configQualifies(allConfigs []server.Config, cfgIndex int) bool { cfg.TLS.LetsEncryptEmail != "off" && // obviously we get can't certs for loopback or internal hosts - cfg.Host != "localhost" && - cfg.Host != "" && - cfg.Host != "0.0.0.0" && - cfg.Host != "::1" && - !strings.HasPrefix(cfg.Host, "127.") && // to use boulder on your own machine, add fake domain to hosts file - // not excluding 10.* and 192.168.* hosts for possibility of running internal Boulder instance + HostQualifies(cfg.Host) && // make sure another HTTPS version of this config doesn't exist in the list already !otherHostHasScheme(allConfigs, cfgIndex, "https") } +// HostQualifies returns true if the hostname alone +// appears eligible for automatic HTTPS. For example, +// localhost, empty hostname, and wildcard hosts are +// not eligible because we cannot obtain certificates +// for those names. +func HostQualifies(hostname string) bool { + return hostname != "localhost" && + strings.TrimSpace(hostname) != "" && + hostname != "0.0.0.0" && + hostname != "[::]" && // before parsing + hostname != "::" && // after parsing + hostname != "[::1]" && // before parsing + hostname != "::1" && // after parsing + !strings.HasPrefix(hostname, "127.") // to use boulder on your own machine, add fake domain to hosts file + // not excluding 10.* and 192.168.* hosts for possibility of running internal Boulder instance +} + // groupConfigsByEmail groups configs by user email address. The returned map is // a map of email address to the configs that are serviced under that account. // If an email address is not available for an eligible config, the user will be @@ -273,12 +285,10 @@ func newClientPort(leEmail, port string) (*acme.Client, error) { // obtainCertificates obtains certificates from the CA server for // the configurations in serverConfigs using client. func obtainCertificates(client *acme.Client, serverConfigs []server.Config) ([]acme.CertificateResource, map[string]error) { - // collect all the hostnames into one slice var hosts []string for _, cfg := range serverConfigs { hosts = append(hosts, cfg.Host) } - return client.ObtainCertificates(hosts, true) } diff --git a/caddy/letsencrypt/letsencrypt_test.go b/caddy/letsencrypt/letsencrypt_test.go index 841ec54bc..dd243c0be 100644 --- a/caddy/letsencrypt/letsencrypt_test.go +++ b/caddy/letsencrypt/letsencrypt_test.go @@ -8,6 +8,34 @@ import ( "github.com/mholt/caddy/server" ) +func TestHostQualifies(t *testing.T) { + for i, test := range []struct { + host string + expect bool + }{ + {"localhost", false}, + {"127.0.0.1", false}, + {"127.0.1.5", false}, + {"::1", false}, + {"[::1]", false}, + {"[::]", false}, + {"::", false}, + {"", false}, + {" ", false}, + {"0.0.0.0", false}, + {"192.168.1.3", true}, + {"10.0.2.1", true}, + {"foobar.com", true}, + } { + if HostQualifies(test.host) && !test.expect { + t.Errorf("Test %d: Expected '%s' to NOT qualify, but it did", i, test.host) + } + if !HostQualifies(test.host) && test.expect { + t.Errorf("Test %d: Expected '%s' to qualify, but it did NOT", i, test.host) + } + } +} + func TestRedirPlaintextHost(t *testing.T) { cfg := redirPlaintextHost(server.Config{ Host: "example.com", |