@marcel91200 / caddy Mirror · read-only / commits / d68cff8e
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

httpcaddyfile: Skip TLS APs for HTTP-only hosts (fix #3977)

This is probably an invasive change, but existing tests continue to pass. It seems to make sense this way. There is likely an edge case I haven't considered.

Matthew Holt committed Jan 19, 2021 at 14:16 UTC d68cff8eb6211be10fc79d3e8d469562420b78cd
3 files changed +88 -10
caddyconfig/httpcaddyfile/httptype.go
+34 -10
@@ -409,7 +409,7 @@ func (st *ServerType) serversFromPairings(
409 var iLongestHost, jLongestHost string
410 var iWildcardHost, jWildcardHost bool
411 for _, addr := range p.serverBlocks[i].keys {
412 - if strings.Contains(addr.Host, "*.") {
412 + if strings.Contains(addr.Host, "*") {
413 iWildcardHost = true
414 }
415 if specificity(addr.Host) > specificity(iLongestHost) {
@@ -420,7 +420,7 @@ func (st *ServerType) serversFromPairings(
420 }
421 }
422 for _, addr := range p.serverBlocks[j].keys {
423 - if strings.Contains(addr.Host, "*.") {
423 + if strings.Contains(addr.Host, "*") {
424 jWildcardHost = true
425 }
426 if specificity(addr.Host) > specificity(jLongestHost) {
@@ -500,16 +500,20 @@ func (st *ServerType) serversFromPairings(
500 }
501
502 for _, addr := range sblock.keys {
503 - // exclude any hosts that were defined explicitly with "http://"
504 - // in the key from automated cert management (issue #2998)
505 - if addr.Scheme == "http" && addr.Host != "" {
506 - if srv.AutoHTTPS == nil {
507 - srv.AutoHTTPS = new(caddyhttp.AutoHTTPSConfig)
508 - }
509 - if !sliceContains(srv.AutoHTTPS.Skip, addr.Host) {
510 - srv.AutoHTTPS.Skip = append(srv.AutoHTTPS.Skip, addr.Host)
503 + // if server only uses HTTPS port, auto-HTTPS will not apply
504 + if listenersUseAnyPortOtherThan(srv.Listen, httpPort) {
505 + // exclude any hosts that were defined explicitly with "http://"
506 + // in the key from automated cert management (issue #2998)
507 + if addr.Scheme == "http" && addr.Host != "" {
508 + if srv.AutoHTTPS == nil {
509 + srv.AutoHTTPS = new(caddyhttp.AutoHTTPSConfig)
510 + }
511 + if !sliceContains(srv.AutoHTTPS.Skip, addr.Host) {
512 + srv.AutoHTTPS.Skip = append(srv.AutoHTTPS.Skip, addr.Host)
513 + }
514 }
515 }
516 +
517 // we'll need to remember if the address qualifies for auto-HTTPS, so we
518 // can add a TLS conn policy if necessary
519 if addr.Scheme == "https" ||
@@ -1183,6 +1187,26 @@ func sliceContains(haystack []string, needle string) bool {
1187 return false
1188 }
1189
1190 +// listenersUseAnyPortOtherThan returns true if there are any
1191 +// listeners in addresses that use a port which is not otherPort.
1192 +// Mostly borrowed from unexported method in caddyhttp package.
1193 +func listenersUseAnyPortOtherThan(addresses []string, otherPort string) bool {
1194 + otherPortInt, err := strconv.Atoi(otherPort)
1195 + if err != nil {
1196 + return false
1197 + }
1198 + for _, lnAddr := range addresses {
1199 + laddrs, err := caddy.ParseNetworkAddress(lnAddr)
1200 + if err != nil {
1201 + continue
1202 + }
1203 + if uint(otherPortInt) > laddrs.EndPort || uint(otherPortInt) < laddrs.StartPort {
1204 + return true
1205 + }
1206 + }
1207 + return false
1208 +}
1209 +
1210 // specificity returns len(s) minus any wildcards (*) and
1211 // placeholders ({...}). Basically, it's a length count
1212 // that penalizes the use of wildcards and placeholders.
caddyconfig/httpcaddyfile/tlsapp.go
+9
@@ -40,6 +40,10 @@ func (st ServerType) buildTLSApp(
40 tlsApp := &caddytls.TLS{CertificatesRaw: make(caddy.ModuleMap)}
41 var certLoaders []caddytls.CertificateLoader
42
43 + httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
44 + if hp, ok := options["http_port"].(int); ok {
45 + httpPort = strconv.Itoa(hp)
46 + }
47 httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)
48 if hsp, ok := options["https_port"].(int); ok {
49 httpsPort = strconv.Itoa(hsp)
@@ -91,6 +95,11 @@ func (st ServerType) buildTLSApp(
95 }
96
97 for _, p := range pairings {
98 + // avoid setting up TLS automation policies for a server that is HTTP-only
99 + if !listenersUseAnyPortOtherThan(p.addresses, httpPort) {
100 + continue
101 + }
102 +
103 for _, sblock := range p.serverBlocks {
104 // get values that populate an automation policy for this block
105 ap, err := newBaseAutomationPolicy(options, warnings, true)
caddytest/integration/caddyfile_adapt/http_only_hostnames.txt new
+45
@@ -0,0 +1,45 @@
1 +# https://github.com/caddyserver/caddy/issues/3977
2 +http://* {
3 + respond "Hello, world!"
4 +}
5 +----------
6 +{
7 + "apps": {
8 + "http": {
9 + "servers": {
10 + "srv0": {
11 + "listen": [
12 + ":80"
13 + ],
14 + "routes": [
15 + {
16 + "match": [
17 + {
18 + "host": [
19 + "*"
20 + ]
21 + }
22 + ],
23 + "handle": [
24 + {
25 + "handler": "subroute",
26 + "routes": [
27 + {
28 + "handle": [
29 + {
30 + "body": "Hello, world!",
31 + "handler": "static_response"
32 + }
33 + ]
34 + }
35 + ]
36 + }
37 + ],
38 + "terminal": true
39 + }
40 + ]
41 + }
42 + }
43 + }
44 + }
45 +}
\ No newline at end of file