Add verify server hostname to tls default (#17155)

This commit is contained in:
Fulvio 2023-07-10 17:34:41 +02:00 committed by GitHub
parent b0a2e33e0a
commit f4b08040fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 23 deletions

3
.changelog/17155.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
config: Add new `tls.defaults.verify_server_hostname` configuration option. This specifies the default value for any interfaces that support the `verify_server_hostname` option.
```

View File

@ -2653,10 +2653,10 @@ func (b *builder) buildTLSConfig(rt RuntimeConfig, t TLS) (tlsutil.Config, error
return c, errors.New("verify_outgoing is not valid in the tls.grpc stanza")
}
// Similarly, only the internal RPC configuration honors VerifyServerHostname
// Similarly, only the internal RPC and defaults configuration honor VerifyServerHostname
// so we call it out here too.
if t.Defaults.VerifyServerHostname != nil || t.GRPC.VerifyServerHostname != nil || t.HTTPS.VerifyServerHostname != nil {
return c, errors.New("verify_server_hostname is only valid in the tls.internal_rpc stanza")
if t.GRPC.VerifyServerHostname != nil || t.HTTPS.VerifyServerHostname != nil {
return c, errors.New("verify_server_hostname is only valid in the tls.defaults and tls.internal_rpc stanzas")
}
// And UseAutoCert right now only applies to external gRPC interface.
@ -2706,8 +2706,11 @@ func (b *builder) buildTLSConfig(rt RuntimeConfig, t TLS) (tlsutil.Config, error
}
mapCommon("internal_rpc", t.InternalRPC, &c.InternalRPC)
c.InternalRPC.VerifyServerHostname = boolVal(t.InternalRPC.VerifyServerHostname)
c.InternalRPC.VerifyServerHostname = boolVal(t.Defaults.VerifyServerHostname)
if t.InternalRPC.VerifyServerHostname != nil {
c.InternalRPC.VerifyServerHostname = boolVal(t.InternalRPC.VerifyServerHostname)
}
// Setting only verify_server_hostname is documented to imply verify_outgoing.
// If it doesn't then we risk sending communication over plain TCP when we
// documented it as forcing TLS for RPCs. Enforce this here rather than in

View File

@ -2736,7 +2736,44 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
}
}
`},
expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza",
expected: func(rt *RuntimeConfig) {
rt.DataDir = dataDir
rt.TLS.InternalRPC.VerifyServerHostname = true
rt.TLS.InternalRPC.VerifyOutgoing = true
},
})
run(t, testCase{
desc: "verify_server_hostname in the defaults stanza and internal_rpc",
args: []string{
`-data-dir=` + dataDir,
},
hcl: []string{`
tls {
defaults {
verify_server_hostname = false
},
internal_rpc {
verify_server_hostname = true
}
}
`},
json: []string{`
{
"tls": {
"defaults": {
"verify_server_hostname": false
},
"internal_rpc": {
"verify_server_hostname": true
}
}
}
`},
expected: func(rt *RuntimeConfig) {
rt.DataDir = dataDir
rt.TLS.InternalRPC.VerifyServerHostname = true
rt.TLS.InternalRPC.VerifyOutgoing = true
},
})
run(t, testCase{
desc: "verify_server_hostname in the grpc stanza",
@ -2759,7 +2796,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
}
}
`},
expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza",
expectedErr: "verify_server_hostname is only valid in the tls.defaults and tls.internal_rpc stanza",
})
run(t, testCase{
desc: "verify_server_hostname in the https stanza",
@ -2782,7 +2819,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
}
}
`},
expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza",
expectedErr: "verify_server_hostname is only valid in the tls.defaults and tls.internal_rpc stanza",
})
run(t, testCase{
desc: "translated keys",
@ -5723,6 +5760,74 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
rt.TLS.InternalRPC.VerifyOutgoing = true
},
})
run(t, testCase{
desc: "tls.defaults.verify_server_hostname implies tls.internal_rpc.verify_outgoing",
args: []string{
`-data-dir=` + dataDir,
},
json: []string{`
{
"tls": {
"defaults": {
"verify_server_hostname": true
}
}
}
`},
hcl: []string{`
tls {
defaults {
verify_server_hostname = true
}
}
`},
expected: func(rt *RuntimeConfig) {
rt.DataDir = dataDir
rt.TLS.Domain = "consul."
rt.TLS.NodeName = "thehostname"
rt.TLS.InternalRPC.VerifyServerHostname = true
rt.TLS.InternalRPC.VerifyOutgoing = true
},
})
run(t, testCase{
desc: "tls.internal_rpc.verify_server_hostname overwrites tls.defaults.verify_server_hostname",
args: []string{
`-data-dir=` + dataDir,
},
json: []string{`
{
"tls": {
"defaults": {
"verify_server_hostname": false
},
"internal_rpc": {
"verify_server_hostname": true
}
}
}
`},
hcl: []string{`
tls {
defaults {
verify_server_hostname = false
},
internal_rpc {
verify_server_hostname = true
}
}
`},
expected: func(rt *RuntimeConfig) {
rt.DataDir = dataDir
rt.TLS.Domain = "consul."
rt.TLS.NodeName = "thehostname"
rt.TLS.InternalRPC.VerifyServerHostname = true
rt.TLS.InternalRPC.VerifyOutgoing = true
},
})
run(t, testCase{
desc: "tls.grpc.use_auto_cert defaults to false",
args: []string{

View File

@ -2094,6 +2094,12 @@ specially crafted certificate signed by the CA can be used to gain full access t
* `TLSv1_2` (default)
* `TLSv1_3`
- `verify_server_hostname` ((#tls_internal_rpc_verify_server_hostname)) When
set to true, Consul verifies the TLS certificate presented by the servers
match the hostname `server.<datacenter>.<domain>`. By default this is false,
and Consul does not verify the hostname of the certificate, only that it
is signed by a trusted CA.
**WARNING: TLS 1.1 and lower are generally considered less secure and
should not be used if possible.**
@ -2201,7 +2207,7 @@ specially crafted certificate signed by the CA can be used to gain full access t
only way to enforce that no client can communicate with a server unencrypted
is to also enable `verify_incoming` which requires client certificates too.
- `verify_server_hostname` ((#tls_internal_rpc_verify_server_hostname)) When
- `verify_server_hostname` Overrides [tls.defaults.verify_server_hostname](#tls_defaults_verify_server_hostname). When
set to true, Consul verifies the TLS certificate presented by the servers
match the hostname `server.<datacenter>.<domain>`. By default this is false,
and Consul does not verify the hostname of the certificate, only that it
@ -2285,9 +2291,6 @@ tls {
ca_file = "/etc/pki/tls/certs/ca-bundle.crt"
verify_incoming = true
verify_outgoing = true
}
internal_rpc {
verify_server_hostname = true
}
}
@ -2316,9 +2319,7 @@ tls {
"cert_file": "/etc/pki/tls/certs/my.crt",
"ca_file": "/etc/pki/tls/certs/ca-bundle.crt",
"verify_incoming": true,
"verify_outgoing": true
},
"internal_rpc": {
"verify_outgoing": true,
"verify_server_hostname": true
}
}

View File

@ -276,9 +276,6 @@ tls {
ca_file = "/consul/config/certs/consul-agent-ca.pem"
cert_file = "/consul/config/certs/dc1-server-consul-0.pem"
key_file = "/consul/config/certs/dc1-server-consul-0-key.pem"
}
internal_rpc {
verify_server_hostname = true
}
}

View File

@ -128,9 +128,6 @@ environment and adapt these configurations accordingly.
ca_file = "consul-agent-ca.pem"
cert_file = "dc1-server-consul-0.pem"
key_file = "dc1-server-consul-0-key.pem"
}
internal_rpc {
verify_server_hostname = true
}
}
@ -148,9 +145,6 @@ environment and adapt these configurations accordingly.
verify_incoming = false
verify_outgoing = true
ca_file = "consul-agent-ca.pem"
}
internal_rpc {
verify_server_hostname = true
}
}