diff options
author | Alexandre Stein <astein58@gmail.com> | 2019-09-03 17:35:36 +0200 |
---|---|---|
committer | Matt Holt <mholt@users.noreply.github.com> | 2019-09-03 09:35:36 -0600 |
commit | 50961ecc77eb7e6a33f823da1d9eea6554a14b43 (patch) | |
tree | ddab36b2122e6b5bbacb8c2b5a45731e74f0696e /modules/caddyhttp | |
parent | 8e821b5039bd6983814a6b1d11894a649c44f74a (diff) |
Initial implementation of TLS client authentication (#2731)
* Add support for client TLS authentication
Signed-off-by: Alexandre Stein <alexandre_stein@interlab-net.com>
* make and use client authentication struct
* force StrictSNIHost if TLSConnPolicies is not empty
* Implement leafs verification
* Fixes issue when using multiple verification
* applies the comments from maintainers
* Apply comment
* Refactor/cleanup initial TLS client auth implementation
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r-- | modules/caddyhttp/caddyhttp.go | 22 | ||||
-rw-r--r-- | modules/caddyhttp/server.go | 11 |
2 files changed, 25 insertions, 8 deletions
diff --git a/modules/caddyhttp/caddyhttp.go b/modules/caddyhttp/caddyhttp.go index b4b1ec6..6d8e921 100644 --- a/modules/caddyhttp/caddyhttp.go +++ b/modules/caddyhttp/caddyhttp.go @@ -75,6 +75,15 @@ func (app *App) Provision(ctx caddy.Context) error { srv.AutoHTTPS = new(AutoHTTPSConfig) } + // disallow TLS client auth bypass which could + // otherwise be exploited by sending an unprotected + // SNI value during TLS handshake, then a protected + // Host header during HTTP request later on that + // connection + if srv.hasTLSClientAuth() { + srv.StrictSNIHost = true + } + // TODO: Test this function to ensure these replacements are performed for i := range srv.Listen { srv.Listen[i] = repl.ReplaceAll(srv.Listen[i], "") @@ -159,8 +168,7 @@ func (app *App) Start() error { return fmt.Errorf("%s: listening on %s: %v", network, addr, err) } - // enable HTTP/2 (and support for solving the - // TLS-ALPN ACME challenge) by default + // enable HTTP/2 by default for _, pol := range srv.TLSConnPolicies { if len(pol.ALPN) == 0 { pol.ALPN = append(pol.ALPN, defaultALPN...) @@ -294,11 +302,11 @@ func (app *App) automaticHTTPS() error { return fmt.Errorf("%s: managing certificate for %s: %s", srvName, domains, err) } - // tell the server to use TLS by specifying a TLS - // connection policy (which supports HTTP/2 and the - // TLS-ALPN ACME challenge as well) - srv.TLSConnPolicies = caddytls.ConnectionPolicies{ - {ALPN: defaultALPN}, + // tell the server to use TLS if it is not already doing so + if srv.TLSConnPolicies == nil { + srv.TLSConnPolicies = caddytls.ConnectionPolicies{ + &caddytls.ConnectionPolicy{ALPN: defaultALPN}, + } } if srv.AutoHTTPS.DisableRedir { diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index f820f71..c1d2683 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -40,7 +40,7 @@ type Server struct { TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies,omitempty"` AutoHTTPS *AutoHTTPSConfig `json:"automatic_https,omitempty"` MaxRehandles *int `json:"max_rehandles,omitempty"` - StrictSNIHost bool `json:"strict_sni_host,omitempty"` // TODO: see if we can turn this on by default when clientauth is configured + StrictSNIHost bool `json:"strict_sni_host,omitempty"` tlsApp *caddytls.TLS } @@ -181,6 +181,15 @@ func (s *Server) listenersUseAnyPortOtherThan(otherPort int) bool { return false } +func (s *Server) hasTLSClientAuth() bool { + for _, cp := range s.TLSConnPolicies { + if cp.Active() { + return true + } + } + return false +} + // AutoHTTPSConfig is used to disable automatic HTTPS // or certain aspects of it for a specific server. type AutoHTTPSConfig struct { |