summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/reverseproxy
diff options
context:
space:
mode:
authorKiss Károly Pál <kiss.karoly.pal@gmail.com>2022-06-15 05:53:05 +0200
committerGitHub <noreply@github.com>2022-06-14 21:53:05 -0600
commitc82fe91104efbbe62826510579ea57fd54c55f8c (patch)
tree2e9acfb95be15b3c215c6180ea589b3d6c18c4b4 /modules/caddyhttp/reverseproxy
parentf9b42c37723ba6fbbfc31c61119fc42963770ce9 (diff)
reverseproxy: Dynamic ServerName for TLS upstreams (#4836)
* Make reverse proxy TLS server name replaceable for SNI upstreams. * Reverted previous TLS server name replacement, and implemented thread safe version. * Move TLS servername replacement into it's own function * Moved SNI servername replacement into httptransport. * Solve issue when dynamic upstreams use wrong protocol upstream. * Revert previous commit. Old commit was: Solve issue when dynamic upstreams use wrong protocol upstream. Id: 3c9806ccb63e66bdcac8e1ed4520c9d135cb011d Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
Diffstat (limited to 'modules/caddyhttp/reverseproxy')
-rw-r--r--modules/caddyhttp/reverseproxy/httptransport.go41
1 files changed, 39 insertions, 2 deletions
diff --git a/modules/caddyhttp/reverseproxy/httptransport.go b/modules/caddyhttp/reverseproxy/httptransport.go
index 8bce580..eefc04a 100644
--- a/modules/caddyhttp/reverseproxy/httptransport.go
+++ b/modules/caddyhttp/reverseproxy/httptransport.go
@@ -25,6 +25,7 @@ import (
"net/http"
"os"
"reflect"
+ "strings"
"time"
"github.com/caddyserver/caddy/v2"
@@ -242,9 +243,45 @@ func (h *HTTPTransport) NewTransport(ctx caddy.Context) (*http.Transport, error)
return rt, nil
}
+// replaceTLSServername checks TLS servername to see if it needs replacing
+// if it does need replacing, it creates a new cloned HTTPTransport object to avoid any races
+// and does the replacing of the TLS servername on that and returns the new object
+// if no replacement is necessary it returns the original
+func (h *HTTPTransport) replaceTLSServername(repl *caddy.Replacer) *HTTPTransport {
+ // check whether we have TLS and need to replace the servername in the TLSClientConfig
+ if h.TLSEnabled() && strings.Contains(h.TLS.ServerName, "{") {
+ // make a new h, "copy" the parts we don't need to touch, add a new *tls.Config and replace servername
+ newtransport := &HTTPTransport{
+ Resolver: h.Resolver,
+ TLS: h.TLS,
+ KeepAlive: h.KeepAlive,
+ Compression: h.Compression,
+ MaxConnsPerHost: h.MaxConnsPerHost,
+ DialTimeout: h.DialTimeout,
+ FallbackDelay: h.FallbackDelay,
+ ResponseHeaderTimeout: h.ResponseHeaderTimeout,
+ ExpectContinueTimeout: h.ExpectContinueTimeout,
+ MaxResponseHeaderSize: h.MaxResponseHeaderSize,
+ WriteBufferSize: h.WriteBufferSize,
+ ReadBufferSize: h.ReadBufferSize,
+ Versions: h.Versions,
+ Transport: h.Transport.Clone(),
+ h2cTransport: h.h2cTransport,
+ }
+ newtransport.Transport.TLSClientConfig.ServerName = repl.ReplaceAll(newtransport.Transport.TLSClientConfig.ServerName, "")
+ return newtransport
+ }
+
+ return h
+}
+
// RoundTrip implements http.RoundTripper.
func (h *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
- h.SetScheme(req)
+ // Try to replace TLS servername if needed
+ repl := req.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
+ transport := h.replaceTLSServername(repl)
+
+ transport.SetScheme(req)
// if H2C ("HTTP/2 over cleartext") is enabled and the upstream request is
// HTTP without TLS, use the alternate H2C-capable transport instead
@@ -252,7 +289,7 @@ func (h *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return h.h2cTransport.RoundTrip(req)
}
- return h.Transport.RoundTrip(req)
+ return transport.Transport.RoundTrip(req)
}
// SetScheme ensures that the outbound request req