diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md index 99a62d28e..53e4c1e33 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## vUNRELEASED + +### New + +- Add ability to override HTTPS backend's TLS Server Name. [GH-297](https://github.com/pomerium/pomerium/pull/297) + ## v0.3.0 ### New diff --git a/docs/docs/reference/reference.md b/docs/docs/reference/reference.md index a53a803b1..e958407a0 100644 --- a/docs/docs/reference/reference.md +++ b/docs/docs/reference/reference.md @@ -355,6 +355,14 @@ If set, enables proxying of websocket connections. TLS Skip Verification controls whether a client verifies the server's certificate chain and host name. If enabled, TLS accepts any certificate presented by the server and any host name in that certificate. In this mode, TLS is susceptible to man-in-the-middle attacks. This should be used only for testing. +### TLS Server Name + +- Config File Key: `tls_server_name` +- Type: `string` +- Optional + +TLS Server Name overrides the hostname you specified in the `to` field. If set, this server name will be used to verify server side certificate. This is useful when the backend of your service is an HTTPS server with valid certificate, but you want to communicate via an internal hostname or IP address. + ### TLS Custom Certificate Authority - Config File Key: `tls_custom_ca` or `tls_custom_ca_file` diff --git a/internal/config/policy.go b/internal/config/policy.go index 830ac021d..fb81e3000 100644 --- a/internal/config/policy.go +++ b/internal/config/policy.go @@ -46,6 +46,12 @@ type Policy struct { // This should be used only for testing. TLSSkipVerify bool `mapstructure:"tls_skip_verify" yaml:"tls_skip_verify"` + // TLSServerName overrides the hostname in the `to` field. This is useful + // if your backend is an HTTPS server with a valid certificate, but you + // want to communicate to the backend with an internal hostname (e.g. + // Docker container name). + TLSServerName string `mapstructure:"tls_server_name" yaml:"tls_server_name"` + // TLSCustomCA defines the root certificate to use with a given // route when verifying server certificates. TLSCustomCA string `mapstructure:"tls_custom_ca" yaml:"tls_custom_ca"` diff --git a/internal/config/policy_test.go b/internal/config/policy_test.go index cfe3cda81..e59370fd1 100644 --- a/internal/config/policy_test.go +++ b/internal/config/policy_test.go @@ -32,6 +32,7 @@ func Test_Validate(t *testing.T) { {"good client certificate files", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientCertFile: "testdata/example-cert.pem", TLSClientKeyFile: "testdata/example-key.pem"}, false}, {"bad certificate file", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientCertFile: "testdata/example-cert-404.pem", TLSClientKeyFile: "testdata/example-key.pem"}, true}, {"bad key file", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientCertFile: "testdata/example-cert.pem", TLSClientKeyFile: "testdata/example-key-404.pem"}, true}, + {"good tls server name", Policy{From: "https://httpbin.corp.example", To: "https://internal-host-name", TLSServerName: "httpbin.corp.notatld"}, false}, } for _, tt := range tests { diff --git a/proxy/proxy.go b/proxy/proxy.go index 026ab50d3..b16b5f5e3 100755 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -186,6 +186,12 @@ func (p *Proxy) UpdatePolicies(opts *config.Options) error { log.Debug().Str("to", policy.Source.String()).Msg("proxy: client certs enabled") } + if policy.TLSServerName != "" { + tlsClientConfig.ServerName = policy.TLSServerName + isCustomClientConfig = true + log.Debug().Str("to", policy.Source.String()).Msgf("proxy: tls hostname override to: %s", policy.TLSServerName) + } + // We avoid setting a custom client config unless we have to as // if TLSClientConfig is nil, the default configuration is used. if isCustomClientConfig {