summaryrefslogtreecommitdiff
path: root/modules/caddyhttp
diff options
context:
space:
mode:
authorAlexandre Stein <astein58@gmail.com>2019-09-03 17:35:36 +0200
committerMatt Holt <mholt@users.noreply.github.com>2019-09-03 09:35:36 -0600
commit50961ecc77eb7e6a33f823da1d9eea6554a14b43 (patch)
treeddab36b2122e6b5bbacb8c2b5a45731e74f0696e /modules/caddyhttp
parent8e821b5039bd6983814a6b1d11894a649c44f74a (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.go22
-rw-r--r--modules/caddyhttp/server.go11
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 {