summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2020-04-24 17:36:52 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2020-04-24 17:36:52 -0600
commitebf07f853bfbc54821fc35c0cfba97111ae70866 (patch)
tree91b7b958af13a39507f8aae868ea285094344dea /modules
parent1b061815b2a336ce4f8d1d3ce3054dab19e00745 (diff)
caddyhttp: Fix auto redirects for catch-all HTTPS sites
Prior logic was not setting up redirects for the case when domain names are not known, but the server still clearly has TLS enabled.
Diffstat (limited to 'modules')
-rw-r--r--modules/caddyhttp/autohttps.go45
1 files changed, 29 insertions, 16 deletions
diff --git a/modules/caddyhttp/autohttps.go b/modules/caddyhttp/autohttps.go
index 44cf581..83414bb 100644
--- a/modules/caddyhttp/autohttps.go
+++ b/modules/caddyhttp/autohttps.go
@@ -129,6 +129,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
}
// find all qualifying domain names (deduplicated) in this server
+ // (this is where we need the provisioned, decoded request matchers)
serverDomainSet := make(map[string]struct{})
for routeIdx, route := range srv.Routes {
for matcherSetIdx, matcherSet := range route.MatcherSets {
@@ -150,9 +151,14 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
}
}
- // nothing more to do here if there are no
- // domains that qualify for automatic HTTPS
- if len(serverDomainSet) == 0 {
+ // nothing more to do here if there are no domains that qualify for
+ // automatic HTTPS or there are no explicit TLS connection policies;
+ // if there is at least one domain but no TLS conn policy, we'll add
+ // one below; if there is a TLS conn policy (meaning TLS is enabled)
+ // and no domains, it could be a catch-all with on-demand TLS, and
+ // in that case we would still need HTTP->HTTPS redirects, which we
+ // do below
+ if len(serverDomainSet) == 0 || len(srv.TLSConnPolicies) == 0 {
continue
}
@@ -207,6 +213,17 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
return fmt.Errorf("%s: invalid listener address: %v", srvName, addr)
}
+ // this address might not have a hostname, i.e. might be a
+ // catch-all address for a particular port; we need to keep
+ // track if it is, so we can set up redirects for it anyway
+ // (e.g. the user might have enabled on-demand TLS); we use
+ // an empty string to indicate a catch-all, which we have to
+ // treat special later
+ if len(serverDomainSet) == 0 {
+ redirDomains[""] = addr
+ continue
+ }
+
// ...and associate it with each domain in this server
for d := range serverDomainSet {
// if this domain is used on more than one HTTPS-enabled
@@ -258,11 +275,6 @@ uniqueDomainsLoop:
return err
}
- // we're done if there are no HTTP->HTTPS redirects to add
- if len(redirDomains) == 0 {
- return nil
- }
-
// we need to reduce the mapping, i.e. group domains by address
// since new routes are appended to servers by their address
domainsByAddr := make(map[string][]string)
@@ -275,17 +287,18 @@ uniqueDomainsLoop:
// and the routes for those servers which actually
// respond with the redirects
redirServerAddrs := make(map[string]struct{})
- var redirRoutes RouteList
-
redirServers := make(map[string][]Route)
+ var redirRoutes RouteList
for addrStr, domains := range domainsByAddr {
- // build the matcher set for this redirect route
- // (note that we happen to bypass Provision and
- // Validate steps for these matcher modules)
- matcherSet := MatcherSet{
- MatchProtocol("http"),
- MatchHost(domains),
+ // build the matcher set for this redirect route; (note that we happen
+ // to bypass Provision and Validate steps for these matcher modules)
+ matcherSet := MatcherSet{MatchProtocol("http")}
+ // match on known domain names, unless it's our special case of a
+ // catch-all which is an empty string (common among catch-all sites
+ // that enable on-demand TLS for yet-unknown domain names)
+ if !(len(domains) == 1 && domains[0] == "") {
+ matcherSet = append(matcherSet, MatchHost(domains))
}
// build the address to which to redirect