From c69167db555f5b711194a9cece6995a2846a340d Mon Sep 17 00:00:00 2001 From: Nick Cabatoff Date: Mon, 29 Mar 2021 13:57:03 -0400 Subject: [PATCH 1/3] Add support for tlx_max_version in listener config. --- internalshared/configutil/listener.go | 1 + internalshared/listenerutil/listener.go | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/internalshared/configutil/listener.go b/internalshared/configutil/listener.go index de02d8827f67..bd7c905a29d1 100644 --- a/internalshared/configutil/listener.go +++ b/internalshared/configutil/listener.go @@ -43,6 +43,7 @@ type Listener struct { TLSCertFile string `hcl:"tls_cert_file"` TLSKeyFile string `hcl:"tls_key_file"` TLSMinVersion string `hcl:"tls_min_version"` + TLSMaxVersion string `hcl:"tls_max_version"` TLSCipherSuites []uint16 `hcl:"-"` TLSCipherSuitesRaw string `hcl:"tls_cipher_suites"` TLSPreferServerCipherSuites bool `hcl:"-"` diff --git a/internalshared/listenerutil/listener.go b/internalshared/listenerutil/listener.go index c72342c22bc2..e1786b96148d 100644 --- a/internalshared/listenerutil/listener.go +++ b/internalshared/listenerutil/listener.go @@ -111,12 +111,25 @@ PASSPHRASECORRECT: l.TLSMinVersion = "tls12" } + if l.TLSMaxVersion == "" { + l.TLSMaxVersion = "tls13" + } + var ok bool tlsConf.MinVersion, ok = tlsutil.TLSLookup[l.TLSMinVersion] if !ok { return nil, nil, fmt.Errorf("'tls_min_version' value %q not supported, please specify one of [tls10,tls11,tls12,tls13]", l.TLSMinVersion) } + tlsConf.MaxVersion, ok = tlsutil.TLSLookup[l.TLSMaxVersion] + if !ok { + return nil, nil, fmt.Errorf("'tls_max_version' value %q not supported, please specify one of [tls10,tls11,tls12,tls13]", l.TLSMaxVersion) + } + + if tlsConf.MaxVersion < tlsConf.MinVersion { + return nil, nil, fmt.Errorf("'tls_max_version' must be greater than or equal to 'tls_min_version'") + } + if len(l.TLSCipherSuites) > 0 { // HTTP/2 with TLS 1.2 blacklists several cipher suites. // https://tools.ietf.org/html/rfc7540#appendix-A From 295d52170c7d73aa00b07528623ea03335fac6c2 Mon Sep 17 00:00:00 2001 From: Nick Cabatoff Date: Mon, 29 Mar 2021 14:00:29 -0400 Subject: [PATCH 2/3] Add changelog and config test. --- changelog/11226.txt | 3 +++ command/server/config_test_helpers.go | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 changelog/11226.txt diff --git a/changelog/11226.txt b/changelog/11226.txt new file mode 100644 index 000000000000..299adac430eb --- /dev/null +++ b/changelog/11226.txt @@ -0,0 +1,3 @@ +```changelog:enhancement +core: Add tls_max_version listener config option. +``` diff --git a/command/server/config_test_helpers.go b/command/server/config_test_helpers.go index cdfde7df3290..f548d32d0fef 100644 --- a/command/server/config_test_helpers.go +++ b/command/server/config_test_helpers.go @@ -707,6 +707,7 @@ listener "tcp" { tls_key_file = "./certs/server.key" tls_client_ca_file = "./certs/rootca.crt" tls_min_version = "tls12" + tls_max_version = "tls13" tls_require_and_verify_client_cert = true tls_disable_client_certs = true }`)) @@ -737,6 +738,7 @@ listener "tcp" { TLSKeyFile: "./certs/server.key", TLSClientCAFile: "./certs/rootca.crt", TLSMinVersion: "tls12", + TLSMaxVersion: "tls13", TLSRequireAndVerifyClientCert: true, TLSDisableClientCerts: true, }, From 428c740c1d5840d9f11577fa5e51f6e707040bb2 Mon Sep 17 00:00:00 2001 From: Nick Cabatoff Date: Mon, 29 Mar 2021 14:14:40 -0400 Subject: [PATCH 3/3] Add test for TLS version. --- command/server/listener_tcp_test.go | 24 +++++++++++++++++++----- command/server/listener_test.go | 5 ++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/command/server/listener_tcp_test.go b/command/server/listener_tcp_test.go index c503d427e801..12e0c7dcb710 100644 --- a/command/server/listener_tcp_test.go +++ b/command/server/listener_tcp_test.go @@ -28,7 +28,7 @@ func TestTCPListener(t *testing.T) { return net.Dial("tcp", ln.Addr().String()) } - testListenerImpl(t, ln, connFn, "") + testListenerImpl(t, ln, connFn, "", 0) } // TestTCPListener_tls tests TLS generally @@ -86,7 +86,7 @@ func TestTCPListener_tls(t *testing.T) { } } - testListenerImpl(t, ln, connFn(true), "foo.example.com") + testListenerImpl(t, ln, connFn(true), "foo.example.com", 0) ln, _, _, err = tcpListenerFactory(&configutil.Listener{ Address: "127.0.0.1:0", @@ -111,7 +111,7 @@ func TestTCPListener_tls(t *testing.T) { t.Fatalf("err: %s", err) } - testListenerImpl(t, ln, connFn(false), "foo.example.com") + testListenerImpl(t, ln, connFn(false), "foo.example.com", 0) } func TestTCPListener_tls13(t *testing.T) { @@ -169,7 +169,7 @@ func TestTCPListener_tls13(t *testing.T) { } } - testListenerImpl(t, ln, connFn(true), "foo.example.com") + testListenerImpl(t, ln, connFn(true), "foo.example.com", tls.VersionTLS13) ln, _, _, err = tcpListenerFactory(&configutil.Listener{ Address: "127.0.0.1:0", @@ -196,5 +196,19 @@ func TestTCPListener_tls13(t *testing.T) { t.Fatalf("err: %s", err) } - testListenerImpl(t, ln, connFn(false), "foo.example.com") + testListenerImpl(t, ln, connFn(false), "foo.example.com", tls.VersionTLS13) + + ln, _, _, err = tcpListenerFactory(&configutil.Listener{ + Address: "127.0.0.1:0", + TLSCertFile: wd + "reload_foo.pem", + TLSKeyFile: wd + "reload_foo.key", + TLSDisableClientCerts: true, + TLSClientCAFile: wd + "reload_ca.pem", + TLSMaxVersion: "tls12", + }, nil, cli.NewMockUi()) + if err != nil { + t.Fatalf("err: %s", err) + } + + testListenerImpl(t, ln, connFn(false), "foo.example.com", tls.VersionTLS12) } diff --git a/command/server/listener_test.go b/command/server/listener_test.go index e7fb4d3dc84c..eac7c221ef99 100644 --- a/command/server/listener_test.go +++ b/command/server/listener_test.go @@ -10,7 +10,7 @@ import ( type testListenerConnFn func(net.Listener) (net.Conn, error) -func testListenerImpl(t *testing.T, ln net.Listener, connFn testListenerConnFn, certName string) { +func testListenerImpl(t *testing.T, ln net.Listener, connFn testListenerConnFn, certName string, expectedVersion uint16) { serverCh := make(chan net.Conn, 1) go func() { server, err := ln.Accept() @@ -31,6 +31,9 @@ func testListenerImpl(t *testing.T, ln net.Listener, connFn testListenerConnFn, if certName != "" { tlsConn := client.(*tls.Conn) + if expectedVersion != 0 && tlsConn.ConnectionState().Version != expectedVersion { + t.Fatalf("expected version %d, got %d", expectedVersion, tlsConn.ConnectionState().Version) + } if len(tlsConn.ConnectionState().PeerCertificates) != 1 { t.Fatalf("err: number of certs too long") }