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
// currently, QUIC does not support ClientAuth (TODO:
// revisit this when our QUIC implementation supports it)
// 3) if TLS ClientAuth is used, StrictHostMatching is on
var atLeastOneSiteLooksLikeProduction bool
for _, cfg := range h.siteConfigs {
// see if all the addresses (both sites and
@ -292,12 +291,6 @@ func (h *httpContext) MakeServers() ([]caddy.Server, error) {
if QUIC {
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)
}
// if not disabled via `insecure_disable_sni_matching`
// enforce strict host matching, which ensures that the SNI
// value (if any), matches the Host header; essential for
// sites that rely on TLS ClientAuth sharing a port with
// 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) {
r.Close = true
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 *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
middleware []Middleware

View file

@ -62,6 +62,18 @@ type Config struct {
// client authentication is enabled
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 bool

View file

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