diff --git a/caddyconfig/httpcaddyfile/tlsapp.go b/caddyconfig/httpcaddyfile/tlsapp.go index 240cb02d..3d32b4f7 100644 --- a/caddyconfig/httpcaddyfile/tlsapp.go +++ b/caddyconfig/httpcaddyfile/tlsapp.go @@ -44,41 +44,32 @@ func (st ServerType) buildTLSApp( if hp, ok := options["http_port"].(int); ok { httpPort = strconv.Itoa(hp) } - httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort) - if hsp, ok := options["https_port"].(int); ok { - httpsPort = strconv.Itoa(hsp) - } autoHTTPS := "on" if ah, ok := options["auto_https"].(string); ok { autoHTTPS = ah } - // count how many server blocks have a TLS-enabled key with - // no host, and find all hosts that share a server block with - // a hostless key, so that they don't get forgotten/omitted - // by auto-HTTPS (since they won't appear in route matchers) - var serverBlocksWithTLSHostlessKey int + // find all hosts that share a server block with a hostless + // key, so that they don't get forgotten/omitted by auto-HTTPS + // (since they won't appear in route matchers) httpsHostsSharedWithHostlessKey := make(map[string]struct{}) - for _, pair := range pairings { - for _, sb := range pair.serverBlocks { - for _, addr := range sb.keys { - if addr.Host == "" { - // this address has no hostname, but if it's explicitly set - // to HTTPS, then we need to count it as being TLS-enabled - if addr.Scheme == "https" || addr.Port == httpsPort { - serverBlocksWithTLSHostlessKey++ - } - // this server block has a hostless key, now - // go through and add all the hosts to the set - for _, otherAddr := range sb.keys { - if otherAddr.Original == addr.Original { - continue - } - if otherAddr.Host != "" && otherAddr.Scheme != "http" && otherAddr.Port != httpPort { - httpsHostsSharedWithHostlessKey[otherAddr.Host] = struct{}{} + if autoHTTPS != "off" { + for _, pair := range pairings { + for _, sb := range pair.serverBlocks { + for _, addr := range sb.keys { + if addr.Host == "" { + // this server block has a hostless key, now + // go through and add all the hosts to the set + for _, otherAddr := range sb.keys { + if otherAddr.Original == addr.Original { + continue + } + if otherAddr.Host != "" && otherAddr.Scheme != "http" && otherAddr.Port != httpPort { + httpsHostsSharedWithHostlessKey[otherAddr.Host] = struct{}{} + } } + break } - break } } } @@ -138,6 +129,19 @@ func (st ServerType) buildTLSApp( issuers = append(issuers, issuerVal.Value.(certmagic.Issuer)) } if ap == catchAllAP && !reflect.DeepEqual(ap.Issuers, issuers) { + // this more correctly implements an error check that was removed + // below; try it with this config: + // + // :443 { + // bind 127.0.0.1 + // } + // + // :443 { + // bind ::1 + // tls { + // issuer acme + // } + // } return nil, warnings, fmt.Errorf("automation policy from site block is also default/catch-all policy because of key without hostname, and the two are in conflict: %#v != %#v", ap.Issuers, issuers) } ap.Issuers = issuers @@ -180,29 +184,25 @@ func (st ServerType) buildTLSApp( } } - // first make sure this block is allowed to create an automation policy; - // doing so is forbidden if it has a key with no host (i.e. ":443") + // we used to ensure this block is allowed to create an automation policy; + // doing so was forbidden if it has a key with no host (i.e. ":443") // and if there is a different server block that also has a key with no // host -- since a key with no host matches any host, we need its // associated automation policy to have an empty Subjects list, i.e. no // host filter, which is indistinguishable between the two server blocks // because automation is not done in the context of a particular server... // this is an example of a poor mapping from Caddyfile to JSON but that's - // the least-leaky abstraction I could figure out - if len(sblockHosts) == 0 { - if serverBlocksWithTLSHostlessKey > 1 { - // this server block and at least one other has a key with no host, - // making the two indistinguishable; it is misleading to define such - // a policy within one server block since it actually will apply to - // others as well - return nil, warnings, fmt.Errorf("cannot make a TLS automation policy from a server block that has a host-less address when there are other TLS-enabled server block addresses lacking a host") - } - if catchAllAP == nil { - // this server block has a key with no hosts, but there is not yet - // a catch-all automation policy (probably because no global options - // were set), so this one becomes it - catchAllAP = ap - } + // the least-leaky abstraction I could figure out -- however, this check + // was preventing certain listeners, like those provided by plugins, from + // being used as desired (see the Tailscale listener plugin), so I removed + // the check: and I think since I originally wrote the check I added a new + // check above which *properly* detects this ambiguity without breaking the + // listener plugin; see the check above with a commented example config + if len(sblockHosts) == 0 && catchAllAP == nil { + // this server block has a key with no hosts, but there is not yet + // a catch-all automation policy (probably because no global options + // were set), so this one becomes it + catchAllAP = ap } // associate our new automation policy with this server block's hosts diff --git a/caddytest/integration/reverseproxy_test.go b/caddytest/integration/reverseproxy_test.go index 049c7fd2..f7b19672 100644 --- a/caddytest/integration/reverseproxy_test.go +++ b/caddytest/integration/reverseproxy_test.go @@ -436,8 +436,8 @@ func TestReverseProxyHealthCheck(t *testing.T) { health_uri /health health_port 2021 - health_interval 2s - health_timeout 5s + health_interval 10ms + health_timeout 100ms } } `, "caddyfile") diff --git a/go.mod b/go.mod index afcd268b..0c7a3766 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/google/uuid v1.3.0 github.com/klauspost/compress v1.15.11 github.com/klauspost/cpuid/v2 v2.1.1 - github.com/lucas-clemente/quic-go v0.29.1 + github.com/lucas-clemente/quic-go v0.29.2 github.com/mholt/acmez v1.0.4 github.com/prometheus/client_golang v1.12.2 github.com/smallstep/certificates v0.22.1 @@ -87,8 +87,8 @@ require ( github.com/libdns/libdns v0.2.1 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/marten-seemann/qpack v0.2.1 // indirect - github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect + github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/mattn/go-colorable v0.1.8 // indirect github.com/mattn/go-isatty v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect diff --git a/go.sum b/go.sum index 1ca18c9d..ddad26b4 100644 --- a/go.sum +++ b/go.sum @@ -423,18 +423,18 @@ github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis= github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lucas-clemente/quic-go v0.29.1 h1:Z+WMJ++qMLhvpFkRZA+jl3BTxUjm415YBmWanXB8zP0= -github.com/lucas-clemente/quic-go v0.29.1/go.mod h1:CTcNfLYJS2UuRNB+zcNlgvkjBhxX6Hm3WUxxAQx2mgE= +github.com/lucas-clemente/quic-go v0.29.2 h1:O8Mt0O6LpvEW+wfC40vZdcw0DngwYzoxq5xULZNzSI8= +github.com/lucas-clemente/quic-go v0.29.2/go.mod h1:g6/h9YMmLuU54tL1gW25uIi3VlBp3uv+sBihplIuskE= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= -github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU= -github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= +github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI= +github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= +github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE= +github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index 60fc3c38..7a244d2c 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -500,14 +500,12 @@ func (s *Server) serveHTTP3(addr caddy.NetworkAddress, tlsCfg *tls.Config) error switch addr.Network { case "unix": addr.Network = "unixgram" - case "tcp": - addr.Network = "udp" case "tcp4": addr.Network = "udp4" case "tcp6": addr.Network = "udp6" default: - return fmt.Errorf("unsure what network to use for HTTP/3 given network type: %s", addr.Network) + addr.Network = "udp" // TODO: Maybe a better default is to not enable HTTP/3 if we do not know the network? } lnAny, err := addr.Listen(s.ctx, 0, net.ListenConfig{})