From d4f068db607e1feab55ff327c2b2ddb03a545728 Mon Sep 17 00:00:00 2001 From: JBD Date: Mon, 12 Jul 2021 19:19:41 -0700 Subject: [PATCH] Allow users to set min and max TLS versions (#3591) * Allow users to set min and max TLS versions Users want to be to choose the min and max versions they want to allow. Introduce two new settings to make the version range configurable. * Make linter happy --- config/configtls/README.md | 8 ++++++ config/configtls/configtls.go | 42 +++++++++++++++++++++++++++++- config/configtls/configtls_test.go | 21 +++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/config/configtls/README.md b/config/configtls/README.md index ea87db3c287..60be861dcf0 100644 --- a/config/configtls/README.md +++ b/config/configtls/README.md @@ -34,6 +34,12 @@ won't use TLS at all. - `insecure_skip_verify` (default = false): whether to skip verifying the certificate or not. +Minimum and maximum TLS version can be set: + +- `min_version` (default = "1.0"): Minimum acceptable TLS version. + +- `max_version` (default = "1.3"): Maximum acceptable TLS version. + How TLS/mTLS is configured depends on whether configuring the client or server. See below for examples. @@ -63,6 +69,8 @@ exporters: ca_file: server.crt cert_file: client.crt key_file: client.key + min_version: "1.1" + max_version: "1.2" otlp/insecure: endpoint: myserver.local:55690 insecure: true diff --git a/config/configtls/configtls.go b/config/configtls/configtls.go index 641971f2f7b..7b6c215d3b8 100644 --- a/config/configtls/configtls.go +++ b/config/configtls/configtls.go @@ -30,10 +30,20 @@ type TLSSetting struct { // For a server this verifies client certificates. If empty uses system root CA. // (optional) CAFile string `mapstructure:"ca_file"` + // Path to the TLS cert to use for TLS required connections. (optional) CertFile string `mapstructure:"cert_file"` + // Path to the TLS key to use for TLS required connections. (optional) KeyFile string `mapstructure:"key_file"` + + // MinVersion sets the minimum TLS version that is acceptable. + // If not set, TLS 1.0 is used. (optional) + MinVersion string `mapstructure:"min_version"` + + // MaxVersion sets the maximum TLS version that is acceptable. + // If not set, TLS 1.3 is used. (optional) + MaxVersion string `mapstructure:"max_version"` } // TLSClientSetting contains TLS configurations that are specific to client @@ -96,16 +106,28 @@ func (c TLSSetting) loadTLSConfig() (*tls.Config, error) { var certificates []tls.Certificate if c.CertFile != "" && c.KeyFile != "" { - tlsCert, err := tls.LoadX509KeyPair(filepath.Clean(c.CertFile), filepath.Clean(c.KeyFile)) + var tlsCert tls.Certificate + tlsCert, err = tls.LoadX509KeyPair(filepath.Clean(c.CertFile), filepath.Clean(c.KeyFile)) if err != nil { return nil, fmt.Errorf("failed to load TLS cert and key: %w", err) } certificates = append(certificates, tlsCert) } + minTLS, err := convertVersion(c.MinVersion) + if err != nil { + return nil, fmt.Errorf("invalid TLS min_version: %w", err) + } + maxTLS, err := convertVersion(c.MaxVersion) + if err != nil { + return nil, fmt.Errorf("invalid TLS max_version: %w", err) + } + return &tls.Config{ RootCAs: certPool, Certificates: certificates, + MinVersion: minTLS, + MaxVersion: maxTLS, }, nil } @@ -153,3 +175,21 @@ func (c TLSServerSetting) LoadTLSConfig() (*tls.Config, error) { } return tlsCfg, nil } + +func convertVersion(v string) (uint16, error) { + if v == "" { + return 0, nil // default + } + val, ok := tlsVersions[v] + if !ok { + return 0, fmt.Errorf("unsupported TLS version: %q", v) + } + return val, nil +} + +var tlsVersions = map[string]uint16{ + "1.0": tls.VersionTLS10, + "1.1": tls.VersionTLS11, + "1.2": tls.VersionTLS12, + "1.3": tls.VersionTLS13, +} diff --git a/config/configtls/configtls_test.go b/config/configtls/configtls_test.go index 9ebc88fd213..b0e1c4cfc46 100644 --- a/config/configtls/configtls_test.go +++ b/config/configtls/configtls_test.go @@ -107,6 +107,27 @@ func TestOptionsToConfig(t *testing.T) { CAFile: "testdata/testCA.pem", }, }, + { + name: "should pass with valid min and max version", + options: TLSSetting{ + MinVersion: "1.1", + MaxVersion: "1.2", + }, + }, + { + name: "should pass with invalid min", + options: TLSSetting{ + MinVersion: "1.7", + }, + expectError: "invalid TLS min_", + }, + { + name: "should pass with invalid max", + options: TLSSetting{ + MaxVersion: "1.7", + }, + expectError: "invalid TLS max_", + }, } for _, test := range tests {