diff --git a/agent/config/runtime.go b/agent/config/runtime.go
index 4d86191931..d18fcfee65 100644
--- a/agent/config/runtime.go
+++ b/agent/config/runtime.go
@@ -1423,7 +1423,8 @@ type RuntimeConfig struct {
TLSCipherSuites []uint16
// TLSMinVersion is used to set the minimum TLS version used for TLS
- // connections. Should be either "tls10", "tls11", or "tls12".
+ // connections. Should be either "tls10", "tls11", "tls12" or "tls13".
+ // Defaults to tls12.
//
// hcl: tls_min_version = string
TLSMinVersion string
diff --git a/tlsutil/config.go b/tlsutil/config.go
index 36046ee66a..86707abd0f 100644
--- a/tlsutil/config.go
+++ b/tlsutil/config.go
@@ -4,15 +4,17 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
- "github.com/hashicorp/consul/logging"
- "github.com/hashicorp/go-hclog"
"io/ioutil"
"net"
"os"
"path/filepath"
+ "sort"
"strings"
"sync"
"time"
+
+ "github.com/hashicorp/consul/logging"
+ "github.com/hashicorp/go-hclog"
)
// DCWrapper is a function that is used to wrap a non-TLS connection
@@ -30,8 +32,12 @@ var TLSLookup = map[string]uint16{
"tls10": tls.VersionTLS10,
"tls11": tls.VersionTLS11,
"tls12": tls.VersionTLS12,
+ "tls13": tls.VersionTLS13,
}
+// TLSVersions has all the keys from the map above.
+var TLSVersions = strings.Join(tlsVersions(), ", ")
+
// Config used to create tls.Config
type Config struct {
// VerifyIncoming is used to verify the authenticity of incoming
@@ -120,6 +126,17 @@ type Config struct {
AutoEncryptTLS bool
}
+func tlsVersions() []string {
+ versions := []string{}
+ for v := range TLSLookup {
+ if v != "" {
+ versions = append(versions, v)
+ }
+ }
+ sort.Strings(versions)
+ return versions
+}
+
// KeyPair is used to open and parse a certificate and key file
func (c *Config) KeyPair() (*tls.Certificate, error) {
return loadKeyPair(c.CertFile, c.KeyFile)
@@ -323,7 +340,7 @@ func (c *Configurator) check(config Config, pool *x509.CertPool, cert *tls.Certi
// Check if a minimum TLS version was set
if config.TLSMinVersion != "" {
if _, ok := TLSLookup[config.TLSMinVersion]; !ok {
- return fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [tls10,tls11,tls12]", config.TLSMinVersion)
+ return fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [%s]", config.TLSMinVersion, TLSVersions)
}
}
diff --git a/tlsutil/config_test.go b/tlsutil/config_test.go
index 72a8aa8746..51e8b25aed 100644
--- a/tlsutil/config_test.go
+++ b/tlsutil/config_test.go
@@ -360,9 +360,6 @@ func TestConfigurator_ErrorPropagation(t *testing.T) {
{Config{}, false, false}, // 1
{Config{TLSMinVersion: "tls9"}, true, false}, // 1
{Config{TLSMinVersion: ""}, false, false}, // 2
- {Config{TLSMinVersion: "tls10"}, false, false}, // 3
- {Config{TLSMinVersion: "tls11"}, false, false}, // 4
- {Config{TLSMinVersion: "tls12"}, false, false}, // 5
{Config{VerifyOutgoing: true, CAFile: "", CAPath: ""}, true, false}, // 6
{Config{VerifyOutgoing: false, CAFile: "", CAPath: ""}, false, false}, // 7
{Config{VerifyOutgoing: false, CAFile: cafile, CAPath: ""},
@@ -390,6 +387,9 @@ func TestConfigurator_ErrorPropagation(t *testing.T) {
{Config{CAFile: "bogus"}, true, true}, // 21
{Config{CAPath: "bogus"}, true, true}, // 22
}
+ for _, v := range tlsVersions() {
+ variants = append(variants, variant{Config{TLSMinVersion: v}, false, false})
+ }
c := Configurator{autoEncrypt: &autoEncrypt{}, manual: &manual{}}
for i, v := range variants {
@@ -590,8 +590,7 @@ func TestConfigurator_CommonTLSConfigTLSMinVersion(t *testing.T) {
require.NoError(t, err)
require.Equal(t, c.commonTLSConfig(false).MinVersion, TLSLookup["tls10"])
- tlsVersions := []string{"tls10", "tls11", "tls12"}
- for _, version := range tlsVersions {
+ for _, version := range tlsVersions() {
require.NoError(t, c.Update(Config{TLSMinVersion: version}))
require.Equal(t, c.commonTLSConfig(false).MinVersion,
TLSLookup[version])
@@ -839,3 +838,8 @@ func TestConfigurator_AutoEncrytCertExpired(t *testing.T) {
c.autoEncrypt.cert = cert
require.False(t, c.AutoEncryptCertExpired())
}
+
+func TestConfig_tlsVersions(t *testing.T) {
+ require.Equal(t, []string{"tls10", "tls11", "tls12", "tls13"}, tlsVersions())
+ require.Equal(t, strings.Join(tlsVersions(), ", "), TLSVersions)
+}
diff --git a/website/source/docs/agent/options.html.md b/website/source/docs/agent/options.html.md
index 0aa7b54fea..e2559b098e 100644
--- a/website/source/docs/agent/options.html.md
+++ b/website/source/docs/agent/options.html.md
@@ -1830,8 +1830,8 @@ to the old fragment -->
facility messages are sent. By default, `LOCAL0` will be used.
* `tls_min_version` Added in Consul
- 0.7.4, this specifies the minimum supported version of TLS. Accepted values are "tls10", "tls11"
- or "tls12". This defaults to "tls12". WARNING: TLS 1.1 and lower are generally considered less
+ 0.7.4, this specifies the minimum supported version of TLS. Accepted values are "tls10", "tls11",
+ "tls12", or "tls13". This defaults to "tls12". WARNING: TLS 1.1 and lower are generally considered less
secure; avoid using these if possible.
* `tls_cipher_suites` Added in Consul