tls: Add insecure_disable_sni_matching subdirective (#3075)

* Disable StrictHostMatching for single server configs

* Add the insecure_disable_sni_matching directive

* Do not override insecure_disable_sni_matching

* Remove comment
This commit is contained in:
Daniel Santos 2020-02-25 16:04:59 -07:00 committed by GitHub
parent c953d17bcc
commit 4fbdd23283
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 16 additions and 18 deletions

View File

@ -251,7 +251,6 @@ func (h *httpContext) MakeServers() ([]caddy.Server, error) {
// 2) if QUIC is enabled, TLS ClientAuth is not, because // 2) if QUIC is enabled, TLS ClientAuth is not, because
// currently, QUIC does not support ClientAuth (TODO: // currently, QUIC does not support ClientAuth (TODO:
// revisit this when our QUIC implementation supports it) // revisit this when our QUIC implementation supports it)
// 3) if TLS ClientAuth is used, StrictHostMatching is on
var atLeastOneSiteLooksLikeProduction bool var atLeastOneSiteLooksLikeProduction bool
for _, cfg := range h.siteConfigs { for _, cfg := range h.siteConfigs {
// see if all the addresses (both sites and // see if all the addresses (both sites and
@ -292,12 +291,6 @@ func (h *httpContext) MakeServers() ([]caddy.Server, error) {
if QUIC { if QUIC {
return nil, fmt.Errorf("cannot enable TLS client authentication with QUIC, because QUIC does not yet support it") return nil, fmt.Errorf("cannot enable TLS client authentication with QUIC, because QUIC does not yet support it")
} }
// this must be enabled so that a client cannot connect
// using SNI for another site on this listener that
// does NOT require ClientAuth, and then send HTTP
// requests with the Host header of this site which DOES
// require client auth, thus bypassing it...
cfg.StrictHostMatching = true
} }
} }

View File

@ -442,11 +442,12 @@ func (s *Server) serveHTTP(w http.ResponseWriter, r *http.Request) (int, error)
r.URL = trimPathPrefix(r.URL, pathPrefix) r.URL = trimPathPrefix(r.URL, pathPrefix)
} }
// if not disabled via `insecure_disable_sni_matching`
// enforce strict host matching, which ensures that the SNI // enforce strict host matching, which ensures that the SNI
// value (if any), matches the Host header; essential for // value (if any), matches the Host header; essential for
// sites that rely on TLS ClientAuth sharing a port with // sites that rely on TLS ClientAuth sharing a port with
// sites that do not - if mismatched, close the connection // sites that do not - if mismatched, close the connection
if vhost.StrictHostMatching && r.TLS != nil && if !vhost.TLS.InsecureDisableSNIMatching && r.TLS != nil &&
strings.ToLower(r.TLS.ServerName) != strings.ToLower(hostname) { strings.ToLower(r.TLS.ServerName) != strings.ToLower(hostname) {
r.Close = true r.Close = true
log.Printf("[ERROR] %s - strict host matching: SNI (%s) and HTTP Host (%s) values differ", log.Printf("[ERROR] %s - strict host matching: SNI (%s) and HTTP Host (%s) values differ",

View File

@ -36,16 +36,6 @@ type SiteConfig struct {
// TLS configuration // TLS configuration
TLS *caddytls.Config TLS *caddytls.Config
// If true, the Host header in the HTTP request must
// match the SNI value in the TLS handshake (if any).
// This should be enabled whenever a site relies on
// TLS client authentication, for example; or any time
// you want to enforce that THIS site's TLS config
// is used and not the TLS config of any other site
// on the same listener. TODO: Check how relevant this
// is with TLS 1.3.
StrictHostMatching bool
// Uncompiled middleware stack // Uncompiled middleware stack
middleware []Middleware middleware []Middleware

View File

@ -62,6 +62,18 @@ type Config struct {
// client authentication is enabled // client authentication is enabled
ClientCerts []string ClientCerts []string
// Allow mismatched TLS SNI and Host header when using TLS client authentication
// If false (the default), the Host header in the HTTP request must
// match the SNI value in the TLS handshake (if any).
// This should be enabled whenever the TLS SNI and Host header
// in the HTTP request can be different, for example when doing mTLS with multiple servers
// and the upstream addresses do not match the HTTP request Host header.
// If a site relies on TLS client authentication or any time you want to enforce that THIS site's TLS config
// is used and not the TLS config of any other site
// on the same listener, set this to false.
// TODO: Check how relevant this is with TLS 1.3.
InsecureDisableSNIMatching bool
// Manual means user provides own certs and keys // Manual means user provides own certs and keys
Manual bool Manual bool

View File

@ -222,6 +222,8 @@ func setupTLS(c *caddy.Controller) error {
} }
config.ClientCerts = clientCertList[listStart:] config.ClientCerts = clientCertList[listStart:]
case "insecure_disable_sni_matching":
config.InsecureDisableSNIMatching = true
case "load": case "load":
c.Args(&loadDir) c.Args(&loadDir)
config.Manual = true config.Manual = true