mirror of https://github.com/hashicorp/consul
Add TLSMinVersion to config options
parent
a64dea878b
commit
07ba3ddb6e
|
@ -429,6 +429,7 @@ func (a *Agent) consulConfig() *consul.Config {
|
||||||
base.KeyFile = a.config.KeyFile
|
base.KeyFile = a.config.KeyFile
|
||||||
base.ServerName = a.config.ServerName
|
base.ServerName = a.config.ServerName
|
||||||
base.Domain = a.config.Domain
|
base.Domain = a.config.Domain
|
||||||
|
base.TLSMinVersion = a.config.TLSMinVersion
|
||||||
|
|
||||||
// Setup the ServerUp callback
|
// Setup the ServerUp callback
|
||||||
base.ServerUp = a.state.ConsulServerUp
|
base.ServerUp = a.state.ConsulServerUp
|
||||||
|
|
|
@ -429,6 +429,9 @@ type Config struct {
|
||||||
// provide matches the certificate
|
// provide matches the certificate
|
||||||
ServerName string `mapstructure:"server_name"`
|
ServerName string `mapstructure:"server_name"`
|
||||||
|
|
||||||
|
// TLSMinVersion is used to set the minimum TLS version used for TLS connections.
|
||||||
|
TLSMinVersion string `mapstructure:"tls_min_version"`
|
||||||
|
|
||||||
// StartJoin is a list of addresses to attempt to join when the
|
// StartJoin is a list of addresses to attempt to join when the
|
||||||
// agent starts. If Serf is unable to communicate with any of these
|
// agent starts. If Serf is unable to communicate with any of these
|
||||||
// addresses, then the agent will error and exit.
|
// addresses, then the agent will error and exit.
|
||||||
|
@ -771,6 +774,8 @@ func DefaultConfig() *Config {
|
||||||
ACLEnforceVersion8: Bool(false),
|
ACLEnforceVersion8: Bool(false),
|
||||||
RetryInterval: 30 * time.Second,
|
RetryInterval: 30 * time.Second,
|
||||||
RetryIntervalWan: 30 * time.Second,
|
RetryIntervalWan: 30 * time.Second,
|
||||||
|
|
||||||
|
TLSMinVersion: "tls10",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,6 +1412,9 @@ func MergeConfig(a, b *Config) *Config {
|
||||||
if b.ServerName != "" {
|
if b.ServerName != "" {
|
||||||
result.ServerName = b.ServerName
|
result.ServerName = b.ServerName
|
||||||
}
|
}
|
||||||
|
if b.TLSMinVersion != "" {
|
||||||
|
result.TLSMinVersion = b.TLSMinVersion
|
||||||
|
}
|
||||||
if b.Checks != nil {
|
if b.Checks != nil {
|
||||||
result.Checks = append(result.Checks, b.Checks...)
|
result.Checks = append(result.Checks, b.Checks...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,7 +332,7 @@ func TestDecodeConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLS
|
// TLS
|
||||||
input = `{"verify_incoming": true, "verify_outgoing": true, "verify_server_hostname": true}`
|
input = `{"verify_incoming": true, "verify_outgoing": true, "verify_server_hostname": true, "tls_min_version": "tls12"}`
|
||||||
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
|
@ -350,6 +350,10 @@ func TestDecodeConfig(t *testing.T) {
|
||||||
t.Fatalf("bad: %#v", config)
|
t.Fatalf("bad: %#v", config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.TLSMinVersion != "tls12" {
|
||||||
|
t.Fatalf("bad: %#v", config)
|
||||||
|
}
|
||||||
|
|
||||||
// TLS keys
|
// TLS keys
|
||||||
input = `{"ca_file": "my/ca/file", "cert_file": "my.cert", "key_file": "key.pem", "server_name": "example.com"}`
|
input = `{"ca_file": "my/ca/file", "cert_file": "my.cert", "key_file": "key.pem", "server_name": "example.com"}`
|
||||||
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||||
|
@ -1621,6 +1625,7 @@ func TestMergeConfig(t *testing.T) {
|
||||||
CAFile: "test/ca.pem",
|
CAFile: "test/ca.pem",
|
||||||
CertFile: "test/cert.pem",
|
CertFile: "test/cert.pem",
|
||||||
KeyFile: "test/key.pem",
|
KeyFile: "test/key.pem",
|
||||||
|
TLSMinVersion: "tls12",
|
||||||
Checks: []*CheckDefinition{nil},
|
Checks: []*CheckDefinition{nil},
|
||||||
Services: []*ServiceDefinition{nil},
|
Services: []*ServiceDefinition{nil},
|
||||||
StartJoin: []string{"1.1.1.1"},
|
StartJoin: []string{"1.1.1.1"},
|
||||||
|
|
|
@ -62,7 +62,9 @@ func NewHTTPServers(agent *Agent, config *Config, logOutput io.Writer) ([]*HTTPS
|
||||||
CertFile: config.CertFile,
|
CertFile: config.CertFile,
|
||||||
KeyFile: config.KeyFile,
|
KeyFile: config.KeyFile,
|
||||||
NodeName: config.NodeName,
|
NodeName: config.NodeName,
|
||||||
ServerName: config.ServerName}
|
ServerName: config.ServerName,
|
||||||
|
TLSMinVersion: config.TLSMinVersion,
|
||||||
|
}
|
||||||
|
|
||||||
tlsConfig, err := tlsConf.IncomingTLSConfig()
|
tlsConfig, err := tlsConf.IncomingTLSConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -144,6 +144,9 @@ type Config struct {
|
||||||
// provide matches the certificate
|
// provide matches the certificate
|
||||||
ServerName string
|
ServerName string
|
||||||
|
|
||||||
|
// TLSMinVersion is used to set the minimum TLS version used for TLS connections.
|
||||||
|
TLSMinVersion string
|
||||||
|
|
||||||
// RejoinAfterLeave controls our interaction with Serf.
|
// RejoinAfterLeave controls our interaction with Serf.
|
||||||
// When set to false (default), a leave causes a Consul to not rejoin
|
// When set to false (default), a leave causes a Consul to not rejoin
|
||||||
// the cluster until an explicit join is received. If this is set to
|
// the cluster until an explicit join is received. If this is set to
|
||||||
|
@ -341,6 +344,8 @@ func DefaultConfig() *Config {
|
||||||
// bit longer to try to cover that period. This should be more
|
// bit longer to try to cover that period. This should be more
|
||||||
// than enough when running in the high performance mode.
|
// than enough when running in the high performance mode.
|
||||||
RPCHoldTimeout: 7 * time.Second,
|
RPCHoldTimeout: 7 * time.Second,
|
||||||
|
|
||||||
|
TLSMinVersion: "tls10",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase our reap interval to 3 days instead of 24h.
|
// Increase our reap interval to 3 days instead of 24h.
|
||||||
|
@ -394,6 +399,7 @@ func (c *Config) tlsConfig() *tlsutil.Config {
|
||||||
NodeName: c.NodeName,
|
NodeName: c.NodeName,
|
||||||
ServerName: c.ServerName,
|
ServerName: c.ServerName,
|
||||||
Domain: c.Domain,
|
Domain: c.Domain,
|
||||||
|
TLSMinVersion: c.TLSMinVersion,
|
||||||
}
|
}
|
||||||
return tlsConf
|
return tlsConf
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,13 @@ type DCWrapper func(dc string, conn net.Conn) (net.Conn, error)
|
||||||
// a constant value. This is usually done by currying DCWrapper.
|
// a constant value. This is usually done by currying DCWrapper.
|
||||||
type Wrapper func(conn net.Conn) (net.Conn, error)
|
type Wrapper func(conn net.Conn) (net.Conn, error)
|
||||||
|
|
||||||
|
// TLSLookup maps the tls_min_version configuration to the internal value
|
||||||
|
var TLSLookup = map[string]uint16{
|
||||||
|
"tls10": tls.VersionTLS10,
|
||||||
|
"tls11": tls.VersionTLS11,
|
||||||
|
"tls12": tls.VersionTLS12,
|
||||||
|
}
|
||||||
|
|
||||||
// Config used to create tls.Config
|
// Config used to create tls.Config
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// VerifyIncoming is used to verify the authenticity of incoming connections.
|
// VerifyIncoming is used to verify the authenticity of incoming connections.
|
||||||
|
@ -61,6 +68,9 @@ type Config struct {
|
||||||
|
|
||||||
// Domain is the Consul TLD being used. Defaults to "consul."
|
// Domain is the Consul TLD being used. Defaults to "consul."
|
||||||
Domain string
|
Domain string
|
||||||
|
|
||||||
|
// TLSMinVersion is the minimum accepted TLS version that can be used.
|
||||||
|
TLSMinVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendCA opens and parses the CA file and adds the certificates to
|
// AppendCA opens and parses the CA file and adds the certificates to
|
||||||
|
@ -140,6 +150,15 @@ func (c *Config) OutgoingTLSConfig() (*tls.Config, error) {
|
||||||
tlsConfig.Certificates = []tls.Certificate{*cert}
|
tlsConfig.Certificates = []tls.Certificate{*cert}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a minimum TLS version was set
|
||||||
|
if c.TLSMinVersion != "" {
|
||||||
|
tlsvers, ok := TLSLookup[c.TLSMinVersion]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [tls10,tls11,tls12]", c.TLSMinVersion)
|
||||||
|
}
|
||||||
|
tlsConfig.MinVersion = tlsvers
|
||||||
|
}
|
||||||
|
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,5 +329,14 @@ func (c *Config) IncomingTLSConfig() (*tls.Config, error) {
|
||||||
return nil, fmt.Errorf("VerifyIncoming set, and no Cert/Key pair provided!")
|
return nil, fmt.Errorf("VerifyIncoming set, and no Cert/Key pair provided!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a minimum TLS version was set
|
||||||
|
if c.TLSMinVersion != "" {
|
||||||
|
tlsvers, ok := TLSLookup[c.TLSMinVersion]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [tls10,tls11,tls12]", c.TLSMinVersion)
|
||||||
|
}
|
||||||
|
tlsConfig.MinVersion = tlsvers
|
||||||
|
}
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,27 @@ func TestConfig_OutgoingTLS_WithKeyPair(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig_OutgoingTLS_TLSMinVersion(t *testing.T) {
|
||||||
|
tlsVersions := []string{"tls10", "tls11", "tls12"}
|
||||||
|
for _, version := range tlsVersions {
|
||||||
|
conf := &Config{
|
||||||
|
VerifyOutgoing: true,
|
||||||
|
CAFile: "../test/ca/root.cer",
|
||||||
|
TLSMinVersion: version,
|
||||||
|
}
|
||||||
|
tls, err := conf.OutgoingTLSConfig()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if tls == nil {
|
||||||
|
t.Fatalf("expected config")
|
||||||
|
}
|
||||||
|
if tls.MinVersion != TLSLookup[version] {
|
||||||
|
t.Fatalf("expected tls min version: %v, %v", tls.MinVersion, TLSLookup[version])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func startTLSServer(config *Config) (net.Conn, chan error) {
|
func startTLSServer(config *Config) (net.Conn, chan error) {
|
||||||
errc := make(chan error, 1)
|
errc := make(chan error, 1)
|
||||||
|
|
||||||
|
@ -450,3 +471,26 @@ func TestConfig_IncomingTLS_NoVerify(t *testing.T) {
|
||||||
t.Fatalf("unexpected client cert")
|
t.Fatalf("unexpected client cert")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig_IncomingTLS_TLSMinVersion(t *testing.T) {
|
||||||
|
tlsVersions := []string{"tls10", "tls11", "tls12"}
|
||||||
|
for _, version := range tlsVersions {
|
||||||
|
conf := &Config{
|
||||||
|
VerifyIncoming: true,
|
||||||
|
CAFile: "../test/ca/root.cer",
|
||||||
|
CertFile: "../test/key/ourdomain.cer",
|
||||||
|
KeyFile: "../test/key/ourdomain.key",
|
||||||
|
TLSMinVersion: version,
|
||||||
|
}
|
||||||
|
tls, err := conf.IncomingTLSConfig()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if tls == nil {
|
||||||
|
t.Fatalf("expected config")
|
||||||
|
}
|
||||||
|
if tls.MinVersion != TLSLookup[version] {
|
||||||
|
t.Fatalf("expected tls min version: %v, %v", tls.MinVersion, TLSLookup[version])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -958,6 +958,11 @@ Consul will not enable TLS for the HTTP API unless the `https` port has been ass
|
||||||
[`enable_syslog`](#enable_syslog) is provided, this controls to which
|
[`enable_syslog`](#enable_syslog) is provided, this controls to which
|
||||||
facility messages are sent. By default, `LOCAL0` will be used.
|
facility messages are sent. By default, `LOCAL0` will be used.
|
||||||
|
|
||||||
|
* <a name="tls_min_version"></a><a href="#tls_min_version">`tls_min_version`</a> Added in Consul
|
||||||
|
0.7.4, this specifies the minimum supported version of TLS. Accepted values are "tls10", "tls11"
|
||||||
|
or "tls12". This defaults to "tls10". WARNING: TLS 1.1 and lower are generally considered less
|
||||||
|
secure; avoid using these if possible. This will be changed to default to "tls12" in Consul 0.8.0.
|
||||||
|
|
||||||
* <a name="translate_wan_addrs"</a><a href="#translate_wan_addrs">`translate_wan_addrs`</a> If
|
* <a name="translate_wan_addrs"</a><a href="#translate_wan_addrs">`translate_wan_addrs`</a> If
|
||||||
set to true, Consul will prefer a node's configured <a href="#_advertise-wan">WAN address</a>
|
set to true, Consul will prefer a node's configured <a href="#_advertise-wan">WAN address</a>
|
||||||
when servicing DNS and HTTP requests for a node in a remote datacenter. This allows the node to
|
when servicing DNS and HTTP requests for a node in a remote datacenter. This allows the node to
|
||||||
|
|
Loading…
Reference in New Issue