diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b8cf14a..103b1076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - [#1489](https://github.com/oauth2-proxy/oauth2-proxy/pull/1489) Fix Docker Buildx push to include build version (@JoelSpeed) - [#1477](https://github.com/oauth2-proxy/oauth2-proxy/pull/1477) Remove provider documentation for `Microsoft Azure AD` (@omBratteng) - [#1509](https://github.com/oauth2-proxy/oauth2-proxy/pull/1509) Update LoginGovProvider ValidateSession to pass access_token in Header (@pksheldon4) +- [#1474](https://github.com/oauth2-proxy/oauth2-proxy/pull/1474) Support configuration of minimal acceptable TLS version (@polarctos) # V7.2.1 diff --git a/docs/docs/configuration/alpha_config.md b/docs/docs/configuration/alpha_config.md index f13ea131..a2af20d9 100644 --- a/docs/docs/configuration/alpha_config.md +++ b/docs/docs/configuration/alpha_config.md @@ -349,18 +349,20 @@ Server represents the configuration for an HTTP(S) server | ----- | ---- | ----------- | | `BindAddress` | _string_ | BindAddress is the address on which to serve traffic.
Leave blank or set to "-" to disable. | | `SecureBindAddress` | _string_ | SecureBindAddress is the address on which to serve secure traffic.
Leave blank or set to "-" to disable. | -| `TLS` | _[TLS](#tls)_ | TLS contains the information for loading the certificate and key for the
secure traffic. | +| `TLS` | _[TLS](#tls)_ | TLS contains the information for loading the certificate and key for the
secure traffic and further configuration for the TLS server. | ### TLS (**Appears on:** [Server](#server)) -TLS contains the information for loading a TLS certifcate and key. +TLS contains the information for loading a TLS certificate and key +as well as an optional minimal TLS version that is acceptable. | Field | Type | Description | | ----- | ---- | ----------- | | `Key` | _[SecretSource](#secretsource)_ | Key is the TLS key data to use.
Typically this will come from a file. | | `Cert` | _[SecretSource](#secretsource)_ | Cert is the TLS certificate data to use.
Typically this will come from a file. | +| `MinVersion` | _string_ | MinVersion is the minimal TLS version that is acceptable.
E.g. Set to "TLS1.3" to select TLS version 1.3 | ### Upstream diff --git a/docs/docs/configuration/overview.md b/docs/docs/configuration/overview.md index 6f623063..1b440114 100644 --- a/docs/docs/configuration/overview.md +++ b/docs/docs/configuration/overview.md @@ -191,6 +191,7 @@ An example [oauth2-proxy.cfg](https://github.com/oauth2-proxy/oauth2-proxy/blob/ | `--standard-logging-format` | string | Template for standard log lines | see [Logging Configuration](#logging-configuration) | | `--tls-cert-file` | string | path to certificate file | | | `--tls-key-file` | string | path to private key file | | +| `--tls-min-version` | string | minimum TLS version that is acceptable, either `"TLS1.2"` or `"TLS1.3"` | `"TLS1.2"` | | `--upstream` | string \| list | the http url(s) of the upstream endpoint, file:// paths for static files or `static://` for static response. Routing is based on the path | | | `--allowed-group` | string \| list | restrict logins to members of this group (may be given multiple times) | | | `--allowed-role` | string \| list | restrict logins to users with this role (may be given multiple times). Only works with the keycloak-oidc provider. | | diff --git a/docs/docs/configuration/tls.md b/docs/docs/configuration/tls.md index ef91ddf8..1efdc5fa 100644 --- a/docs/docs/configuration/tls.md +++ b/docs/docs/configuration/tls.md @@ -3,7 +3,11 @@ id: tls title: TLS Configuration --- -There are two recommended configurations. +There are two recommended configurations: +- [At OAuth2 Proxy](#terminate-tls-at-oauth2-proxy) +- [At Reverse Proxy](#terminate-tls-at-reverse-proxy-eg-nginx) + +### Terminate TLS at OAuth2 Proxy 1. Configure SSL Termination with OAuth2 Proxy by providing a `--tls-cert-file=/path/to/cert.pem` and `--tls-key-file=/path/to/cert.key`. @@ -22,7 +26,18 @@ There are two recommended configurations. --client-secret=... ``` -2. Configure SSL Termination with [Nginx](http://nginx.org/) (example config below), Amazon ELB, Google Cloud Platform Load Balancing, or .... +2. With this configuration approach the customization of the TLS settings is limited. + + The minimal acceptable TLS version can be set with `--tls-min-version=TLS1.3`. + The defaults set `TLS1.2` as the minimal version. + Regardless of the minimum version configured, `TLS1.3` is currently always used as the maximal version. + + The server side cipher suites are the defaults from [`crypto/tls`](https://pkg.go.dev/crypto/tls#CipherSuites) of + the currently used `go` version for building `oauth2-proxy`. + +### Terminate TLS at Reverse Proxy, e.g. Nginx + +1. Configure SSL Termination with [Nginx](http://nginx.org/) (example config below), Amazon ELB, Google Cloud Platform Load Balancing, or ... Because `oauth2-proxy` listens on `127.0.0.1:4180` by default, to listen on all interfaces (needed when using an external load balancer like Amazon ELB or Google Platform Load Balancing) use `--http-address="0.0.0.0:4180"` or @@ -55,7 +70,7 @@ There are two recommended configurations. } ``` - The command line to run `oauth2-proxy` in this configuration would look like this: +2. The command line to run `oauth2-proxy` in this configuration would look like this: ```bash ./oauth2-proxy \ diff --git a/pkg/apis/options/legacy_options.go b/pkg/apis/options/legacy_options.go index 3441fd41..3709f2e9 100644 --- a/pkg/apis/options/legacy_options.go +++ b/pkg/apis/options/legacy_options.go @@ -448,6 +448,7 @@ type LegacyServer struct { HTTPSAddress string `flag:"https-address" cfg:"https_address"` TLSCertFile string `flag:"tls-cert-file" cfg:"tls_cert_file"` TLSKeyFile string `flag:"tls-key-file" cfg:"tls_key_file"` + TLSMinVersion string `flag:"tls-min-version" cfg:"tls_min_version"` } func legacyServerFlagset() *pflag.FlagSet { @@ -461,6 +462,7 @@ func legacyServerFlagset() *pflag.FlagSet { flagSet.String("https-address", ":443", ": to listen on for HTTPS clients") flagSet.String("tls-cert-file", "", "path to certificate file") flagSet.String("tls-key-file", "", "path to private key file") + flagSet.String("tls-min-version", "", "minimal TLS version for HTTPS clients (either \"TLS1.2\" or \"TLS1.3\")") return flagSet } @@ -582,6 +584,7 @@ func (l LegacyServer) convert() (Server, Server) { Cert: &SecretSource{ FromFile: l.TLSCertFile, }, + MinVersion: l.TLSMinVersion, } // Preserve backwards compatibility, only run one server appServer.BindAddress = "" diff --git a/pkg/apis/options/legacy_options_test.go b/pkg/apis/options/legacy_options_test.go index ecf48494..064d9881 100644 --- a/pkg/apis/options/legacy_options_test.go +++ b/pkg/apis/options/legacy_options_test.go @@ -785,6 +785,7 @@ var _ = Describe("Legacy Options", func() { secureMetricsAddr = ":9443" crtPath = "tls.crt" keyPath = "tls.key" + minVersion = "TLS1.3" ) var tlsConfig = &TLS{ @@ -796,6 +797,12 @@ var _ = Describe("Legacy Options", func() { }, } + var tlsConfigMinVersion = &TLS{ + Cert: tlsConfig.Cert, + Key: tlsConfig.Key, + MinVersion: minVersion, + } + DescribeTable("should convert to app and metrics servers", func(in legacyServersTableInput) { appServer, metricsServer := in.legacyServer.convert() @@ -823,6 +830,19 @@ var _ = Describe("Legacy Options", func() { TLS: tlsConfig, }, }), + Entry("with TLS options specified with MinVersion", legacyServersTableInput{ + legacyServer: LegacyServer{ + HTTPAddress: insecureAddr, + HTTPSAddress: secureAddr, + TLSKeyFile: keyPath, + TLSCertFile: crtPath, + TLSMinVersion: minVersion, + }, + expectedAppServer: Server{ + SecureBindAddress: secureAddr, + TLS: tlsConfigMinVersion, + }, + }), Entry("with metrics HTTP and HTTPS addresses", legacyServersTableInput{ legacyServer: LegacyServer{ HTTPAddress: insecureAddr, diff --git a/pkg/apis/options/server.go b/pkg/apis/options/server.go index 5148366e..704e133e 100644 --- a/pkg/apis/options/server.go +++ b/pkg/apis/options/server.go @@ -11,11 +11,12 @@ type Server struct { SecureBindAddress string // TLS contains the information for loading the certificate and key for the - // secure traffic. + // secure traffic and further configuration for the TLS server. TLS *TLS } -// TLS contains the information for loading a TLS certifcate and key. +// TLS contains the information for loading a TLS certificate and key +// as well as an optional minimal TLS version that is acceptable. type TLS struct { // Key is the TLS key data to use. // Typically this will come from a file. @@ -24,4 +25,8 @@ type TLS struct { // Cert is the TLS certificate data to use. // Typically this will come from a file. Cert *SecretSource + + // MinVersion is the minimal TLS version that is acceptable. + // E.g. Set to "TLS1.3" to select TLS version 1.3 + MinVersion string } diff --git a/pkg/http/server.go b/pkg/http/server.go index e9a1d248..b44d5b10 100644 --- a/pkg/http/server.go +++ b/pkg/http/server.go @@ -91,7 +91,7 @@ func (s *server) setupTLSListener(opts Opts) error { } config := &tls.Config{ - MinVersion: tls.VersionTLS12, + MinVersion: tls.VersionTLS12, // default, override below MaxVersion: tls.VersionTLS13, NextProtos: []string{"http/1.1"}, } @@ -104,6 +104,17 @@ func (s *server) setupTLSListener(opts Opts) error { } config.Certificates = []tls.Certificate{cert} + if len(opts.TLS.MinVersion) > 0 { + switch opts.TLS.MinVersion { + case "TLS1.2": + config.MinVersion = tls.VersionTLS12 + case "TLS1.3": + config.MinVersion = tls.VersionTLS13 + default: + return errors.New("unknown TLS MinVersion config provided") + } + } + listenAddr := getListenAddress(opts.SecureBindAddress) listener, err := net.Listen("tcp", listenAddr) diff --git a/pkg/http/server_test.go b/pkg/http/server_test.go index 612ef9f7..0451fa71 100644 --- a/pkg/http/server_test.go +++ b/pkg/http/server_test.go @@ -233,6 +233,34 @@ var _ = Describe("Server", func() { expectHTTPListener: false, expectTLSListener: true, }), + Entry("with a valid https bind address, and valid TLS config with MinVersion", &newServerTableInput{ + opts: Opts{ + Handler: handler, + SecureBindAddress: "127.0.0.1:0", + TLS: &options.TLS{ + Key: &keyDataSource, + Cert: &certDataSource, + MinVersion: "TLS1.3", + }, + }, + expectedErr: nil, + expectHTTPListener: false, + expectTLSListener: true, + }), + Entry("with a valid https bind address, and invalid TLS config with unknown MinVersion", &newServerTableInput{ + opts: Opts{ + Handler: handler, + SecureBindAddress: "127.0.0.1:0", + TLS: &options.TLS{ + Key: &keyDataSource, + Cert: &certDataSource, + MinVersion: "TLS1.42", + }, + }, + expectedErr: errors.New("error setting up TLS listener: unknown TLS MinVersion config provided"), + expectHTTPListener: false, + expectTLSListener: true, + }), ) })