Support per-listener TLS configuration ⚙️ (#12504)
Introduces the capability to configure TLS differently for Consul's listeners/ports (i.e. HTTPS, gRPC, and the internal multiplexed RPC port) which is useful in scenarios where you may want the HTTPS or gRPC interfaces to present a certificate signed by a well-known/public CA, rather than the certificate used for internal communication which must have a SAN in the form `server.<dc>.consul`.
This commit is contained in:
parent
27711fe5c7
commit
57f0f42733
|
@ -0,0 +1,7 @@
|
|||
```release-note:feature
|
||||
tls: it is now possible to configure TLS differently for each of Consul's listeners (i.e. HTTPS, gRPC and the internal multiplexed RPC listener) using the `tls` stanza
|
||||
```
|
||||
|
||||
```release-note:deprecation
|
||||
config: setting `cert_file`, `key_file`, `ca_file`, `ca_path`, `tls_min_version`, `tls_cipher_suites`, `verify_incoming`, `verify_incoming_rpc`, `verify_incoming_https`, `verify_outgoing` and `verify_server_hostname` at the top-level is now deprecated, use the `tls` stanza instead
|
||||
```
|
|
@ -489,7 +489,7 @@ func (a *Agent) Start(ctx context.Context) error {
|
|||
c.NodeID = a.config.NodeID
|
||||
a.config = c
|
||||
|
||||
if err := a.tlsConfigurator.Update(a.config.ToTLSUtilConfig()); err != nil {
|
||||
if err := a.tlsConfigurator.Update(a.config.TLS); err != nil {
|
||||
return fmt.Errorf("Failed to load TLS configurations after applying auto-config settings: %w", err)
|
||||
}
|
||||
|
||||
|
@ -1218,7 +1218,7 @@ func newConsulConfig(runtimeCfg *config.RuntimeConfig, logger hclog.Logger) (*co
|
|||
}
|
||||
cfg.Build = fmt.Sprintf("%s%s:%s", runtimeCfg.Version, runtimeCfg.VersionPrerelease, revision)
|
||||
|
||||
cfg.TLSConfig = runtimeCfg.ToTLSUtilConfig()
|
||||
cfg.TLSConfig = runtimeCfg.TLS
|
||||
|
||||
cfg.DefaultQueryTime = runtimeCfg.DefaultQueryTime
|
||||
cfg.MaxQueryTime = runtimeCfg.MaxQueryTime
|
||||
|
@ -3748,7 +3748,7 @@ func (a *Agent) reloadConfigInternal(newCfg *config.RuntimeConfig) error {
|
|||
// the checks and service registrations.
|
||||
a.tokens.Load(newCfg.ACLTokens, a.logger)
|
||||
|
||||
if err := a.tlsConfigurator.Update(newCfg.ToTLSUtilConfig()); err != nil {
|
||||
if err := a.tlsConfigurator.Update(newCfg.TLS); err != nil {
|
||||
return fmt.Errorf("Failed reloading tls configuration: %s", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -822,7 +822,7 @@ func startedAutoConfig(t *testing.T, autoEncrypt bool) testAutoConfig {
|
|||
if !autoEncrypt {
|
||||
// auto-encrypt doesn't modify the config but rather sets the value
|
||||
// in the TLS configurator
|
||||
require.True(t, cfg.VerifyServerHostname)
|
||||
require.True(t, cfg.TLS.InternalRPC.VerifyServerHostname)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
|
|
@ -81,11 +81,12 @@ func translateConfig(c *pbconfig.Config) config.Config {
|
|||
}
|
||||
|
||||
if t := c.TLS; t != nil {
|
||||
result.VerifyOutgoing = &t.VerifyOutgoing
|
||||
result.VerifyServerHostname = &t.VerifyServerHostname
|
||||
result.TLSMinVersion = stringPtrOrNil(t.MinVersion)
|
||||
result.TLSCipherSuites = stringPtrOrNil(t.CipherSuites)
|
||||
result.TLSPreferServerCipherSuites = &t.PreferServerCipherSuites
|
||||
result.TLS.Defaults = config.TLSProtocolConfig{
|
||||
VerifyOutgoing: &t.VerifyOutgoing,
|
||||
TLSMinVersion: stringPtrOrNil(t.MinVersion),
|
||||
TLSCipherSuites: stringPtrOrNil(t.CipherSuites),
|
||||
}
|
||||
result.TLS.InternalRPC.VerifyServerHostname = &t.VerifyServerHostname
|
||||
}
|
||||
|
||||
return result
|
||||
|
|
|
@ -92,7 +92,6 @@ func TestTranslateConfig(t *testing.T) {
|
|||
VerifyServerHostname: true,
|
||||
CipherSuites: "stuff",
|
||||
MinVersion: "tls13",
|
||||
PreferServerCipherSuites: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -105,11 +104,16 @@ func TestTranslateConfig(t *testing.T) {
|
|||
EncryptKey: stringPointer("blarg"),
|
||||
EncryptVerifyIncoming: boolPointer(true),
|
||||
EncryptVerifyOutgoing: boolPointer(true),
|
||||
TLS: config.TLS{
|
||||
Defaults: config.TLSProtocolConfig{
|
||||
VerifyOutgoing: boolPointer(true),
|
||||
VerifyServerHostname: boolPointer(true),
|
||||
TLSCipherSuites: stringPointer("stuff"),
|
||||
TLSMinVersion: stringPointer("tls13"),
|
||||
TLSPreferServerCipherSuites: boolPointer(true),
|
||||
},
|
||||
InternalRPC: config.TLSProtocolConfig{
|
||||
VerifyServerHostname: boolPointer(true),
|
||||
},
|
||||
},
|
||||
ACL: config.ACL{
|
||||
Enabled: boolPointer(true),
|
||||
PolicyTTL: stringPointer("1s"),
|
||||
|
|
|
@ -747,18 +747,6 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
|||
enableRemoteScriptChecks := boolVal(c.EnableScriptChecks)
|
||||
enableLocalScriptChecks := boolValWithDefault(c.EnableLocalScriptChecks, enableRemoteScriptChecks)
|
||||
|
||||
// VerifyServerHostname implies VerifyOutgoing
|
||||
verifyServerName := boolVal(c.VerifyServerHostname)
|
||||
verifyOutgoing := boolVal(c.VerifyOutgoing)
|
||||
if verifyServerName {
|
||||
// Setting only verify_server_hostname is documented to imply
|
||||
// verify_outgoing. If it doesn't then we risk sending communication over TCP
|
||||
// when we documented it as forcing TLS for RPCs. Enforce this here rather
|
||||
// than in several different places through the code that need to reason
|
||||
// about it. (See CVE-2018-19653)
|
||||
verifyOutgoing = true
|
||||
}
|
||||
|
||||
var configEntries []structs.ConfigEntry
|
||||
|
||||
if len(c.ConfigEntries.Bootstrap) > 0 {
|
||||
|
@ -963,9 +951,6 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
|||
c.Cache.EntryFetchMaxBurst, cache.DefaultEntryFetchMaxBurst,
|
||||
),
|
||||
},
|
||||
CAFile: stringVal(c.CAFile),
|
||||
CAPath: stringVal(c.CAPath),
|
||||
CertFile: stringVal(c.CertFile),
|
||||
CheckUpdateInterval: b.durationVal("check_update_interval", c.CheckUpdateInterval),
|
||||
CheckOutputMaxSize: intValWithDefault(c.CheckOutputMaxSize, 4096),
|
||||
Checks: checks,
|
||||
|
@ -1012,7 +997,6 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
|||
GRPCAddrs: grpcAddrs,
|
||||
HTTPMaxConnsPerClient: intVal(c.Limits.HTTPMaxConnsPerClient),
|
||||
HTTPSHandshakeTimeout: b.durationVal("limits.https_handshake_timeout", c.Limits.HTTPSHandshakeTimeout),
|
||||
KeyFile: stringVal(c.KeyFile),
|
||||
KVMaxValueSize: uint64Val(c.Limits.KVMaxValueSize),
|
||||
LeaveDrainTime: b.durationVal("performance.leave_drain_time", c.Performance.LeaveDrainTime),
|
||||
LeaveOnTerm: leaveOnTerm,
|
||||
|
@ -1076,9 +1060,6 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
|||
SkipLeaveOnInt: skipLeaveOnInt,
|
||||
StartJoinAddrsLAN: b.expandAllOptionalAddrs("start_join", c.StartJoinAddrsLAN),
|
||||
StartJoinAddrsWAN: b.expandAllOptionalAddrs("start_join_wan", c.StartJoinAddrsWAN),
|
||||
TLSCipherSuites: b.tlsCipherSuites("tls_cipher_suites", c.TLSCipherSuites),
|
||||
TLSMinVersion: stringVal(c.TLSMinVersion),
|
||||
TLSPreferServerCipherSuites: boolVal(c.TLSPreferServerCipherSuites),
|
||||
TaggedAddresses: c.TaggedAddresses,
|
||||
TranslateWANAddrs: boolVal(c.TranslateWANAddrs),
|
||||
TxnMaxReqLen: uint64Val(c.Limits.TxnMaxReqLen),
|
||||
|
@ -1086,14 +1067,14 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
|||
UnixSocketGroup: stringVal(c.UnixSocket.Group),
|
||||
UnixSocketMode: stringVal(c.UnixSocket.Mode),
|
||||
UnixSocketUser: stringVal(c.UnixSocket.User),
|
||||
VerifyIncoming: boolVal(c.VerifyIncoming),
|
||||
VerifyIncomingHTTPS: boolVal(c.VerifyIncomingHTTPS),
|
||||
VerifyIncomingRPC: boolVal(c.VerifyIncomingRPC),
|
||||
VerifyOutgoing: verifyOutgoing,
|
||||
VerifyServerHostname: verifyServerName,
|
||||
Watches: c.Watches,
|
||||
}
|
||||
|
||||
rt.TLS, err = b.buildTLSConfig(rt, c.TLS)
|
||||
if err != nil {
|
||||
return RuntimeConfig{}, err
|
||||
}
|
||||
|
||||
rt.UseStreamingBackend = boolValWithDefault(c.UseStreamingBackend, true)
|
||||
|
||||
if c.RaftBoltDBConfig != nil {
|
||||
|
@ -1477,10 +1458,8 @@ func (b *builder) validate(rt RuntimeConfig) error {
|
|||
b.warn("rpc.enable_streaming = true has no effect when not running in server mode")
|
||||
}
|
||||
|
||||
if rt.AutoEncryptAllowTLS {
|
||||
if !rt.VerifyIncoming && !rt.VerifyIncomingRPC {
|
||||
b.warn("if auto_encrypt.allow_tls is turned on, either verify_incoming or verify_incoming_rpc should be enabled. It is necessary to turn it off during a migration to TLS, but it should definitely be turned on afterwards.")
|
||||
}
|
||||
if rt.AutoEncryptAllowTLS && !rt.TLS.InternalRPC.VerifyIncoming {
|
||||
b.warn("if auto_encrypt.allow_tls is turned on, tls.internal_rpc.verify_incoming should be enabled (either explicitly or via tls.defaults.verify_incoming). It is necessary to turn it off during a migration to TLS, but it should definitely be turned on afterwards.")
|
||||
}
|
||||
|
||||
if err := checkLimitsFromMaxConnsPerClient(rt.HTTPMaxConnsPerClient); err != nil {
|
||||
|
@ -2319,7 +2298,7 @@ func (b *builder) validateAutoConfig(rt RuntimeConfig) error {
|
|||
|
||||
// Right now we require TLS as everything we are going to transmit via auto-config is sensitive. Signed Certificates, Tokens
|
||||
// and other encryption keys. This must be transmitted over a secure connection so we don't allow doing otherwise.
|
||||
if !rt.VerifyOutgoing {
|
||||
if !rt.TLS.InternalRPC.VerifyOutgoing {
|
||||
return fmt.Errorf("auto_config.enabled cannot be set without configuring TLS for server communications")
|
||||
}
|
||||
|
||||
|
@ -2366,7 +2345,7 @@ func validateAutoConfigAuthorizer(rt RuntimeConfig) error {
|
|||
|
||||
// Right now we require TLS as everything we are going to transmit via auto-config is sensitive. Signed Certificates, Tokens
|
||||
// and other encryption keys. This must be transmitted over a secure connection so we don't allow doing otherwise.
|
||||
if rt.CertFile == "" {
|
||||
if rt.TLS.InternalRPC.CertFile == "" {
|
||||
return fmt.Errorf("auto_config.authorization.enabled cannot be set without providing a TLS certificate for the server")
|
||||
}
|
||||
|
||||
|
@ -2475,3 +2454,75 @@ func validateAbsoluteURLPath(p string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *builder) buildTLSConfig(rt RuntimeConfig, t TLS) (tlsutil.Config, error) {
|
||||
var c tlsutil.Config
|
||||
|
||||
// Consul makes no outgoing connections to the public gRPC port (internal gRPC
|
||||
// traffic goes through the multiplexed internal RPC port) so return an error
|
||||
// rather than let the user think this setting is going to do anything useful.
|
||||
if t.GRPC.VerifyOutgoing != nil {
|
||||
return c, errors.New("verify_outgoing is not valid in the tls.grpc stanza")
|
||||
}
|
||||
|
||||
// Similarly, only the internal RPC configuration honors 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")
|
||||
}
|
||||
|
||||
// TLS is only enabled on the gRPC listener if there's an HTTPS port configured
|
||||
// for historic and backwards-compatibility reasons.
|
||||
if rt.HTTPSPort <= 0 && (t.GRPC != TLSProtocolConfig{}) {
|
||||
b.warn("tls.grpc was provided but TLS will NOT be enabled on the gRPC listener without an HTTPS listener configured (e.g. via ports.https)")
|
||||
}
|
||||
|
||||
defaultCipherSuites := b.tlsCipherSuites("tls.defaults.tls_cipher_suites", t.Defaults.TLSCipherSuites)
|
||||
|
||||
mapCommon := func(name string, src TLSProtocolConfig, dst *tlsutil.ProtocolConfig) {
|
||||
dst.CAPath = stringValWithDefault(src.CAPath, stringVal(t.Defaults.CAPath))
|
||||
dst.CAFile = stringValWithDefault(src.CAFile, stringVal(t.Defaults.CAFile))
|
||||
dst.CertFile = stringValWithDefault(src.CertFile, stringVal(t.Defaults.CertFile))
|
||||
dst.KeyFile = stringValWithDefault(src.KeyFile, stringVal(t.Defaults.KeyFile))
|
||||
dst.TLSMinVersion = stringValWithDefault(src.TLSMinVersion, stringVal(t.Defaults.TLSMinVersion))
|
||||
dst.VerifyIncoming = boolValWithDefault(src.VerifyIncoming, boolVal(t.Defaults.VerifyIncoming))
|
||||
|
||||
// We prevent this from being set explicity in the tls.grpc stanza above, but
|
||||
// let's also prevent it from getting the tls.defaults value to avoid confusion
|
||||
// if we decide to support it in the future.
|
||||
if name != "grpc" {
|
||||
dst.VerifyOutgoing = boolValWithDefault(src.VerifyOutgoing, boolVal(t.Defaults.VerifyOutgoing))
|
||||
}
|
||||
|
||||
if src.TLSCipherSuites == nil {
|
||||
dst.CipherSuites = defaultCipherSuites
|
||||
} else {
|
||||
dst.CipherSuites = b.tlsCipherSuites(
|
||||
fmt.Sprintf("tls.%s.tls_cipher_suites", name),
|
||||
src.TLSCipherSuites,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
mapCommon("internal_rpc", t.InternalRPC, &c.InternalRPC)
|
||||
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
|
||||
// several different places through the code that need to reason about it.
|
||||
//
|
||||
// See: CVE-2018-19653
|
||||
c.InternalRPC.VerifyOutgoing = c.InternalRPC.VerifyOutgoing || c.InternalRPC.VerifyServerHostname
|
||||
|
||||
mapCommon("https", t.HTTPS, &c.HTTPS)
|
||||
mapCommon("grpc", t.GRPC, &c.GRPC)
|
||||
|
||||
c.ServerName = rt.ServerName
|
||||
c.NodeName = rt.NodeName
|
||||
c.Domain = rt.DNSDomain
|
||||
c.EnableAgentTLSForChecks = rt.EnableAgentTLSForChecks
|
||||
c.AutoTLS = rt.AutoEncryptTLS || rt.AutoConfig.Enabled
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
|
|
@ -147,9 +147,6 @@ type Config struct {
|
|||
Bootstrap *bool `mapstructure:"bootstrap"`
|
||||
BootstrapExpect *int `mapstructure:"bootstrap_expect"`
|
||||
Cache Cache `mapstructure:"cache"`
|
||||
CAFile *string `mapstructure:"ca_file"`
|
||||
CAPath *string `mapstructure:"ca_path"`
|
||||
CertFile *string `mapstructure:"cert_file"`
|
||||
Check *CheckDefinition `mapstructure:"check"` // needs to be a pointer to avoid partial merges
|
||||
CheckOutputMaxSize *int `mapstructure:"check_output_max_size"`
|
||||
CheckUpdateInterval *string `mapstructure:"check_update_interval"`
|
||||
|
@ -186,7 +183,6 @@ type Config struct {
|
|||
GossipLAN GossipLANConfig `mapstructure:"gossip_lan"`
|
||||
GossipWAN GossipWANConfig `mapstructure:"gossip_wan"`
|
||||
HTTPConfig HTTPConfig `mapstructure:"http_config"`
|
||||
KeyFile *string `mapstructure:"key_file"`
|
||||
LeaveOnTerm *bool `mapstructure:"leave_on_terminate"`
|
||||
LicensePath *string `mapstructure:"license_path"`
|
||||
Limits Limits `mapstructure:"limits"`
|
||||
|
@ -233,9 +229,7 @@ type Config struct {
|
|||
StartJoinAddrsLAN []string `mapstructure:"start_join"`
|
||||
StartJoinAddrsWAN []string `mapstructure:"start_join_wan"`
|
||||
SyslogFacility *string `mapstructure:"syslog_facility"`
|
||||
TLSCipherSuites *string `mapstructure:"tls_cipher_suites"`
|
||||
TLSMinVersion *string `mapstructure:"tls_min_version"`
|
||||
TLSPreferServerCipherSuites *bool `mapstructure:"tls_prefer_server_cipher_suites"`
|
||||
TLS TLS `mapstructure:"tls"`
|
||||
TaggedAddresses map[string]string `mapstructure:"tagged_addresses"`
|
||||
Telemetry Telemetry `mapstructure:"telemetry"`
|
||||
TranslateWANAddrs *bool `mapstructure:"translate_wan_addrs"`
|
||||
|
@ -249,11 +243,6 @@ type Config struct {
|
|||
UIConfig RawUIConfig `mapstructure:"ui_config"`
|
||||
|
||||
UnixSocket UnixSocket `mapstructure:"unix_sockets"`
|
||||
VerifyIncoming *bool `mapstructure:"verify_incoming"`
|
||||
VerifyIncomingHTTPS *bool `mapstructure:"verify_incoming_https"`
|
||||
VerifyIncomingRPC *bool `mapstructure:"verify_incoming_rpc"`
|
||||
VerifyOutgoing *bool `mapstructure:"verify_outgoing"`
|
||||
VerifyServerHostname *bool `mapstructure:"verify_server_hostname"`
|
||||
Watches []map[string]interface{} `mapstructure:"watches"`
|
||||
|
||||
RPC RPC `mapstructure:"rpc"`
|
||||
|
@ -859,3 +848,22 @@ type RawUIMetricsProxyAddHeader struct {
|
|||
type RPC struct {
|
||||
EnableStreaming *bool `mapstructure:"enable_streaming"`
|
||||
}
|
||||
|
||||
type TLSProtocolConfig struct {
|
||||
CAFile *string `mapstructure:"ca_file"`
|
||||
CAPath *string `mapstructure:"ca_path"`
|
||||
CertFile *string `mapstructure:"cert_file"`
|
||||
KeyFile *string `mapstructure:"key_file"`
|
||||
TLSMinVersion *string `mapstructure:"tls_min_version"`
|
||||
TLSCipherSuites *string `mapstructure:"tls_cipher_suites"`
|
||||
VerifyIncoming *bool `mapstructure:"verify_incoming"`
|
||||
VerifyOutgoing *bool `mapstructure:"verify_outgoing"`
|
||||
VerifyServerHostname *bool `mapstructure:"verify_server_hostname"`
|
||||
}
|
||||
|
||||
type TLS struct {
|
||||
Defaults TLSProtocolConfig `mapstructure:"defaults"`
|
||||
InternalRPC TLSProtocolConfig `mapstructure:"internal_rpc"`
|
||||
HTTPS TLSProtocolConfig `mapstructure:"https"`
|
||||
GRPC TLSProtocolConfig `mapstructure:"grpc"`
|
||||
}
|
||||
|
|
|
@ -55,7 +55,12 @@ func DefaultSource() Source {
|
|||
|
||||
server = false
|
||||
syslog_facility = "LOCAL0"
|
||||
|
||||
tls = {
|
||||
defaults = {
|
||||
tls_min_version = "tls12"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (slackpad) - Until #3744 is done, we need to keep these
|
||||
// in sync with agent/consul/config.go.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package config
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type DeprecatedConfig struct {
|
||||
// DEPRECATED (ACL-Legacy-Compat) - moved into the "acl.tokens" stanza
|
||||
|
@ -28,6 +30,42 @@ type DeprecatedConfig struct {
|
|||
ACLDownPolicy *string `mapstructure:"acl_down_policy"`
|
||||
// DEPRECATED (ACL-Legacy-Compat) - moved to "acl.token_ttl"
|
||||
ACLTTL *string `mapstructure:"acl_ttl"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.ca_file"
|
||||
CAFile *string `mapstructure:"ca_file"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.ca_path"
|
||||
CAPath *string `mapstructure:"ca_path"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.cert_file"
|
||||
CertFile *string `mapstructure:"cert_file"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.key_file"
|
||||
KeyFile *string `mapstructure:"key_file"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.tls_cipher_suites"
|
||||
TLSCipherSuites *string `mapstructure:"tls_cipher_suites"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.tls_min_version"
|
||||
TLSMinVersion *string `mapstructure:"tls_min_version"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.verify_incoming"
|
||||
VerifyIncoming *bool `mapstructure:"verify_incoming"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.https.verify_incoming"
|
||||
VerifyIncomingHTTPS *bool `mapstructure:"verify_incoming_https"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.internal_rpc.verify_incoming"
|
||||
VerifyIncomingRPC *bool `mapstructure:"verify_incoming_rpc"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.defaults.verify_outgoing"
|
||||
VerifyOutgoing *bool `mapstructure:"verify_outgoing"`
|
||||
|
||||
// DEPRECATED(TLS) - moved to "tls.internal_rpc.verify_server_hostname"
|
||||
VerifyServerHostname *bool `mapstructure:"verify_server_hostname"`
|
||||
|
||||
// DEPRECATED(TLS) - this isn't honored by crypto/tls anymore.
|
||||
TLSPreferServerCipherSuites *bool `mapstructure:"tls_prefer_server_cipher_suites"`
|
||||
}
|
||||
|
||||
func applyDeprecatedConfig(d *decodeTarget) (Config, []string) {
|
||||
|
@ -132,9 +170,102 @@ func applyDeprecatedConfig(d *decodeTarget) (Config, []string) {
|
|||
warns = append(warns, deprecationWarning("acl_enable_key_list_policy", "acl.enable_key_list_policy"))
|
||||
}
|
||||
|
||||
warns = append(warns, applyDeprecatedTLSConfig(dep, &d.Config)...)
|
||||
|
||||
return d.Config, warns
|
||||
}
|
||||
|
||||
func applyDeprecatedTLSConfig(dep DeprecatedConfig, cfg *Config) []string {
|
||||
var warns []string
|
||||
|
||||
defaults := &cfg.TLS.Defaults
|
||||
internalRPC := &cfg.TLS.InternalRPC
|
||||
https := &cfg.TLS.HTTPS
|
||||
|
||||
if v := dep.CAFile; v != nil {
|
||||
if defaults.CAFile == nil {
|
||||
defaults.CAFile = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("ca_file", "tls.defaults.ca_file"))
|
||||
}
|
||||
|
||||
if v := dep.CAPath; v != nil {
|
||||
if defaults.CAPath == nil {
|
||||
defaults.CAPath = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("ca_path", "tls.defaults.ca_path"))
|
||||
}
|
||||
|
||||
if v := dep.CertFile; v != nil {
|
||||
if defaults.CertFile == nil {
|
||||
defaults.CertFile = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("cert_file", "tls.defaults.cert_file"))
|
||||
}
|
||||
|
||||
if v := dep.KeyFile; v != nil {
|
||||
if defaults.KeyFile == nil {
|
||||
defaults.KeyFile = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("key_file", "tls.defaults.key_file"))
|
||||
}
|
||||
|
||||
if v := dep.TLSCipherSuites; v != nil {
|
||||
if defaults.TLSCipherSuites == nil {
|
||||
defaults.TLSCipherSuites = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("tls_cipher_suites", "tls.defaults.tls_cipher_suites"))
|
||||
}
|
||||
|
||||
if v := dep.TLSMinVersion; v != nil {
|
||||
if defaults.TLSMinVersion == nil {
|
||||
defaults.TLSMinVersion = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("tls_min_version", "tls.defaults.tls_min_version"))
|
||||
}
|
||||
|
||||
if v := dep.VerifyIncoming; v != nil {
|
||||
if defaults.VerifyIncoming == nil {
|
||||
defaults.VerifyIncoming = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("verify_incoming", "tls.defaults.verify_incoming"))
|
||||
}
|
||||
|
||||
if v := dep.VerifyIncomingHTTPS; v != nil {
|
||||
if https.VerifyIncoming == nil {
|
||||
https.VerifyIncoming = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("verify_incoming_https", "tls.https.verify_incoming"))
|
||||
}
|
||||
|
||||
if v := dep.VerifyIncomingRPC; v != nil {
|
||||
if internalRPC.VerifyIncoming == nil {
|
||||
internalRPC.VerifyIncoming = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("verify_incoming_rpc", "tls.internal_rpc.verify_incoming"))
|
||||
}
|
||||
|
||||
if v := dep.VerifyOutgoing; v != nil {
|
||||
if defaults.VerifyOutgoing == nil {
|
||||
defaults.VerifyOutgoing = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("verify_outgoing", "tls.defaults.verify_outgoing"))
|
||||
}
|
||||
|
||||
if v := dep.VerifyServerHostname; v != nil {
|
||||
if internalRPC.VerifyServerHostname == nil {
|
||||
internalRPC.VerifyServerHostname = v
|
||||
}
|
||||
warns = append(warns, deprecationWarning("verify_server_hostname", "tls.internal_rpc.verify_server_hostname"))
|
||||
}
|
||||
|
||||
if dep.TLSPreferServerCipherSuites != nil {
|
||||
warns = append(warns, "The 'tls_prefer_server_cipher_suites' field is deprecated and will be ignored.")
|
||||
}
|
||||
|
||||
return warns
|
||||
}
|
||||
|
||||
func deprecationWarning(old, new string) string {
|
||||
return fmt.Sprintf("The '%v' field is deprecated. Use the '%v' field instead.", old, new)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/tlsutil"
|
||||
)
|
||||
|
||||
func TestLoad_DeprecatedConfig(t *testing.T) {
|
||||
|
@ -26,6 +29,18 @@ acl_down_policy = "async-cache"
|
|||
acl_ttl = "3h"
|
||||
acl_enable_key_list_policy = true
|
||||
|
||||
ca_file = "some-ca-file"
|
||||
ca_path = "some-ca-path"
|
||||
cert_file = "some-cert-file"
|
||||
key_file = "some-key-file"
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
|
||||
tls_min_version = "some-tls-version"
|
||||
verify_incoming = true
|
||||
verify_incoming_https = false
|
||||
verify_incoming_rpc = false
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
tls_prefer_server_cipher_suites = true
|
||||
`},
|
||||
}
|
||||
patchLoadOptsShims(&opts)
|
||||
|
@ -41,9 +56,20 @@ acl_enable_key_list_policy = true
|
|||
deprecationWarning("acl_replication_token", "acl.tokens.replication"),
|
||||
deprecationWarning("acl_token", "acl.tokens.default"),
|
||||
deprecationWarning("acl_ttl", "acl.token_ttl"),
|
||||
deprecationWarning("ca_file", "tls.defaults.ca_file"),
|
||||
deprecationWarning("ca_path", "tls.defaults.ca_path"),
|
||||
deprecationWarning("cert_file", "tls.defaults.cert_file"),
|
||||
deprecationWarning("key_file", "tls.defaults.key_file"),
|
||||
deprecationWarning("tls_cipher_suites", "tls.defaults.tls_cipher_suites"),
|
||||
deprecationWarning("tls_min_version", "tls.defaults.tls_min_version"),
|
||||
deprecationWarning("verify_incoming", "tls.defaults.verify_incoming"),
|
||||
deprecationWarning("verify_incoming_https", "tls.https.verify_incoming"),
|
||||
deprecationWarning("verify_incoming_rpc", "tls.internal_rpc.verify_incoming"),
|
||||
deprecationWarning("verify_outgoing", "tls.defaults.verify_outgoing"),
|
||||
deprecationWarning("verify_server_hostname", "tls.internal_rpc.verify_server_hostname"),
|
||||
"The 'tls_prefer_server_cipher_suites' field is deprecated and will be ignored.",
|
||||
}
|
||||
sort.Strings(result.Warnings)
|
||||
require.Equal(t, expectWarns, result.Warnings)
|
||||
require.ElementsMatch(t, expectWarns, result.Warnings)
|
||||
// Ideally this would compare against the entire result.RuntimeConfig, but
|
||||
// we have so many non-zero defaults in that response that the noise of those
|
||||
// defaults makes this test difficult to read. So as a workaround, compare
|
||||
|
@ -58,6 +84,22 @@ acl_enable_key_list_policy = true
|
|||
require.Equal(t, "async-cache", rt.ACLResolverSettings.ACLDownPolicy)
|
||||
require.Equal(t, 3*time.Hour, rt.ACLResolverSettings.ACLTokenTTL)
|
||||
require.Equal(t, true, rt.ACLEnableKeyListPolicy)
|
||||
|
||||
for _, l := range []tlsutil.ProtocolConfig{rt.TLS.InternalRPC, rt.TLS.GRPC, rt.TLS.HTTPS} {
|
||||
require.Equal(t, "some-ca-file", l.CAFile)
|
||||
require.Equal(t, "some-ca-path", l.CAPath)
|
||||
require.Equal(t, "some-cert-file", l.CertFile)
|
||||
require.Equal(t, "some-key-file", l.KeyFile)
|
||||
require.Equal(t, "some-tls-version", l.TLSMinVersion)
|
||||
require.Equal(t, []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}, l.CipherSuites)
|
||||
}
|
||||
|
||||
require.False(t, rt.TLS.InternalRPC.VerifyIncoming)
|
||||
require.False(t, rt.TLS.HTTPS.VerifyIncoming)
|
||||
require.True(t, rt.TLS.GRPC.VerifyIncoming)
|
||||
require.True(t, rt.TLS.InternalRPC.VerifyOutgoing)
|
||||
require.True(t, rt.TLS.HTTPS.VerifyOutgoing)
|
||||
require.True(t, rt.TLS.InternalRPC.VerifyServerHostname)
|
||||
}
|
||||
|
||||
func TestLoad_DeprecatedConfig_ACLReplication(t *testing.T) {
|
||||
|
|
|
@ -377,24 +377,6 @@ type RuntimeConfig struct {
|
|||
// Cache represent cache configuration of agent
|
||||
Cache cache.Options
|
||||
|
||||
// CAFile is a path to a certificate authority file. This is used with
|
||||
// VerifyIncoming or VerifyOutgoing to verify the TLS connection.
|
||||
//
|
||||
// hcl: ca_file = string
|
||||
CAFile string
|
||||
|
||||
// CAPath is a path to a directory of certificate authority files. This is
|
||||
// used with VerifyIncoming or VerifyOutgoing to verify the TLS connection.
|
||||
//
|
||||
// hcl: ca_path = string
|
||||
CAPath string
|
||||
|
||||
// CertFile is used to provide a TLS certificate that is used for serving
|
||||
// TLS connections. Must be provided to serve TLS connections.
|
||||
//
|
||||
// hcl: cert_file = string
|
||||
CertFile string
|
||||
|
||||
// CheckUpdateInterval controls the interval on which the output of a health check
|
||||
// is updated if there is no change to the state. For example, a check in a steady
|
||||
// state may run every 5 second generating a unique output (timestamp, etc), forcing
|
||||
|
@ -767,12 +749,6 @@ type RuntimeConfig struct {
|
|||
// flags: -https-port int
|
||||
HTTPSPort int
|
||||
|
||||
// KeyFile is used to provide a TLS key that is used for serving TLS
|
||||
// connections. Must be provided to serve TLS connections.
|
||||
//
|
||||
// hcl: key_file = string
|
||||
KeyFile string
|
||||
|
||||
// KVMaxValueSize controls the max allowed value size. If not set defaults
|
||||
// to raft's suggested max value size.
|
||||
//
|
||||
|
@ -1338,40 +1314,11 @@ type RuntimeConfig struct {
|
|||
// flag: -join-wan string -join-wan string
|
||||
StartJoinAddrsWAN []string
|
||||
|
||||
// TLSCipherSuites is used to specify the list of supported ciphersuites.
|
||||
// TLS configures certificates, CA, cipher suites, and other TLS settings
|
||||
// on Consul's listeners (i.e. Internal multiplexed RPC, HTTPS and gRPC).
|
||||
//
|
||||
// The values should be a list of the following values:
|
||||
//
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
// TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||
// TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
|
||||
// TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
// TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||
// TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
//
|
||||
// todo(fs): IMHO, we should also support the raw 0xNNNN values from
|
||||
// todo(fs): https://golang.org/pkg/crypto/tls/#pkg-constants
|
||||
// todo(fs): since they are standardized by IANA.
|
||||
//
|
||||
// hcl: tls_cipher_suites = []string
|
||||
TLSCipherSuites []uint16
|
||||
|
||||
// TLSMinVersion is used to set the minimum TLS version used for TLS
|
||||
// connections. Should be either "tls10", "tls11", "tls12" or "tls13".
|
||||
// Defaults to tls12.
|
||||
//
|
||||
// hcl: tls_min_version = string
|
||||
TLSMinVersion string
|
||||
|
||||
// TLSPreferServerCipherSuites specifies whether to prefer the server's
|
||||
// cipher suite over the client cipher suites.
|
||||
//
|
||||
// hcl: tls_prefer_server_cipher_suites = (true|false)
|
||||
TLSPreferServerCipherSuites bool
|
||||
// hcl: tls { ... }
|
||||
TLS tlsutil.Config
|
||||
|
||||
// TaggedAddresses are used to publish a set of addresses for
|
||||
// for a node, which can be used by the remote agent. We currently
|
||||
|
@ -1427,49 +1374,6 @@ type RuntimeConfig struct {
|
|||
// hcl: unix_sockets { user = string }
|
||||
UnixSocketUser string
|
||||
|
||||
// VerifyIncoming is used to verify the authenticity of incoming
|
||||
// connections. This means that TCP requests are forbidden, only allowing
|
||||
// for TLS. TLS connections must match a provided certificate authority.
|
||||
// This can be used to force client auth.
|
||||
//
|
||||
// hcl: verify_incoming = (true|false)
|
||||
VerifyIncoming bool
|
||||
|
||||
// VerifyIncomingHTTPS is used to verify the authenticity of incoming HTTPS
|
||||
// connections. This means that TCP requests are forbidden, only allowing
|
||||
// for TLS. TLS connections must match a provided certificate authority.
|
||||
// This can be used to force client auth.
|
||||
//
|
||||
// hcl: verify_incoming_https = (true|false)
|
||||
VerifyIncomingHTTPS bool
|
||||
|
||||
// VerifyIncomingRPC is used to verify the authenticity of incoming RPC
|
||||
// connections. This means that TCP requests are forbidden, only allowing
|
||||
// for TLS. TLS connections must match a provided certificate authority.
|
||||
// This can be used to force client auth.
|
||||
//
|
||||
// hcl: verify_incoming_rpc = (true|false)
|
||||
VerifyIncomingRPC bool
|
||||
|
||||
// VerifyOutgoing is used to verify the authenticity of outgoing
|
||||
// connections. This means that TLS requests are used. TLS connections must
|
||||
// match a provided certificate authority. This is used to verify
|
||||
// authenticity of server nodes.
|
||||
//
|
||||
// hcl: verify_outgoing = (true|false)
|
||||
VerifyOutgoing bool
|
||||
|
||||
// VerifyServerHostname is used to enable hostname verification of servers.
|
||||
// This ensures that the certificate presented is valid for
|
||||
// server.<datacenter>.<domain>. This prevents a compromised client from
|
||||
// being restarted as a server, and then intercepting request traffic as
|
||||
// well as being added as a raft peer. This should be enabled by default
|
||||
// with VerifyOutgoing, but for legacy reasons we cannot break existing
|
||||
// clients.
|
||||
//
|
||||
// hcl: verify_server_hostname = (true|false)
|
||||
VerifyServerHostname bool
|
||||
|
||||
// Watches are used to monitor various endpoints and to invoke a
|
||||
// handler to act appropriately. These are managed entirely in the
|
||||
// agent layer using the standard APIs.
|
||||
|
@ -1676,9 +1580,11 @@ func (c *RuntimeConfig) ConnectCAConfiguration() (*structs.CAConfiguration, erro
|
|||
}
|
||||
|
||||
func (c *RuntimeConfig) APIConfig(includeClientCerts bool) (*api.Config, error) {
|
||||
tls := c.TLS.HTTPS
|
||||
|
||||
cfg := &api.Config{
|
||||
Datacenter: c.Datacenter,
|
||||
TLSConfig: api.TLSConfig{InsecureSkipVerify: !c.VerifyOutgoing},
|
||||
TLSConfig: api.TLSConfig{InsecureSkipVerify: !tls.VerifyOutgoing},
|
||||
}
|
||||
|
||||
unixAddr, httpAddr, httpsAddr := c.ClientAddress()
|
||||
|
@ -1686,11 +1592,11 @@ func (c *RuntimeConfig) APIConfig(includeClientCerts bool) (*api.Config, error)
|
|||
if httpsAddr != "" {
|
||||
cfg.Address = httpsAddr
|
||||
cfg.Scheme = "https"
|
||||
cfg.TLSConfig.CAFile = c.CAFile
|
||||
cfg.TLSConfig.CAPath = c.CAPath
|
||||
cfg.TLSConfig.CAFile = tls.CAFile
|
||||
cfg.TLSConfig.CAPath = tls.CAPath
|
||||
if includeClientCerts {
|
||||
cfg.TLSConfig.CertFile = c.CertFile
|
||||
cfg.TLSConfig.KeyFile = c.KeyFile
|
||||
cfg.TLSConfig.CertFile = tls.CertFile
|
||||
cfg.TLSConfig.KeyFile = tls.KeyFile
|
||||
}
|
||||
} else if httpAddr != "" {
|
||||
cfg.Address = httpAddr
|
||||
|
@ -1715,28 +1621,6 @@ func (c *RuntimeConfig) Sanitized() map[string]interface{} {
|
|||
return sanitize("rt", reflect.ValueOf(c)).Interface().(map[string]interface{})
|
||||
}
|
||||
|
||||
func (c *RuntimeConfig) ToTLSUtilConfig() tlsutil.Config {
|
||||
return tlsutil.Config{
|
||||
VerifyIncoming: c.VerifyIncoming,
|
||||
VerifyIncomingRPC: c.VerifyIncomingRPC,
|
||||
VerifyIncomingHTTPS: c.VerifyIncomingHTTPS,
|
||||
VerifyOutgoing: c.VerifyOutgoing,
|
||||
VerifyServerHostname: c.VerifyServerHostname,
|
||||
CAFile: c.CAFile,
|
||||
CAPath: c.CAPath,
|
||||
CertFile: c.CertFile,
|
||||
KeyFile: c.KeyFile,
|
||||
NodeName: c.NodeName,
|
||||
Domain: c.DNSDomain,
|
||||
ServerName: c.ServerName,
|
||||
TLSMinVersion: c.TLSMinVersion,
|
||||
CipherSuites: c.TLSCipherSuites,
|
||||
PreferServerCipherSuites: c.TLSPreferServerCipherSuites,
|
||||
EnableAgentTLSForChecks: c.EnableAgentTLSForChecks,
|
||||
AutoTLS: c.AutoEncryptTLS || c.AutoConfig.Enabled,
|
||||
}
|
||||
}
|
||||
|
||||
// isSecret determines whether a field name represents a field which
|
||||
// may contain a secret.
|
||||
func isSecret(name string) bool {
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/hashicorp/consul/lib"
|
||||
"github.com/hashicorp/consul/logging"
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
"github.com/hashicorp/consul/tlsutil"
|
||||
"github.com/hashicorp/consul/types"
|
||||
)
|
||||
|
||||
|
@ -386,6 +387,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DNSDomain = "a"
|
||||
rt.TLS.Domain = "a"
|
||||
rt.DataDir = dataDir
|
||||
},
|
||||
})
|
||||
|
@ -590,6 +592,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.NodeName = "a"
|
||||
rt.TLS.NodeName = "a"
|
||||
rt.DataDir = dataDir
|
||||
},
|
||||
})
|
||||
|
@ -2505,6 +2508,98 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
},
|
||||
expectedErr: `invalid meta for service a: Node metadata cannot contain more than 64 key`,
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "verify_outgoing in the grpc stanza",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
hcl: []string{`
|
||||
tls {
|
||||
grpc {
|
||||
verify_outgoing = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
"tls": {
|
||||
"grpc": {
|
||||
"verify_outgoing": true
|
||||
}
|
||||
}
|
||||
}
|
||||
`},
|
||||
expectedErr: "verify_outgoing is not valid in the tls.grpc stanza",
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "verify_server_hostname in the defaults stanza",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
hcl: []string{`
|
||||
tls {
|
||||
defaults {
|
||||
verify_server_hostname = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
"tls": {
|
||||
"defaults": {
|
||||
"verify_server_hostname": true
|
||||
}
|
||||
}
|
||||
}
|
||||
`},
|
||||
expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza",
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "verify_server_hostname in the grpc stanza",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
hcl: []string{`
|
||||
tls {
|
||||
grpc {
|
||||
verify_server_hostname = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
"tls": {
|
||||
"grpc": {
|
||||
"verify_server_hostname": true
|
||||
}
|
||||
}
|
||||
}
|
||||
`},
|
||||
expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza",
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "verify_server_hostname in the https stanza",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
hcl: []string{`
|
||||
tls {
|
||||
https {
|
||||
verify_server_hostname = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
"tls": {
|
||||
"https": {
|
||||
"verify_server_hostname": true
|
||||
}
|
||||
}
|
||||
}
|
||||
`},
|
||||
expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza",
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "translated keys",
|
||||
args: []string{
|
||||
|
@ -2920,8 +3015,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
`},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DataDir = dataDir
|
||||
rt.VerifyServerHostname = true
|
||||
rt.VerifyOutgoing = true
|
||||
rt.TLS.InternalRPC.VerifyServerHostname = true
|
||||
rt.TLS.InternalRPC.VerifyOutgoing = true
|
||||
},
|
||||
expectedWarnings: []string{
|
||||
deprecationWarning("verify_server_hostname", "tls.internal_rpc.verify_server_hostname"),
|
||||
},
|
||||
})
|
||||
run(t, testCase{
|
||||
|
@ -2930,18 +3028,18 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
`-data-dir=` + dataDir,
|
||||
},
|
||||
json: []string{`{
|
||||
"verify_incoming": true,
|
||||
"tls": { "internal_rpc": { "verify_incoming": true } },
|
||||
"auto_encrypt": { "allow_tls": true },
|
||||
"server": true
|
||||
}`},
|
||||
hcl: []string{`
|
||||
verify_incoming = true
|
||||
tls { internal_rpc { verify_incoming = true } }
|
||||
auto_encrypt { allow_tls = true }
|
||||
server = true
|
||||
`},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DataDir = dataDir
|
||||
rt.VerifyIncoming = true
|
||||
rt.TLS.InternalRPC.VerifyIncoming = true
|
||||
rt.AutoEncryptAllowTLS = true
|
||||
rt.ConnectEnabled = true
|
||||
|
||||
|
@ -2953,26 +3051,29 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
},
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "auto_encrypt.allow_tls works with verify_incoming",
|
||||
desc: "auto_encrypt.allow_tls works with tls.defaults.verify_incoming",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
json: []string{`{
|
||||
"verify_incoming": true,
|
||||
"tls": { "defaults": { "verify_incoming": true } },
|
||||
"auto_encrypt": { "allow_tls": true },
|
||||
"server": true
|
||||
}`},
|
||||
hcl: []string{`
|
||||
verify_incoming = true
|
||||
tls { defaults { verify_incoming = true } }
|
||||
auto_encrypt { allow_tls = true }
|
||||
server = true
|
||||
`},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DataDir = dataDir
|
||||
rt.VerifyIncoming = true
|
||||
rt.AutoEncryptAllowTLS = true
|
||||
rt.ConnectEnabled = true
|
||||
|
||||
rt.TLS.InternalRPC.VerifyIncoming = true
|
||||
rt.TLS.GRPC.VerifyIncoming = true
|
||||
rt.TLS.HTTPS.VerifyIncoming = true
|
||||
|
||||
// server things
|
||||
rt.ServerMode = true
|
||||
rt.LeaveOnTerm = false
|
||||
|
@ -2981,25 +3082,25 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
},
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "auto_encrypt.allow_tls works with verify_incoming_rpc",
|
||||
desc: "auto_encrypt.allow_tls works with tls.internal_rpc.verify_incoming",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
json: []string{`{
|
||||
"verify_incoming_rpc": true,
|
||||
"tls": { "internal_rpc": { "verify_incoming": true } },
|
||||
"auto_encrypt": { "allow_tls": true },
|
||||
"server": true
|
||||
}`},
|
||||
hcl: []string{`
|
||||
verify_incoming_rpc = true
|
||||
tls { internal_rpc { verify_incoming = true } }
|
||||
auto_encrypt { allow_tls = true }
|
||||
server = true
|
||||
`},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DataDir = dataDir
|
||||
rt.VerifyIncomingRPC = true
|
||||
rt.AutoEncryptAllowTLS = true
|
||||
rt.ConnectEnabled = true
|
||||
rt.TLS.InternalRPC.VerifyIncoming = true
|
||||
|
||||
// server things
|
||||
rt.ServerMode = true
|
||||
|
@ -3009,7 +3110,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
},
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "auto_encrypt.allow_tls warns without verify_incoming or verify_incoming_rpc",
|
||||
desc: "auto_encrypt.allow_tls warns without tls.defaults.verify_incoming or tls.internal_rpc.verify_incoming",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
|
@ -3021,7 +3122,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
auto_encrypt { allow_tls = true }
|
||||
server = true
|
||||
`},
|
||||
expectedWarnings: []string{"if auto_encrypt.allow_tls is turned on, either verify_incoming or verify_incoming_rpc should be enabled. It is necessary to turn it off during a migration to TLS, but it should definitely be turned on afterwards."},
|
||||
expectedWarnings: []string{"if auto_encrypt.allow_tls is turned on, tls.internal_rpc.verify_incoming should be enabled (either explicitly or via tls.defaults.verify_incoming). It is necessary to turn it off during a migration to TLS, but it should definitely be turned on afterwards."},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DataDir = dataDir
|
||||
rt.AutoEncryptAllowTLS = true
|
||||
|
@ -4436,7 +4537,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
auto_encrypt {
|
||||
tls = true
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
verify_outgoing = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`{
|
||||
"auto_config": {
|
||||
|
@ -4447,7 +4552,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
"auto_encrypt": {
|
||||
"tls": true
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"verify_outgoing": true
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: "both auto_encrypt.tls and auto_config.enabled cannot be set to true.",
|
||||
})
|
||||
|
@ -4463,7 +4572,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
intro_token = "blah"
|
||||
server_addresses = ["198.18.0.1"]
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
verify_outgoing = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4473,7 +4586,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
"intro_token": "blah",
|
||||
"server_addresses": ["198.18.0.1"]
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"verify_outgoing": true
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: "auto_config.enabled cannot be set to true for server agents",
|
||||
})
|
||||
|
@ -4536,7 +4653,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
enabled = true
|
||||
server_addresses = ["198.18.0.1"]
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
verify_outgoing = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4544,7 +4665,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
"enabled": true,
|
||||
"server_addresses": ["198.18.0.1"]
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"verify_outgoing": true
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: "One of auto_config.intro_token, auto_config.intro_token_file or the CONSUL_INTRO_TOKEN environment variable must be set to enable auto_config",
|
||||
})
|
||||
|
@ -4559,7 +4684,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
enabled = true
|
||||
intro_token = "blah"
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
verify_outgoing = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4567,7 +4696,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
"enabled": true,
|
||||
"intro_token": "blah"
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"verify_outgoing": true
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: "auto_config.enabled is set without providing a list of addresses",
|
||||
})
|
||||
|
@ -4586,7 +4719,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
dns_sans = ["foo"]
|
||||
ip_sans = ["invalid", "127.0.0.1"]
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
verify_outgoing = true
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4598,7 +4735,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
"dns_sans": ["foo"],
|
||||
"ip_sans": ["invalid", "127.0.0.1"]
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"verify_outgoing": true
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedWarnings: []string{
|
||||
"Cannot parse ip \"invalid\" from auto_config.ip_sans",
|
||||
|
@ -4613,7 +4754,8 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
rt.AutoConfig.DNSSANs = []string{"foo"}
|
||||
rt.AutoConfig.IPSANs = []net.IP{net.IPv4(127, 0, 0, 1)}
|
||||
rt.DataDir = dataDir
|
||||
rt.VerifyOutgoing = true
|
||||
rt.TLS.InternalRPC.VerifyOutgoing = true
|
||||
rt.TLS.AutoTLS = true
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -4652,7 +4794,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
enabled = true
|
||||
}
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
cert_file = "foo"
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4661,7 +4807,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
"enabled": true
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"cert_file": "foo"
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: `auto_config.authorization.static has invalid configuration: exactly one of 'JWTValidationPubKeys', 'JWKSURL', or 'OIDCDiscoveryURL' must be set for type "jwt"`,
|
||||
})
|
||||
|
@ -4682,7 +4832,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
cert_file = "foo"
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4695,7 +4849,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"cert_file": "foo"
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: `auto_config.authorization.static has invalid configuration: exactly one of 'JWTValidationPubKeys', 'JWKSURL', or 'OIDCDiscoveryURL' must be set for type "jwt"`,
|
||||
})
|
||||
|
@ -4720,7 +4878,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
cert_file = "foo"
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4737,7 +4899,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"cert_file": "foo"
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: `Enabling auto-config authorization (auto_config.authorization.enabled) in non primary datacenters with ACLs enabled (acl.enabled) requires also enabling ACL token replication (acl.enable_token_replication)`,
|
||||
})
|
||||
|
@ -4760,7 +4926,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
cert_file = "foo"
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4775,7 +4945,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"cert_file": "foo"
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expectedErr: `auto_config.authorization.static.claim_assertion "values.node == ${node}" is invalid: Selector "values" is not valid`,
|
||||
})
|
||||
|
@ -4800,7 +4974,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
tls {
|
||||
internal_rpc {
|
||||
cert_file = "foo"
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
|
@ -4818,7 +4996,11 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"cert_file": "foo"
|
||||
}
|
||||
}
|
||||
}`},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.AutoConfig.Authorizer.Enabled = true
|
||||
|
@ -4831,7 +5013,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
rt.LeaveOnTerm = false
|
||||
rt.ServerMode = true
|
||||
rt.SkipLeaveOnInt = true
|
||||
rt.CertFile = "foo"
|
||||
rt.TLS.InternalRPC.CertFile = "foo"
|
||||
rt.RPCConfig.EnableStreaming = true
|
||||
},
|
||||
})
|
||||
|
@ -5197,6 +5379,165 @@ func TestLoad_IntegrationWithFlags(t *testing.T) {
|
|||
}`},
|
||||
expectedErr: "advertise_reconnect_timeout can only be used on a client",
|
||||
})
|
||||
|
||||
run(t, testCase{
|
||||
desc: "TLS defaults and overrides",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
hcl: []string{`
|
||||
ports {
|
||||
https = 4321
|
||||
}
|
||||
|
||||
tls {
|
||||
defaults {
|
||||
ca_file = "default_ca_file"
|
||||
ca_path = "default_ca_path"
|
||||
cert_file = "default_cert_file"
|
||||
tls_min_version = "tls12"
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
|
||||
verify_incoming = true
|
||||
}
|
||||
|
||||
internal_rpc {
|
||||
ca_file = "internal_rpc_ca_file"
|
||||
}
|
||||
|
||||
https {
|
||||
cert_file = "https_cert_file"
|
||||
tls_min_version = "tls13"
|
||||
}
|
||||
|
||||
grpc {
|
||||
verify_incoming = false
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
|
||||
}
|
||||
}
|
||||
`},
|
||||
json: []string{`
|
||||
{
|
||||
"ports": {
|
||||
"https": 4321
|
||||
},
|
||||
"tls": {
|
||||
"defaults": {
|
||||
"ca_file": "default_ca_file",
|
||||
"ca_path": "default_ca_path",
|
||||
"cert_file": "default_cert_file",
|
||||
"tls_min_version": "tls12",
|
||||
"tls_cipher_suites": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"verify_incoming": true
|
||||
},
|
||||
"internal_rpc": {
|
||||
"ca_file": "internal_rpc_ca_file"
|
||||
},
|
||||
"https": {
|
||||
"cert_file": "https_cert_file",
|
||||
"tls_min_version": "tls13"
|
||||
},
|
||||
"grpc": {
|
||||
"verify_incoming": false,
|
||||
"tls_cipher_suites": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
|
||||
}
|
||||
}
|
||||
}
|
||||
`},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DataDir = dataDir
|
||||
|
||||
rt.HTTPSPort = 4321
|
||||
rt.HTTPSAddrs = []net.Addr{tcpAddr("127.0.0.1:4321")}
|
||||
|
||||
rt.TLS.Domain = "consul."
|
||||
rt.TLS.NodeName = "thehostname"
|
||||
|
||||
rt.TLS.InternalRPC.CAFile = "internal_rpc_ca_file"
|
||||
rt.TLS.InternalRPC.CAPath = "default_ca_path"
|
||||
rt.TLS.InternalRPC.CertFile = "default_cert_file"
|
||||
rt.TLS.InternalRPC.TLSMinVersion = "tls12"
|
||||
rt.TLS.InternalRPC.CipherSuites = []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}
|
||||
rt.TLS.InternalRPC.VerifyIncoming = true
|
||||
|
||||
rt.TLS.HTTPS.CAFile = "default_ca_file"
|
||||
rt.TLS.HTTPS.CAPath = "default_ca_path"
|
||||
rt.TLS.HTTPS.CertFile = "https_cert_file"
|
||||
rt.TLS.HTTPS.TLSMinVersion = "tls13"
|
||||
rt.TLS.HTTPS.CipherSuites = []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}
|
||||
rt.TLS.HTTPS.VerifyIncoming = true
|
||||
|
||||
rt.TLS.GRPC.CAFile = "default_ca_file"
|
||||
rt.TLS.GRPC.CAPath = "default_ca_path"
|
||||
rt.TLS.GRPC.CertFile = "default_cert_file"
|
||||
rt.TLS.GRPC.TLSMinVersion = "tls12"
|
||||
rt.TLS.GRPC.CipherSuites = []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}
|
||||
rt.TLS.GRPC.VerifyIncoming = false
|
||||
},
|
||||
})
|
||||
run(t, testCase{
|
||||
desc: "tls.internal_rpc.verify_server_hostname implies tls.internal_rpc.verify_outgoing",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
json: []string{`
|
||||
{
|
||||
"tls": {
|
||||
"internal_rpc": {
|
||||
"verify_server_hostname": true
|
||||
}
|
||||
}
|
||||
}
|
||||
`},
|
||||
hcl: []string{`
|
||||
tls {
|
||||
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 without ports.https",
|
||||
args: []string{
|
||||
`-data-dir=` + dataDir,
|
||||
},
|
||||
json: []string{`
|
||||
{
|
||||
"tls": {
|
||||
"grpc": {
|
||||
"cert_file": "cert-1234"
|
||||
}
|
||||
}
|
||||
}
|
||||
`},
|
||||
hcl: []string{`
|
||||
tls {
|
||||
grpc {
|
||||
cert_file = "cert-1234"
|
||||
}
|
||||
}
|
||||
`},
|
||||
expected: func(rt *RuntimeConfig) {
|
||||
rt.DataDir = dataDir
|
||||
|
||||
rt.TLS.Domain = "consul."
|
||||
rt.TLS.NodeName = "thehostname"
|
||||
|
||||
rt.TLS.GRPC.CertFile = "cert-1234"
|
||||
},
|
||||
expectedWarnings: []string{
|
||||
"tls.grpc was provided but TLS will NOT be enabled on the gRPC listener without an HTTPS listener configured (e.g. via ports.https)",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (tc testCase) run(format string, dataDir string) func(t *testing.T) {
|
||||
|
@ -5382,9 +5723,6 @@ func TestLoad_FullConfig(t *testing.T) {
|
|||
EntryFetchMaxBurst: 42,
|
||||
EntryFetchRate: 0.334,
|
||||
},
|
||||
CAFile: "erA7T0PM",
|
||||
CAPath: "mQEN1Mfp",
|
||||
CertFile: "7s4QAzDk",
|
||||
CheckOutputMaxSize: checks.DefaultBufSize,
|
||||
Checks: []*structs.CheckDefinition{
|
||||
{
|
||||
|
@ -5592,7 +5930,6 @@ func TestLoad_FullConfig(t *testing.T) {
|
|||
HTTPSHandshakeTimeout: 2391 * time.Millisecond,
|
||||
HTTPSPort: 15127,
|
||||
HTTPUseCache: false,
|
||||
KeyFile: "IEkkwgIA",
|
||||
KVMaxValueSize: 1234567800,
|
||||
LeaveDrainTime: 8265 * time.Second,
|
||||
LeaveOnTerm: true,
|
||||
|
@ -5966,9 +6303,43 @@ func TestLoad_FullConfig(t *testing.T) {
|
|||
Name: "ftO6DySn", // notice this is the same as the metrics prefix
|
||||
},
|
||||
},
|
||||
TLSCipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
|
||||
TLSMinVersion: "pAOWafkR",
|
||||
TLSPreferServerCipherSuites: true,
|
||||
TLS: tlsutil.Config{
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyIncoming: true,
|
||||
CAFile: "mKl19Utl",
|
||||
CAPath: "lOp1nhPa",
|
||||
CertFile: "dfJ4oPln",
|
||||
KeyFile: "aL1Knkpo",
|
||||
TLSMinVersion: "lPo1MklP",
|
||||
CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
},
|
||||
GRPC: tlsutil.ProtocolConfig{
|
||||
VerifyIncoming: true,
|
||||
CAFile: "lOp1nhJk",
|
||||
CAPath: "fLponKpl",
|
||||
CertFile: "a674klPn",
|
||||
KeyFile: "1y4prKjl",
|
||||
TLSMinVersion: "lPo4fNkl",
|
||||
CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
|
||||
VerifyOutgoing: false,
|
||||
},
|
||||
HTTPS: tlsutil.ProtocolConfig{
|
||||
VerifyIncoming: true,
|
||||
CAFile: "7Yu1PolM",
|
||||
CAPath: "nu4PlHzn",
|
||||
CertFile: "1yrhPlMk",
|
||||
KeyFile: "1bHapOkL",
|
||||
TLSMinVersion: "mK14iOpz",
|
||||
CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
|
||||
VerifyOutgoing: true,
|
||||
},
|
||||
NodeName: "otlLxGaI",
|
||||
ServerName: "Oerr9n1G",
|
||||
Domain: "7W1xXSqd",
|
||||
EnableAgentTLSForChecks: true,
|
||||
},
|
||||
TaggedAddresses: map[string]string{
|
||||
"7MYgHrYH": "dALJAhLD",
|
||||
"h6DdBy6K": "ebrr9zZ8",
|
||||
|
@ -6000,11 +6371,6 @@ func TestLoad_FullConfig(t *testing.T) {
|
|||
UnixSocketUser: "E0nB1DwA",
|
||||
UnixSocketGroup: "8pFodrV8",
|
||||
UnixSocketMode: "E8sAwOv4",
|
||||
VerifyIncoming: true,
|
||||
VerifyIncomingHTTPS: true,
|
||||
VerifyIncomingRPC: true,
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
Watches: []map[string]interface{}{
|
||||
{
|
||||
"type": "key",
|
||||
|
@ -6038,6 +6404,18 @@ func TestLoad_FullConfig(t *testing.T) {
|
|||
deprecationWarning("acl_ttl", "acl.token_ttl"),
|
||||
deprecationWarning("acl_enable_key_list_policy", "acl.enable_key_list_policy"),
|
||||
`bootstrap_expect > 0: expecting 53 servers`,
|
||||
deprecationWarning("ca_file", "tls.defaults.ca_file"),
|
||||
deprecationWarning("ca_path", "tls.defaults.ca_path"),
|
||||
deprecationWarning("cert_file", "tls.defaults.cert_file"),
|
||||
deprecationWarning("key_file", "tls.defaults.key_file"),
|
||||
deprecationWarning("tls_cipher_suites", "tls.defaults.tls_cipher_suites"),
|
||||
deprecationWarning("tls_min_version", "tls.defaults.tls_min_version"),
|
||||
deprecationWarning("verify_incoming", "tls.defaults.verify_incoming"),
|
||||
deprecationWarning("verify_incoming_https", "tls.https.verify_incoming"),
|
||||
deprecationWarning("verify_incoming_rpc", "tls.internal_rpc.verify_incoming"),
|
||||
deprecationWarning("verify_outgoing", "tls.defaults.verify_outgoing"),
|
||||
deprecationWarning("verify_server_hostname", "tls.internal_rpc.verify_server_hostname"),
|
||||
"The 'tls_prefer_server_cipher_suites' field is deprecated and will be ignored.",
|
||||
}
|
||||
expectedWarns = append(expectedWarns, enterpriseConfigKeyWarnings...)
|
||||
|
||||
|
@ -6351,33 +6729,37 @@ func TestRuntime_APIConfigHTTPS(t *testing.T) {
|
|||
&net.TCPAddr{IP: net.ParseIP("198.18.0.2"), Port: 5678},
|
||||
},
|
||||
Datacenter: "dc-test",
|
||||
TLS: tlsutil.Config{
|
||||
HTTPS: tlsutil.ProtocolConfig{
|
||||
CAFile: "/etc/consul/ca.crt",
|
||||
CAPath: "/etc/consul/ca.dir",
|
||||
CertFile: "/etc/consul/server.crt",
|
||||
KeyFile: "/etc/consul/ssl/server.key",
|
||||
VerifyOutgoing: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cfg, err := rt.APIConfig(false)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "198.18.0.2:5678", cfg.Address)
|
||||
require.Equal(t, "https", cfg.Scheme)
|
||||
require.Equal(t, rt.CAFile, cfg.TLSConfig.CAFile)
|
||||
require.Equal(t, rt.CAPath, cfg.TLSConfig.CAPath)
|
||||
require.Equal(t, rt.TLS.HTTPS.CAFile, cfg.TLSConfig.CAFile)
|
||||
require.Equal(t, rt.TLS.HTTPS.CAPath, cfg.TLSConfig.CAPath)
|
||||
require.Equal(t, "", cfg.TLSConfig.CertFile)
|
||||
require.Equal(t, "", cfg.TLSConfig.KeyFile)
|
||||
require.Equal(t, rt.Datacenter, cfg.Datacenter)
|
||||
require.Equal(t, true, cfg.TLSConfig.InsecureSkipVerify)
|
||||
|
||||
rt.VerifyOutgoing = true
|
||||
rt.TLS.HTTPS.VerifyOutgoing = true
|
||||
cfg, err = rt.APIConfig(true)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "198.18.0.2:5678", cfg.Address)
|
||||
require.Equal(t, "https", cfg.Scheme)
|
||||
require.Equal(t, rt.CAFile, cfg.TLSConfig.CAFile)
|
||||
require.Equal(t, rt.CAPath, cfg.TLSConfig.CAPath)
|
||||
require.Equal(t, rt.CertFile, cfg.TLSConfig.CertFile)
|
||||
require.Equal(t, rt.KeyFile, cfg.TLSConfig.KeyFile)
|
||||
require.Equal(t, rt.TLS.HTTPS.CAFile, cfg.TLSConfig.CAFile)
|
||||
require.Equal(t, rt.TLS.HTTPS.CAPath, cfg.TLSConfig.CAPath)
|
||||
require.Equal(t, rt.TLS.HTTPS.CertFile, cfg.TLSConfig.CertFile)
|
||||
require.Equal(t, rt.TLS.HTTPS.KeyFile, cfg.TLSConfig.KeyFile)
|
||||
require.Equal(t, rt.Datacenter, cfg.Datacenter)
|
||||
require.Equal(t, false, cfg.TLSConfig.InsecureSkipVerify)
|
||||
}
|
||||
|
@ -6515,86 +6897,6 @@ func TestRuntime_ClientAddressAnyV6(t *testing.T) {
|
|||
require.Equal(t, "[::1]:5688", https)
|
||||
}
|
||||
|
||||
func TestRuntime_ToTLSUtilConfig(t *testing.T) {
|
||||
c := &RuntimeConfig{
|
||||
VerifyIncoming: true,
|
||||
VerifyIncomingRPC: true,
|
||||
VerifyIncomingHTTPS: true,
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: "a",
|
||||
CAPath: "b",
|
||||
CertFile: "c",
|
||||
KeyFile: "d",
|
||||
NodeName: "e",
|
||||
ServerName: "f",
|
||||
DNSDomain: "g",
|
||||
TLSMinVersion: "tls12",
|
||||
TLSCipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
|
||||
TLSPreferServerCipherSuites: true,
|
||||
EnableAgentTLSForChecks: true,
|
||||
AutoEncryptTLS: true,
|
||||
}
|
||||
r := c.ToTLSUtilConfig()
|
||||
require.True(t, r.VerifyIncoming)
|
||||
require.True(t, r.VerifyIncomingRPC)
|
||||
require.True(t, r.VerifyIncomingHTTPS)
|
||||
require.True(t, r.VerifyOutgoing)
|
||||
require.True(t, r.EnableAgentTLSForChecks)
|
||||
require.True(t, r.AutoTLS)
|
||||
require.True(t, r.VerifyServerHostname)
|
||||
require.True(t, r.PreferServerCipherSuites)
|
||||
require.Equal(t, "a", r.CAFile)
|
||||
require.Equal(t, "b", r.CAPath)
|
||||
require.Equal(t, "c", r.CertFile)
|
||||
require.Equal(t, "d", r.KeyFile)
|
||||
require.Equal(t, "e", r.NodeName)
|
||||
require.Equal(t, "f", r.ServerName)
|
||||
require.Equal(t, "g", r.Domain)
|
||||
require.Equal(t, "tls12", r.TLSMinVersion)
|
||||
require.Equal(t, []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, r.CipherSuites)
|
||||
}
|
||||
|
||||
func TestRuntime_ToTLSUtilConfig_AutoConfig(t *testing.T) {
|
||||
c := &RuntimeConfig{
|
||||
VerifyIncoming: true,
|
||||
VerifyIncomingRPC: true,
|
||||
VerifyIncomingHTTPS: true,
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: "a",
|
||||
CAPath: "b",
|
||||
CertFile: "c",
|
||||
KeyFile: "d",
|
||||
NodeName: "e",
|
||||
ServerName: "f",
|
||||
DNSDomain: "g",
|
||||
TLSMinVersion: "tls12",
|
||||
TLSCipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
|
||||
TLSPreferServerCipherSuites: true,
|
||||
EnableAgentTLSForChecks: true,
|
||||
AutoConfig: AutoConfig{Enabled: true},
|
||||
}
|
||||
r := c.ToTLSUtilConfig()
|
||||
require.True(t, r.VerifyIncoming)
|
||||
require.True(t, r.VerifyIncomingRPC)
|
||||
require.True(t, r.VerifyIncomingHTTPS)
|
||||
require.True(t, r.VerifyOutgoing)
|
||||
require.True(t, r.EnableAgentTLSForChecks)
|
||||
require.True(t, r.AutoTLS)
|
||||
require.True(t, r.VerifyServerHostname)
|
||||
require.True(t, r.PreferServerCipherSuites)
|
||||
require.Equal(t, "a", r.CAFile)
|
||||
require.Equal(t, "b", r.CAPath)
|
||||
require.Equal(t, "c", r.CertFile)
|
||||
require.Equal(t, "d", r.KeyFile)
|
||||
require.Equal(t, "e", r.NodeName)
|
||||
require.Equal(t, "f", r.ServerName)
|
||||
require.Equal(t, "g", r.Domain)
|
||||
require.Equal(t, "tls12", r.TLSMinVersion)
|
||||
require.Equal(t, []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, r.CipherSuites)
|
||||
}
|
||||
|
||||
func Test_UIPathBuilder(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
|
|
|
@ -74,14 +74,11 @@
|
|||
"BindAddr": "127.0.0.1",
|
||||
"Bootstrap": false,
|
||||
"BootstrapExpect": 0,
|
||||
"CAFile": "",
|
||||
"CAPath": "",
|
||||
"Cache": {
|
||||
"EntryFetchMaxBurst": 42,
|
||||
"EntryFetchRate": 0.334,
|
||||
"Logger": null
|
||||
},
|
||||
"CertFile": "",
|
||||
"CheckDeregisterIntervalMin": "0s",
|
||||
"CheckOutputMaxSize": 4096,
|
||||
"CheckReapInterval": "0s",
|
||||
|
@ -218,7 +215,6 @@
|
|||
"HTTPSPort": 0,
|
||||
"HTTPUseCache": false,
|
||||
"KVMaxValueSize": 1234567800000000,
|
||||
"KeyFile": "hidden",
|
||||
"LeaveDrainTime": "0s",
|
||||
"LeaveOnTerm": false,
|
||||
"Logging": {
|
||||
|
@ -354,9 +350,46 @@
|
|||
"StartJoinAddrsWAN": [],
|
||||
"SyncCoordinateIntervalMin": "0s",
|
||||
"SyncCoordinateRateTarget": 0,
|
||||
"TLSCipherSuites": [],
|
||||
"TLS": {
|
||||
"AutoTLS": false,
|
||||
"Domain": "",
|
||||
"EnableAgentTLSForChecks": false,
|
||||
"GRPC": {
|
||||
"CAFile": "",
|
||||
"CAPath": "",
|
||||
"CertFile": "",
|
||||
"CipherSuites": [],
|
||||
"KeyFile": "hidden",
|
||||
"TLSMinVersion": "",
|
||||
"TLSPreferServerCipherSuites": false,
|
||||
"VerifyIncoming": false,
|
||||
"VerifyOutgoing": false,
|
||||
"VerifyServerHostname": false
|
||||
},
|
||||
"HTTPS": {
|
||||
"CAFile": "",
|
||||
"CAPath": "",
|
||||
"CertFile": "",
|
||||
"CipherSuites": [],
|
||||
"KeyFile": "hidden",
|
||||
"TLSMinVersion": "",
|
||||
"VerifyIncoming": false,
|
||||
"VerifyOutgoing": false,
|
||||
"VerifyServerHostname": false
|
||||
},
|
||||
"InternalRPC": {
|
||||
"CAFile": "",
|
||||
"CAPath": "",
|
||||
"CertFile": "",
|
||||
"CipherSuites": [],
|
||||
"KeyFile": "hidden",
|
||||
"TLSMinVersion": "",
|
||||
"VerifyIncoming": false,
|
||||
"VerifyOutgoing": false,
|
||||
"VerifyServerHostname": false
|
||||
},
|
||||
"NodeName": "",
|
||||
"ServerName": ""
|
||||
},
|
||||
"TaggedAddresses": {},
|
||||
"Telemetry": {
|
||||
"AllowedPrefixes": [],
|
||||
|
@ -417,11 +450,6 @@
|
|||
"UnixSocketMode": "",
|
||||
"UnixSocketUser": "",
|
||||
"UseStreamingBackend": false,
|
||||
"VerifyIncoming": false,
|
||||
"VerifyIncomingHTTPS": false,
|
||||
"VerifyIncomingRPC": false,
|
||||
"VerifyOutgoing": false,
|
||||
"VerifyServerHostname": false,
|
||||
"Version": "",
|
||||
"VersionPrerelease": "",
|
||||
"Watches": []
|
||||
|
|
|
@ -647,6 +647,48 @@ telemetry {
|
|||
statsite_address = "HpFwKB8R"
|
||||
disable_compat_1.9 = true
|
||||
}
|
||||
tls {
|
||||
defaults {
|
||||
ca_file = "a5tY0opl"
|
||||
ca_path = "bN63LpXu"
|
||||
cert_file = "hB4PoxkL"
|
||||
key_file = "Po0hB1tY"
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
|
||||
tls_min_version = "yU0uIp1A"
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
}
|
||||
internal_rpc {
|
||||
ca_file = "mKl19Utl"
|
||||
ca_path = "lOp1nhPa"
|
||||
cert_file = "dfJ4oPln"
|
||||
key_file = "aL1Knkpo"
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
|
||||
tls_min_version = "lPo1MklP"
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
}
|
||||
https {
|
||||
ca_file = "7Yu1PolM"
|
||||
ca_path = "nu4PlHzn"
|
||||
cert_file = "1yrhPlMk"
|
||||
key_file = "1bHapOkL"
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
|
||||
tls_min_version = "mK14iOpz"
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
}
|
||||
grpc {
|
||||
ca_file = "lOp1nhJk"
|
||||
ca_path = "fLponKpl"
|
||||
cert_file = "a674klPn"
|
||||
key_file = "1y4prKjl"
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
|
||||
tls_min_version = "lPo4fNkl"
|
||||
verify_incoming = true
|
||||
}
|
||||
}
|
||||
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
|
||||
tls_min_version = "pAOWafkR"
|
||||
tls_prefer_server_cipher_suites = true
|
||||
|
|
|
@ -644,6 +644,47 @@
|
|||
"statsite_address": "HpFwKB8R",
|
||||
"disable_compat_1.9": true
|
||||
},
|
||||
"tls": {
|
||||
"defaults": {
|
||||
"ca_file": "a5tY0opl",
|
||||
"ca_path": "bN63LpXu",
|
||||
"cert_file": "hB4PoxkL",
|
||||
"key_file": "Po0hB1tY",
|
||||
"tls_cipher_suites": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"tls_min_version": "yU0uIp1A",
|
||||
"verify_incoming": true,
|
||||
"verify_outgoing": true
|
||||
},
|
||||
"internal_rpc": {
|
||||
"ca_file": "mKl19Utl",
|
||||
"ca_path": "lOp1nhPa",
|
||||
"cert_file": "dfJ4oPln",
|
||||
"key_file": "aL1Knkpo",
|
||||
"tls_cipher_suites": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"tls_min_version": "lPo1MklP",
|
||||
"verify_incoming": true,
|
||||
"verify_outgoing": true
|
||||
},
|
||||
"https": {
|
||||
"ca_file": "7Yu1PolM",
|
||||
"ca_path": "nu4PlHzn",
|
||||
"cert_file": "1yrhPlMk",
|
||||
"key_file": "1bHapOkL",
|
||||
"tls_cipher_suites": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"tls_min_version": "mK14iOpz",
|
||||
"verify_incoming": true,
|
||||
"verify_outgoing": true
|
||||
},
|
||||
"grpc": {
|
||||
"ca_file": "lOp1nhJk",
|
||||
"ca_path": "fLponKpl",
|
||||
"cert_file": "a674klPn",
|
||||
"key_file": "1y4prKjl",
|
||||
"tls_cipher_suites": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"tls_min_version": "lPo4fNkl",
|
||||
"verify_incoming": true
|
||||
}
|
||||
},
|
||||
"tls_cipher_suites": "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"tls_min_version": "pAOWafkR",
|
||||
"tls_prefer_server_cipher_suites": true,
|
||||
|
|
|
@ -280,19 +280,8 @@ func (ac *AutoConfig) updateTLSSettingsInConfig(_ AutoConfigOptions, resp *pbaut
|
|||
return nil
|
||||
}
|
||||
|
||||
// add in TLS configuration
|
||||
if resp.Config.TLS == nil {
|
||||
resp.Config.TLS = &pbconfig.TLS{}
|
||||
}
|
||||
|
||||
resp.Config.TLS.VerifyServerHostname = ac.tlsConfigurator.VerifyServerHostname()
|
||||
base := ac.tlsConfigurator.Base()
|
||||
resp.Config.TLS.VerifyOutgoing = base.VerifyOutgoing
|
||||
resp.Config.TLS.MinVersion = base.TLSMinVersion
|
||||
resp.Config.TLS.PreferServerCipherSuites = base.PreferServerCipherSuites
|
||||
|
||||
var err error
|
||||
resp.Config.TLS.CipherSuites, err = tlsutil.CipherString(base.CipherSuites)
|
||||
resp.Config.TLS, err = ac.tlsConfigurator.AutoConfigTLSSettings()
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,12 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
"github.com/hashicorp/memberlist"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
|
||||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/internal/go-sso/oidcauth/oidcauthtest"
|
||||
|
@ -166,14 +167,13 @@ func TestAutoConfigInitialConfiguration(t *testing.T) {
|
|||
err = ioutil.WriteFile(keyfile, []byte(key), 0600)
|
||||
require.NoError(t, err)
|
||||
|
||||
c.TLSConfig.CAFile = cafile
|
||||
c.TLSConfig.CertFile = certfile
|
||||
c.TLSConfig.KeyFile = keyfile
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.VerifyIncoming = true
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.TLSMinVersion = "tls12"
|
||||
c.TLSConfig.PreferServerCipherSuites = true
|
||||
c.TLSConfig.InternalRPC.CAFile = cafile
|
||||
c.TLSConfig.InternalRPC.CertFile = certfile
|
||||
c.TLSConfig.InternalRPC.KeyFile = keyfile
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.TLSMinVersion = "tls12"
|
||||
|
||||
c.ConnectEnabled = true
|
||||
c.AutoEncryptAllowTLS = true
|
||||
|
@ -187,9 +187,11 @@ func TestAutoConfigInitialConfiguration(t *testing.T) {
|
|||
|
||||
// TODO: use s.config.TLSConfig directly instead of creating a new one?
|
||||
conf := tlsutil.Config{
|
||||
CAFile: s.config.TLSConfig.CAFile,
|
||||
VerifyServerHostname: s.config.TLSConfig.VerifyServerHostname,
|
||||
VerifyOutgoing: s.config.TLSConfig.VerifyOutgoing,
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
CAFile: s.config.TLSConfig.InternalRPC.CAFile,
|
||||
VerifyServerHostname: s.config.TLSConfig.InternalRPC.VerifyServerHostname,
|
||||
VerifyOutgoing: s.config.TLSConfig.InternalRPC.VerifyOutgoing,
|
||||
},
|
||||
Domain: s.config.TLSConfig.Domain,
|
||||
}
|
||||
codec, err := insecureRPCClient(s, conf)
|
||||
|
@ -284,7 +286,6 @@ func TestAutoConfigInitialConfiguration(t *testing.T) {
|
|||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
MinVersion: "tls12",
|
||||
PreferServerCipherSuites: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -414,20 +415,20 @@ func TestAutoConfig_updateTLSSettingsInConfig(t *testing.T) {
|
|||
cases := map[string]testCase{
|
||||
"secure": {
|
||||
tlsConfig: tlsutil.Config{
|
||||
VerifyOutgoing: true,
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyServerHostname: true,
|
||||
VerifyOutgoing: true,
|
||||
TLSMinVersion: "tls12",
|
||||
PreferServerCipherSuites: true,
|
||||
CAFile: cafile,
|
||||
CipherSuites: parseCiphers(t, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
|
||||
},
|
||||
},
|
||||
expected: pbautoconf.AutoConfigResponse{
|
||||
Config: &pbconfig.Config{
|
||||
TLS: &pbconfig.TLS{
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
MinVersion: "tls12",
|
||||
PreferServerCipherSuites: true,
|
||||
CipherSuites: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
},
|
||||
|
@ -435,20 +436,20 @@ func TestAutoConfig_updateTLSSettingsInConfig(t *testing.T) {
|
|||
},
|
||||
"less-secure": {
|
||||
tlsConfig: tlsutil.Config{
|
||||
VerifyOutgoing: true,
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyServerHostname: false,
|
||||
VerifyOutgoing: true,
|
||||
TLSMinVersion: "tls10",
|
||||
PreferServerCipherSuites: false,
|
||||
CAFile: cafile,
|
||||
CipherSuites: parseCiphers(t, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
|
||||
},
|
||||
},
|
||||
expected: pbautoconf.AutoConfigResponse{
|
||||
Config: &pbconfig.Config{
|
||||
TLS: &pbconfig.TLS{
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: false,
|
||||
MinVersion: "tls10",
|
||||
PreferServerCipherSuites: false,
|
||||
CipherSuites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
},
|
||||
|
@ -631,13 +632,14 @@ func TestAutoConfig_updateTLSCertificatesInConfig(t *testing.T) {
|
|||
ConnectEnabled: true,
|
||||
},
|
||||
tlsConfig: tlsutil.Config{
|
||||
VerifyOutgoing: true,
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyServerHostname: true,
|
||||
VerifyOutgoing: true,
|
||||
TLSMinVersion: "tls12",
|
||||
PreferServerCipherSuites: true,
|
||||
CAFile: cafile,
|
||||
CipherSuites: parseCiphers(t, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
|
||||
},
|
||||
},
|
||||
expected: pbautoconf.AutoConfigResponse{
|
||||
CARoots: pbroots,
|
||||
ExtraCACertificates: []string{cacert},
|
||||
|
@ -649,13 +651,14 @@ func TestAutoConfig_updateTLSCertificatesInConfig(t *testing.T) {
|
|||
ConnectEnabled: true,
|
||||
},
|
||||
tlsConfig: tlsutil.Config{
|
||||
VerifyOutgoing: true,
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyServerHostname: true,
|
||||
VerifyOutgoing: true,
|
||||
TLSMinVersion: "tls12",
|
||||
PreferServerCipherSuites: true,
|
||||
CAFile: cafile,
|
||||
CipherSuites: parseCiphers(t, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
|
||||
},
|
||||
},
|
||||
opts: AutoConfigOptions{
|
||||
NodeName: "test",
|
||||
CSR: csr,
|
||||
|
|
|
@ -8,10 +8,11 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
|
||||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/testrpc"
|
||||
|
@ -38,11 +39,11 @@ func TestAutoEncryptSign(t *testing.T) {
|
|||
|
||||
tests := []test{
|
||||
{Name: "Works with defaults", Config: tlsutil.Config{}, ConnError: false},
|
||||
{Name: "Works with good root", Config: tlsutil.Config{CAFile: root}, ConnError: false},
|
||||
{Name: "VerifyOutgoing fails because of bad root", Config: tlsutil.Config{CAFile: badRoot}, ConnError: true},
|
||||
{Name: "VerifyServerHostname fails", Config: tlsutil.Config{VerifyServerHostname: true, CAFile: root}, ConnError: false, RPCError: true},
|
||||
{Name: "Works with good root", Config: tlsutil.Config{InternalRPC: tlsutil.ProtocolConfig{CAFile: root}}, ConnError: false},
|
||||
{Name: "VerifyOutgoing fails because of bad root", Config: tlsutil.Config{InternalRPC: tlsutil.ProtocolConfig{CAFile: badRoot}}, ConnError: true},
|
||||
{Name: "VerifyServerHostname fails", Config: tlsutil.Config{InternalRPC: tlsutil.ProtocolConfig{CAFile: root, VerifyServerHostname: true}}, ConnError: false, RPCError: true},
|
||||
{Name: "VerifyServerHostname succeeds", Cert: "../../test/key/ourdomain_server.cer", Key: "../../test/key/ourdomain_server.key",
|
||||
Config: tlsutil.Config{VerifyServerHostname: true, CAFile: root}, ConnError: false, RPCError: false},
|
||||
Config: tlsutil.Config{InternalRPC: tlsutil.ProtocolConfig{VerifyServerHostname: true, CAFile: root}}, ConnError: false, RPCError: false},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
|
@ -59,10 +60,10 @@ func TestAutoEncryptSign(t *testing.T) {
|
|||
c.AutoEncryptAllowTLS = true
|
||||
c.PrimaryDatacenter = "dc1"
|
||||
c.Bootstrap = true
|
||||
c.TLSConfig.CAFile = root
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.CertFile = cert
|
||||
c.TLSConfig.KeyFile = key
|
||||
c.TLSConfig.InternalRPC.CAFile = root
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.CertFile = cert
|
||||
c.TLSConfig.InternalRPC.KeyFile = key
|
||||
})
|
||||
defer os.RemoveAll(dir)
|
||||
defer s.Shutdown()
|
||||
|
|
|
@ -10,12 +10,13 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/serf/serf"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
|
||||
"github.com/hashicorp/consul/agent/grpc"
|
||||
"github.com/hashicorp/consul/agent/grpc/resolver"
|
||||
"github.com/hashicorp/consul/agent/pool"
|
||||
|
@ -447,8 +448,8 @@ func TestClient_RPC_ConsulServerPing(t *testing.T) {
|
|||
func TestClient_RPC_TLS(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, conf1 := testServerConfig(t)
|
||||
conf1.TLSConfig.VerifyIncoming = true
|
||||
conf1.TLSConfig.VerifyOutgoing = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
configureTLS(conf1)
|
||||
s1, err := newServer(t, conf1)
|
||||
if err != nil {
|
||||
|
@ -457,7 +458,7 @@ func TestClient_RPC_TLS(t *testing.T) {
|
|||
defer s1.Shutdown()
|
||||
|
||||
_, conf2 := testClientConfig(t)
|
||||
conf2.TLSConfig.VerifyOutgoing = true
|
||||
conf2.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
configureTLS(conf2)
|
||||
c1 := newClient(t, conf2)
|
||||
|
||||
|
@ -660,8 +661,8 @@ func TestClient_SnapshotRPC_TLS(t *testing.T) {
|
|||
|
||||
t.Parallel()
|
||||
_, conf1 := testServerConfig(t)
|
||||
conf1.TLSConfig.VerifyIncoming = true
|
||||
conf1.TLSConfig.VerifyOutgoing = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
configureTLS(conf1)
|
||||
s1, err := newServer(t, conf1)
|
||||
if err != nil {
|
||||
|
@ -670,7 +671,7 @@ func TestClient_SnapshotRPC_TLS(t *testing.T) {
|
|||
defer s1.Shutdown()
|
||||
|
||||
_, conf2 := testClientConfig(t)
|
||||
conf2.TLSConfig.VerifyOutgoing = true
|
||||
conf2.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
configureTLS(conf2)
|
||||
c1 := newClient(t, conf2)
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul-net-rpc/go-msgpack/codec"
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-memdb"
|
||||
"github.com/hashicorp/raft"
|
||||
|
@ -28,6 +26,9 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/consul-net-rpc/go-msgpack/codec"
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/agent/consul/state"
|
||||
|
@ -565,12 +566,12 @@ func TestRPC_TLSHandshakeTimeout(t *testing.T) {
|
|||
|
||||
dir1, s1 := testServerWithConfig(t, func(c *Config) {
|
||||
c.RPCHandshakeTimeout = 10 * time.Millisecond
|
||||
c.TLSConfig.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.CertFile = "../../test/hostname/Alice.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/hostname/Alice.key"
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.VerifyIncoming = true
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/hostname/Alice.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/hostname/Alice.key"
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
})
|
||||
defer os.RemoveAll(dir1)
|
||||
defer s1.Shutdown()
|
||||
|
@ -661,12 +662,12 @@ func TestRPC_PreventsTLSNesting(t *testing.T) {
|
|||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
dir1, s1 := testServerWithConfig(t, func(c *Config) {
|
||||
c.TLSConfig.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.CertFile = "../../test/hostname/Alice.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/hostname/Alice.key"
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.VerifyIncoming = false // saves us getting client cert setup
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/hostname/Alice.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/hostname/Alice.key"
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = false // saves us getting client cert setup
|
||||
c.TLSConfig.Domain = "consul"
|
||||
})
|
||||
defer os.RemoveAll(dir1)
|
||||
|
@ -818,12 +819,12 @@ func TestRPC_RPCMaxConnsPerClient(t *testing.T) {
|
|||
dir1, s1 := testServerWithConfig(t, func(c *Config) {
|
||||
c.RPCMaxConnsPerClient = 2
|
||||
if tc.tlsEnabled {
|
||||
c.TLSConfig.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.CertFile = "../../test/hostname/Alice.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/hostname/Alice.key"
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.VerifyIncoming = false // saves us getting client cert setup
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/hostname/Alice.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/hostname/Alice.key"
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = false // saves us getting client cert setup
|
||||
c.TLSConfig.Domain = "consul"
|
||||
}
|
||||
})
|
||||
|
@ -1416,11 +1417,11 @@ func TestRPC_AuthorizeRaftRPC(t *testing.T) {
|
|||
|
||||
_, srv := testServerWithConfig(t, func(c *Config) {
|
||||
c.TLSConfig.Domain = "consul." // consul. is the default value in agent/config
|
||||
c.TLSConfig.CAFile = filepath.Join(dir, "ca.pem")
|
||||
c.TLSConfig.CertFile = filepath.Join(dir, "srv1-server.dc1.consul.pem")
|
||||
c.TLSConfig.KeyFile = filepath.Join(dir, "srv1-server.dc1.consul.key")
|
||||
c.TLSConfig.VerifyIncoming = true
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.CAFile = filepath.Join(dir, "ca.pem")
|
||||
c.TLSConfig.InternalRPC.CertFile = filepath.Join(dir, "srv1-server.dc1.consul.pem")
|
||||
c.TLSConfig.InternalRPC.KeyFile = filepath.Join(dir, "srv1-server.dc1.consul.key")
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
// Enable Auto-Encrypt so that Connect CA roots are added to the
|
||||
// tlsutil.Configurator.
|
||||
c.AutoEncryptAllowTLS = true
|
||||
|
@ -1509,11 +1510,13 @@ func TestRPC_AuthorizeRaftRPC(t *testing.T) {
|
|||
certPath := tc.setupCert(t)
|
||||
|
||||
cfg := tlsutil.Config{
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: filepath.Join(dir, "ca.pem"),
|
||||
CertFile: certPath + ".pem",
|
||||
KeyFile: certPath + ".key",
|
||||
},
|
||||
Domain: "consul",
|
||||
}
|
||||
c, err := tlsutil.NewConfigurator(cfg, hclog.New(nil))
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"go.etcd.io/bbolt"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||
connlimit "github.com/hashicorp/go-connlimit"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-memdb"
|
||||
|
@ -33,6 +32,8 @@ import (
|
|||
"golang.org/x/time/rate"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/consul/authmethod"
|
||||
"github.com/hashicorp/consul/agent/consul/authmethod/ssoauth"
|
||||
|
|
|
@ -115,7 +115,7 @@ func (s *Server) setupSerfConfig(opts setupSerfOptions) (*serf.Config, error) {
|
|||
conf.Tags["nonvoter"] = "1"
|
||||
conf.Tags["read_replica"] = "1"
|
||||
}
|
||||
if s.config.TLSConfig.CAPath != "" || s.config.TLSConfig.CAFile != "" {
|
||||
if s.config.TLSConfig.InternalRPC.CAPath != "" || s.config.TLSConfig.InternalRPC.CAFile != "" {
|
||||
conf.Tags["use_tls"] = "1"
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,11 @@ import (
|
|||
|
||||
"github.com/hashicorp/consul/ipaddr"
|
||||
|
||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||
|
||||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/agent/metadata"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
|
@ -75,9 +76,9 @@ func testServerACLConfig(c *Config) {
|
|||
}
|
||||
|
||||
func configureTLS(config *Config) {
|
||||
config.TLSConfig.CAFile = "../../test/ca/root.cer"
|
||||
config.TLSConfig.CertFile = "../../test/key/ourdomain.cer"
|
||||
config.TLSConfig.KeyFile = "../../test/key/ourdomain.key"
|
||||
config.TLSConfig.InternalRPC.CAFile = "../../test/ca/root.cer"
|
||||
config.TLSConfig.InternalRPC.CertFile = "../../test/key/ourdomain.cer"
|
||||
config.TLSConfig.InternalRPC.KeyFile = "../../test/key/ourdomain.key"
|
||||
}
|
||||
|
||||
var id int64
|
||||
|
@ -709,12 +710,12 @@ func TestServer_JoinWAN_viaMeshGateway(t *testing.T) {
|
|||
c.PrimaryDatacenter = "dc1"
|
||||
c.Bootstrap = true
|
||||
// tls
|
||||
c.TLSConfig.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.CertFile = "../../test/hostname/Bob.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/hostname/Bob.key"
|
||||
c.TLSConfig.VerifyIncoming = true
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/hostname/Bob.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/hostname/Bob.key"
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
// wanfed
|
||||
c.ConnectMeshGatewayWANFederationEnabled = true
|
||||
})
|
||||
|
@ -728,12 +729,12 @@ func TestServer_JoinWAN_viaMeshGateway(t *testing.T) {
|
|||
c.PrimaryDatacenter = "dc1"
|
||||
c.Bootstrap = true
|
||||
// tls
|
||||
c.TLSConfig.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.CertFile = "../../test/hostname/Betty.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/hostname/Betty.key"
|
||||
c.TLSConfig.VerifyIncoming = true
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/hostname/Betty.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/hostname/Betty.key"
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
// wanfed
|
||||
c.ConnectMeshGatewayWANFederationEnabled = true
|
||||
})
|
||||
|
@ -747,12 +748,12 @@ func TestServer_JoinWAN_viaMeshGateway(t *testing.T) {
|
|||
c.PrimaryDatacenter = "dc1"
|
||||
c.Bootstrap = true
|
||||
// tls
|
||||
c.TLSConfig.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.CertFile = "../../test/hostname/Bonnie.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/hostname/Bonnie.key"
|
||||
c.TLSConfig.VerifyIncoming = true
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.VerifyServerHostname = true
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/hostname/CertAuth.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/hostname/Bonnie.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/hostname/Bonnie.key"
|
||||
c.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.VerifyServerHostname = true
|
||||
// wanfed
|
||||
c.ConnectMeshGatewayWANFederationEnabled = true
|
||||
})
|
||||
|
@ -1136,8 +1137,8 @@ func TestServer_JoinLAN_TLS(t *testing.T) {
|
|||
|
||||
t.Parallel()
|
||||
_, conf1 := testServerConfig(t)
|
||||
conf1.TLSConfig.VerifyIncoming = true
|
||||
conf1.TLSConfig.VerifyOutgoing = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
configureTLS(conf1)
|
||||
s1, err := newServer(t, conf1)
|
||||
if err != nil {
|
||||
|
@ -1148,8 +1149,8 @@ func TestServer_JoinLAN_TLS(t *testing.T) {
|
|||
|
||||
_, conf2 := testServerConfig(t)
|
||||
conf2.Bootstrap = false
|
||||
conf2.TLSConfig.VerifyIncoming = true
|
||||
conf2.TLSConfig.VerifyOutgoing = true
|
||||
conf2.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
conf2.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
configureTLS(conf2)
|
||||
s2, err := newServer(t, conf2)
|
||||
if err != nil {
|
||||
|
@ -1410,9 +1411,9 @@ func TestServer_TLSToNoTLS(t *testing.T) {
|
|||
// Add a second server with TLS configured
|
||||
dir2, s2 := testServerWithConfig(t, func(c *Config) {
|
||||
c.Bootstrap = false
|
||||
c.TLSConfig.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/client_certs/server.key"
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/client_certs/server.key"
|
||||
})
|
||||
defer os.RemoveAll(dir2)
|
||||
defer s2.Shutdown()
|
||||
|
@ -1442,10 +1443,10 @@ func TestServer_TLSForceOutgoingToNoTLS(t *testing.T) {
|
|||
// Add a second server with TLS and VerifyOutgoing set
|
||||
dir2, s2 := testServerWithConfig(t, func(c *Config) {
|
||||
c.Bootstrap = false
|
||||
c.TLSConfig.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/client_certs/server.key"
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/client_certs/server.key"
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
})
|
||||
defer os.RemoveAll(dir2)
|
||||
defer s2.Shutdown()
|
||||
|
@ -1464,10 +1465,10 @@ func TestServer_TLSToFullVerify(t *testing.T) {
|
|||
t.Parallel()
|
||||
// Set up a server with TLS and VerifyIncoming set
|
||||
dir1, s1 := testServerWithConfig(t, func(c *Config) {
|
||||
c.TLSConfig.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/client_certs/server.key"
|
||||
c.TLSConfig.VerifyOutgoing = true
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/client_certs/server.key"
|
||||
c.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
})
|
||||
defer os.RemoveAll(dir1)
|
||||
defer s1.Shutdown()
|
||||
|
@ -1477,9 +1478,9 @@ func TestServer_TLSToFullVerify(t *testing.T) {
|
|||
// Add a second server with TLS configured
|
||||
dir2, s2 := testServerWithConfig(t, func(c *Config) {
|
||||
c.Bootstrap = false
|
||||
c.TLSConfig.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.KeyFile = "../../test/client_certs/server.key"
|
||||
c.TLSConfig.InternalRPC.CAFile = "../../test/client_certs/rootca.crt"
|
||||
c.TLSConfig.InternalRPC.CertFile = "../../test/client_certs/server.crt"
|
||||
c.TLSConfig.InternalRPC.KeyFile = "../../test/client_certs/server.key"
|
||||
})
|
||||
defer os.RemoveAll(dir2)
|
||||
defer s2.Shutdown()
|
||||
|
|
|
@ -6,9 +6,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/agent/pool"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
|
|
|
@ -29,8 +29,8 @@ func TestSubscribeBackend_IntegrationWithServer_TLSEnabled(t *testing.T) {
|
|||
// TODO(rb): add tests for the wanfed/alpn variations
|
||||
|
||||
_, conf1 := testServerConfig(t)
|
||||
conf1.TLSConfig.VerifyIncoming = true
|
||||
conf1.TLSConfig.VerifyOutgoing = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
conf1.RPCConfig.EnableStreaming = true
|
||||
configureTLS(conf1)
|
||||
server, err := newServer(t, conf1)
|
||||
|
@ -161,11 +161,11 @@ func TestSubscribeBackend_IntegrationWithServer_TLSReload(t *testing.T) {
|
|||
|
||||
// Set up a server with initially bad certificates.
|
||||
_, conf1 := testServerConfig(t)
|
||||
conf1.TLSConfig.VerifyIncoming = true
|
||||
conf1.TLSConfig.VerifyOutgoing = true
|
||||
conf1.TLSConfig.CAFile = "../../test/ca/root.cer"
|
||||
conf1.TLSConfig.CertFile = "../../test/key/ssl-cert-snakeoil.pem"
|
||||
conf1.TLSConfig.KeyFile = "../../test/key/ssl-cert-snakeoil.key"
|
||||
conf1.TLSConfig.InternalRPC.VerifyIncoming = true
|
||||
conf1.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
conf1.TLSConfig.InternalRPC.CAFile = "../../test/ca/root.cer"
|
||||
conf1.TLSConfig.InternalRPC.CertFile = "../../test/key/ssl-cert-snakeoil.pem"
|
||||
conf1.TLSConfig.InternalRPC.KeyFile = "../../test/key/ssl-cert-snakeoil.key"
|
||||
conf1.RPCConfig.EnableStreaming = true
|
||||
|
||||
server, err := newServer(t, conf1)
|
||||
|
@ -199,8 +199,8 @@ func TestSubscribeBackend_IntegrationWithServer_TLSReload(t *testing.T) {
|
|||
|
||||
// Reload the server with valid certs
|
||||
newConf := server.config.TLSConfig
|
||||
newConf.CertFile = "../../test/key/ourdomain.cer"
|
||||
newConf.KeyFile = "../../test/key/ourdomain.key"
|
||||
newConf.InternalRPC.CertFile = "../../test/key/ourdomain.cer"
|
||||
newConf.InternalRPC.KeyFile = "../../test/key/ourdomain.key"
|
||||
server.tlsConfigurator.Update(newConf)
|
||||
|
||||
// Try the subscribe call again
|
||||
|
@ -212,7 +212,7 @@ func TestSubscribeBackend_IntegrationWithServer_TLSReload(t *testing.T) {
|
|||
}
|
||||
|
||||
func clientConfigVerifyOutgoing(config *Config) {
|
||||
config.TLSConfig.VerifyOutgoing = true
|
||||
config.TLSConfig.InternalRPC.VerifyOutgoing = true
|
||||
}
|
||||
|
||||
// retryFailedConn forces the ClientConn to reset its backoff timer and retry the connection,
|
||||
|
|
|
@ -143,11 +143,13 @@ func TestNewDialer_IntegrationWithTLSEnabledHandler(t *testing.T) {
|
|||
registerWithGRPC(t, res)
|
||||
|
||||
tlsConf, err := tlsutil.NewConfigurator(tlsutil.Config{
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyIncoming: true,
|
||||
VerifyOutgoing: true,
|
||||
CAFile: "../../test/hostname/CertAuth.crt",
|
||||
CertFile: "../../test/hostname/Alice.crt",
|
||||
KeyFile: "../../test/hostname/Alice.key",
|
||||
VerifyOutgoing: true,
|
||||
},
|
||||
}, hclog.New(nil))
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -188,12 +190,14 @@ func TestNewDialer_IntegrationWithTLSEnabledHandler_viaMeshGateway(t *testing.T)
|
|||
registerWithGRPC(t, res)
|
||||
|
||||
tlsConf, err := tlsutil.NewConfigurator(tlsutil.Config{
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyIncoming: true,
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: "../../test/hostname/CertAuth.crt",
|
||||
CertFile: "../../test/hostname/Bob.crt",
|
||||
KeyFile: "../../test/hostname/Bob.key",
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
},
|
||||
Domain: "consul",
|
||||
NodeName: "bob",
|
||||
}, hclog.New(nil))
|
||||
|
@ -216,12 +220,14 @@ func TestNewDialer_IntegrationWithTLSEnabledHandler_viaMeshGateway(t *testing.T)
|
|||
t.Cleanup(srv.shutdown)
|
||||
|
||||
clientTLSConf, err := tlsutil.NewConfigurator(tlsutil.Config{
|
||||
InternalRPC: tlsutil.ProtocolConfig{
|
||||
VerifyIncoming: true,
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: "../../test/hostname/CertAuth.crt",
|
||||
CertFile: "../../test/hostname/Betty.crt",
|
||||
KeyFile: "../../test/hostname/Betty.key",
|
||||
VerifyOutgoing: true,
|
||||
VerifyServerHostname: true,
|
||||
},
|
||||
Domain: "consul",
|
||||
NodeName: "betty",
|
||||
}, hclog.New(nil))
|
||||
|
|
|
@ -14,11 +14,12 @@ import (
|
|||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
|
||||
"github.com/hashicorp/consul/agent/grpc/internal/testservice"
|
||||
"github.com/hashicorp/consul/agent/metadata"
|
||||
"github.com/hashicorp/consul/agent/pool"
|
||||
"github.com/hashicorp/consul/tlsutil"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
)
|
||||
|
||||
type testServer struct {
|
||||
|
|
|
@ -11,9 +11,10 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/yamux"
|
||||
|
||||
msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc"
|
||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||
"github.com/hashicorp/yamux"
|
||||
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
|
|
|
@ -93,7 +93,7 @@ func NewBaseDeps(configLoader ConfigLoader, logOut io.Writer) (BaseDeps, error)
|
|||
return d, fmt.Errorf("failed to initialize telemetry: %w", err)
|
||||
}
|
||||
|
||||
d.TLSConfigurator, err = tlsutil.NewConfigurator(cfg.ToTLSUtilConfig(), d.Logger)
|
||||
d.TLSConfigurator, err = tlsutil.NewConfigurator(cfg.TLS, d.Logger)
|
||||
if err != nil {
|
||||
return d, err
|
||||
}
|
||||
|
|
|
@ -222,12 +222,10 @@ func NewGRPCServer(s *Server, tlsConfigurator *tlsutil.Configurator) *grpc.Serve
|
|||
recovery.StreamServerInterceptor(recoveryOpts...),
|
||||
),
|
||||
}
|
||||
if tlsConfigurator != nil {
|
||||
if tlsConfigurator.Cert() != nil {
|
||||
if tlsConfigurator != nil && tlsConfigurator.GRPCTLSConfigured() {
|
||||
creds := credentials.NewTLS(tlsConfigurator.IncomingGRPCConfig())
|
||||
opts = append(opts, grpc.Creds(creds))
|
||||
}
|
||||
}
|
||||
srv := grpc.NewServer(opts...)
|
||||
envoy_discovery_v3.RegisterAggregatedDiscoveryServiceServer(srv, s)
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ func (c *cmd) run(args []string) int {
|
|||
ui.Info(fmt.Sprintf(" Cluster Addr: %v (LAN: %d, WAN: %d)", config.AdvertiseAddrLAN,
|
||||
config.SerfPortLAN, config.SerfPortWAN))
|
||||
ui.Info(fmt.Sprintf(" Encrypt: Gossip: %v, TLS-Outgoing: %v, TLS-Incoming: %v, Auto-Encrypt-TLS: %t",
|
||||
config.EncryptKey != "", config.VerifyOutgoing, config.VerifyIncoming, config.AutoEncryptTLS || config.AutoEncryptAllowTLS))
|
||||
config.EncryptKey != "", config.TLS.InternalRPC.VerifyOutgoing, config.TLS.InternalRPC.VerifyIncoming, config.AutoEncryptTLS || config.AutoEncryptAllowTLS))
|
||||
// Enable log streaming
|
||||
ui.Output("")
|
||||
ui.Output("Log data will now stream in as it occurs:\n")
|
||||
|
|
|
@ -256,7 +256,9 @@ type TLS struct {
|
|||
VerifyServerHostname bool `protobuf:"varint,2,opt,name=VerifyServerHostname,proto3" json:"VerifyServerHostname,omitempty"`
|
||||
CipherSuites string `protobuf:"bytes,3,opt,name=CipherSuites,proto3" json:"CipherSuites,omitempty"`
|
||||
MinVersion string `protobuf:"bytes,4,opt,name=MinVersion,proto3" json:"MinVersion,omitempty"`
|
||||
PreferServerCipherSuites bool `protobuf:"varint,5,opt,name=PreferServerCipherSuites,proto3" json:"PreferServerCipherSuites,omitempty"`
|
||||
// Deprecated_PreferServerCipherSuites is deprecated. It is no longer
|
||||
// populated and should be ignored by clients.
|
||||
Deprecated_PreferServerCipherSuites bool `protobuf:"varint,5,opt,name=Deprecated_PreferServerCipherSuites,json=DeprecatedPreferServerCipherSuites,proto3" json:"Deprecated_PreferServerCipherSuites,omitempty"` // Deprecated: Do not use.
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -323,9 +325,10 @@ func (m *TLS) GetMinVersion() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *TLS) GetPreferServerCipherSuites() bool {
|
||||
// Deprecated: Do not use.
|
||||
func (m *TLS) GetDeprecated_PreferServerCipherSuites() bool {
|
||||
if m != nil {
|
||||
return m.PreferServerCipherSuites
|
||||
return m.Deprecated_PreferServerCipherSuites
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -687,59 +690,59 @@ func init() {
|
|||
func init() { proto.RegisterFile("proto/pbconfig/config.proto", fileDescriptor_aefa824db7b74d77) }
|
||||
|
||||
var fileDescriptor_aefa824db7b74d77 = []byte{
|
||||
// 823 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x55, 0xdd, 0x6e, 0xe3, 0x44,
|
||||
0x14, 0xc6, 0xf1, 0xd6, 0x6d, 0x26, 0xb0, 0xda, 0x9d, 0x5d, 0x8a, 0xc5, 0x4f, 0x88, 0x2c, 0xb4,
|
||||
0x2a, 0x08, 0xb5, 0xa8, 0x08, 0x04, 0x88, 0x9b, 0x34, 0x59, 0x41, 0xd8, 0x34, 0x44, 0x76, 0x58,
|
||||
0x24, 0x6e, 0x90, 0xe3, 0x9c, 0x24, 0x23, 0x9c, 0x19, 0x6b, 0x3c, 0xe9, 0xca, 0xaf, 0xc0, 0x13,
|
||||
0xf0, 0x2e, 0xbc, 0x00, 0x77, 0xf0, 0x08, 0x50, 0x5e, 0x64, 0x75, 0x66, 0xc6, 0x8e, 0xdd, 0x26,
|
||||
0x57, 0xc9, 0xf9, 0xbe, 0x6f, 0xce, 0x9c, 0x33, 0xe7, 0xc7, 0xe4, 0xbd, 0x4c, 0x0a, 0x25, 0x2e,
|
||||
0xb2, 0x79, 0x22, 0xf8, 0x92, 0xad, 0x2e, 0xcc, 0xcf, 0xb9, 0x46, 0xa9, 0x67, 0xac, 0xe0, 0xef,
|
||||
0x16, 0xf1, 0x06, 0xfa, 0x2f, 0xed, 0x12, 0x32, 0x8c, 0x55, 0x9c, 0x00, 0x57, 0x20, 0x7d, 0xa7,
|
||||
0xe7, 0x9c, 0xb5, 0xc3, 0x1a, 0x42, 0x3f, 0x25, 0x8f, 0xa7, 0x92, 0x6d, 0x62, 0x59, 0xd4, 0x64,
|
||||
0x2d, 0x2d, 0xbb, 0x4f, 0xd0, 0x77, 0xc9, 0xc9, 0x44, 0x2c, 0x60, 0x12, 0x6f, 0xc0, 0x77, 0xb5,
|
||||
0xa8, 0xb2, 0x69, 0x8f, 0x74, 0x22, 0x58, 0x6d, 0x80, 0x2b, 0x4d, 0x3f, 0xd0, 0x74, 0x1d, 0xa2,
|
||||
0xef, 0x93, 0xf6, 0x34, 0x96, 0x8a, 0x29, 0x26, 0xb8, 0xdf, 0xd6, 0xfc, 0x0e, 0xa0, 0x1f, 0x10,
|
||||
0xb7, 0x3f, 0x18, 0xfb, 0x47, 0x3d, 0xe7, 0xac, 0x73, 0xd9, 0x39, 0xb7, 0x89, 0xf5, 0x07, 0xe3,
|
||||
0x10, 0x71, 0xfa, 0x05, 0xe9, 0xf4, 0xb7, 0x4a, 0x3c, 0xe7, 0x89, 0x2c, 0x32, 0xe5, 0x7b, 0x5a,
|
||||
0xf6, 0xa4, 0x92, 0xed, 0xa8, 0xb0, 0xae, 0xa3, 0xcf, 0x88, 0xf7, 0x9d, 0xc8, 0x73, 0x96, 0xf9,
|
||||
0xc7, 0xfa, 0xc4, 0xc3, 0xf2, 0x84, 0x41, 0x43, 0xcb, 0xe2, 0xed, 0xb3, 0x71, 0xe4, 0x9f, 0x34,
|
||||
0x6f, 0x9f, 0x8d, 0xa3, 0x10, 0xf1, 0x60, 0x59, 0xba, 0xa1, 0x5f, 0x11, 0x62, 0x7d, 0x63, 0x16,
|
||||
0x8e, 0xd6, 0xfb, 0x4d, 0xa7, 0x3b, 0x3e, 0xac, 0x69, 0x69, 0x40, 0xde, 0x0c, 0x41, 0xc9, 0xe2,
|
||||
0x07, 0xc1, 0xf8, 0xb8, 0x3f, 0xf1, 0x5b, 0x3d, 0xf7, 0xac, 0x1d, 0x36, 0xb0, 0x40, 0x91, 0x47,
|
||||
0x77, 0x7d, 0xd0, 0x47, 0xc4, 0x7d, 0x01, 0x85, 0xad, 0x1d, 0xfe, 0xa5, 0xcf, 0xc8, 0xc3, 0x97,
|
||||
0x20, 0xd9, 0xb2, 0x18, 0xf1, 0x44, 0x6c, 0x18, 0x5f, 0xe9, 0x8a, 0x9d, 0x84, 0x77, 0xd0, 0x9d,
|
||||
0xee, 0xc7, 0xad, 0x5a, 0x09, 0xd4, 0xb9, 0x75, 0x5d, 0x89, 0x06, 0xff, 0x39, 0x3a, 0xfb, 0x3d,
|
||||
0x7a, 0x67, 0x9f, 0x9e, 0x5e, 0x92, 0xa7, 0x06, 0x89, 0x40, 0xde, 0x80, 0xfc, 0x5e, 0xe4, 0x8a,
|
||||
0x63, 0xcd, 0x4d, 0x14, 0x7b, 0x39, 0xcc, 0x7e, 0xc0, 0xb2, 0x35, 0xc8, 0x68, 0xcb, 0x14, 0xe4,
|
||||
0xb6, 0x7d, 0x1a, 0x18, 0x36, 0xeb, 0x35, 0xe3, 0x2f, 0x41, 0xe6, 0xf8, 0xb6, 0xa6, 0x83, 0x6a,
|
||||
0x08, 0xfd, 0x86, 0xf8, 0x53, 0x09, 0x4b, 0x90, 0xc6, 0x77, 0xc3, 0xdf, 0x91, 0xbe, 0xfb, 0x20,
|
||||
0x1f, 0xfc, 0xe9, 0xea, 0xfe, 0xa2, 0x3e, 0x39, 0x7e, 0xce, 0xe3, 0x79, 0x0a, 0x0b, 0x9b, 0x5c,
|
||||
0x69, 0xea, 0xf6, 0x14, 0x29, 0x4b, 0x8a, 0xd9, 0x6c, 0x6c, 0x47, 0x60, 0x07, 0xe0, 0xb9, 0x50,
|
||||
0xa4, 0x80, 0x9c, 0x09, 0xbd, 0x34, 0x71, 0x28, 0x66, 0xe2, 0x37, 0xe0, 0x48, 0x99, 0x98, 0x2b,
|
||||
0x5b, 0x8f, 0x9f, 0x78, 0xc5, 0x8d, 0x1b, 0x1d, 0x23, 0x8e, 0x5f, 0x85, 0xd0, 0x8f, 0xc8, 0x5b,
|
||||
0x43, 0x58, 0xc6, 0xdb, 0x54, 0x59, 0x89, 0xa7, 0x25, 0x4d, 0x90, 0x7e, 0x46, 0x9e, 0x98, 0x20,
|
||||
0x5f, 0x40, 0x31, 0x66, 0x79, 0xa9, 0x3d, 0xd6, 0xf1, 0xef, 0xa3, 0xe8, 0xc7, 0xc4, 0xd3, 0x31,
|
||||
0xe4, 0xb6, 0xa3, 0x1f, 0xd7, 0xe6, 0xc9, 0x10, 0xa1, 0x15, 0xd0, 0xaf, 0xc9, 0xe9, 0x10, 0x32,
|
||||
0x09, 0x49, 0xac, 0x60, 0xf1, 0xeb, 0x90, 0xe5, 0xfa, 0x35, 0x30, 0x19, 0x3d, 0xa2, 0x57, 0x2d,
|
||||
0xdf, 0x09, 0xdf, 0xde, 0x29, 0x6a, 0x02, 0xfa, 0x25, 0x39, 0x35, 0x97, 0x6b, 0x57, 0x53, 0xac,
|
||||
0x52, 0xae, 0x80, 0x27, 0xe0, 0x13, 0x1d, 0xda, 0x01, 0x16, 0xf3, 0xb9, 0x8e, 0xa6, 0xd6, 0xd3,
|
||||
0x95, 0x10, 0x2a, 0x57, 0x32, 0xce, 0xfc, 0x8e, 0xc9, 0x67, 0x0f, 0x15, 0xfc, 0xde, 0x22, 0xed,
|
||||
0x2a, 0x74, 0x5c, 0x5a, 0x23, 0xce, 0x14, 0x8b, 0xd3, 0xeb, 0x98, 0xc7, 0x2b, 0xc0, 0x0d, 0x63,
|
||||
0xe7, 0xe3, 0x3e, 0x81, 0x8b, 0x29, 0x84, 0x2c, 0x65, 0x49, 0xac, 0x47, 0xd6, 0x54, 0xb6, 0x0e,
|
||||
0x61, 0x15, 0xfa, 0x2b, 0xe0, 0x2a, 0x84, 0x44, 0xdc, 0x80, 0x2c, 0x6c, 0x85, 0x9b, 0x20, 0x76,
|
||||
0x80, 0x2d, 0x8b, 0x2d, 0x73, 0x69, 0xd2, 0xa7, 0xe4, 0x48, 0x4b, 0x6d, 0x81, 0x8d, 0x41, 0x7f,
|
||||
0x26, 0xa7, 0x26, 0x8a, 0x05, 0xb6, 0x23, 0x4b, 0x60, 0x2a, 0xc5, 0x0d, 0x5b, 0x80, 0xf4, 0xbd,
|
||||
0x9e, 0x7b, 0xd6, 0xb9, 0xfc, 0xb0, 0x56, 0x93, 0x3b, 0x0a, 0x9d, 0x67, 0x78, 0xe0, 0x78, 0xf0,
|
||||
0x13, 0x79, 0xe7, 0xc0, 0x11, 0xec, 0xb7, 0x7e, 0x92, 0x40, 0x9e, 0x0b, 0x39, 0x1a, 0x96, 0xeb,
|
||||
0x7e, 0x87, 0x60, 0xaf, 0x46, 0x90, 0x48, 0x50, 0xa3, 0xa1, 0x7d, 0x88, 0xca, 0x0e, 0x58, 0x63,
|
||||
0xc3, 0xe2, 0xda, 0xc1, 0x8d, 0x68, 0x86, 0x44, 0xaf, 0x87, 0x53, 0xe2, 0x0d, 0x27, 0x51, 0x54,
|
||||
0xad, 0x2e, 0x6b, 0x61, 0xfa, 0xa3, 0x29, 0xc2, 0xae, 0x86, 0x8d, 0x81, 0x57, 0xf5, 0xd3, 0x54,
|
||||
0xbc, 0x42, 0x27, 0x0f, 0xb4, 0x93, 0xca, 0xbe, 0xfa, 0xf6, 0xaf, 0xdb, 0xae, 0xf3, 0xcf, 0x6d,
|
||||
0xd7, 0xf9, 0xf7, 0xb6, 0xeb, 0xfc, 0xf1, 0x7f, 0xf7, 0x8d, 0x5f, 0x3e, 0x59, 0x31, 0xb5, 0xde,
|
||||
0xce, 0xcf, 0x13, 0xb1, 0xb9, 0x58, 0xc7, 0xf9, 0x9a, 0x25, 0x42, 0x66, 0xf8, 0x75, 0xcb, 0xb7,
|
||||
0xe9, 0x45, 0xf3, 0x9b, 0x37, 0xf7, 0xb4, 0xfd, 0xf9, 0xeb, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5d,
|
||||
0x66, 0xca, 0x39, 0x0c, 0x07, 0x00, 0x00,
|
||||
// 831 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x55, 0xdd, 0x8e, 0xdb, 0x44,
|
||||
0x14, 0xc6, 0x71, 0xeb, 0xdd, 0x4c, 0xa0, 0x6a, 0xa7, 0x65, 0xb1, 0xf8, 0x09, 0x91, 0x41, 0xd5,
|
||||
0x82, 0xd0, 0x2e, 0x5a, 0x04, 0x02, 0x89, 0x9b, 0xec, 0xa6, 0x82, 0xd0, 0x6c, 0x88, 0xec, 0x50,
|
||||
0x24, 0x6e, 0x90, 0xe3, 0x9c, 0x24, 0x23, 0x9c, 0x19, 0x6b, 0x3c, 0xd9, 0xca, 0xaf, 0xc0, 0x13,
|
||||
0xf0, 0x2e, 0xbc, 0x00, 0x77, 0xf0, 0x08, 0x68, 0x79, 0x0b, 0xae, 0xaa, 0x33, 0x33, 0xfe, 0xdb,
|
||||
0x26, 0x57, 0xc9, 0xf9, 0xbe, 0x6f, 0xce, 0x9c, 0x33, 0xe7, 0xc7, 0xe4, 0xbd, 0x4c, 0x0a, 0x25,
|
||||
0xce, 0xb3, 0x45, 0x22, 0xf8, 0x8a, 0xad, 0xcf, 0xcd, 0xcf, 0x99, 0x46, 0xa9, 0x67, 0xac, 0xe0,
|
||||
0xef, 0x0e, 0xf1, 0xae, 0xf4, 0x5f, 0xda, 0x27, 0x64, 0x14, 0xab, 0x38, 0x01, 0xae, 0x40, 0xfa,
|
||||
0xce, 0xc0, 0x39, 0xed, 0x86, 0x0d, 0x84, 0x7e, 0x46, 0x1e, 0xcd, 0x24, 0xdb, 0xc6, 0xb2, 0x68,
|
||||
0xc8, 0x3a, 0x5a, 0xf6, 0x3a, 0x41, 0xdf, 0x25, 0xc7, 0x53, 0xb1, 0x84, 0x69, 0xbc, 0x05, 0xdf,
|
||||
0xd5, 0xa2, 0xca, 0xa6, 0x03, 0xd2, 0x8b, 0x60, 0xbd, 0x05, 0xae, 0x34, 0x7d, 0x4f, 0xd3, 0x4d,
|
||||
0x88, 0xbe, 0x4f, 0xba, 0xb3, 0x58, 0x2a, 0xa6, 0x98, 0xe0, 0x7e, 0x57, 0xf3, 0x35, 0x40, 0x3f,
|
||||
0x20, 0xee, 0xf0, 0x6a, 0xe2, 0xdf, 0x1f, 0x38, 0xa7, 0xbd, 0x8b, 0xde, 0x99, 0x4d, 0x6c, 0x78,
|
||||
0x35, 0x09, 0x11, 0xa7, 0x5f, 0x92, 0xde, 0x70, 0xa7, 0xc4, 0x33, 0x9e, 0xc8, 0x22, 0x53, 0xbe,
|
||||
0xa7, 0x65, 0x8f, 0x2b, 0x59, 0x4d, 0x85, 0x4d, 0x1d, 0x7d, 0x4a, 0xbc, 0xef, 0x44, 0x9e, 0xb3,
|
||||
0xcc, 0x3f, 0xd2, 0x27, 0x1e, 0x94, 0x27, 0x0c, 0x1a, 0x5a, 0x16, 0x6f, 0x9f, 0x4f, 0x22, 0xff,
|
||||
0xb8, 0x7d, 0xfb, 0x7c, 0x12, 0x85, 0x88, 0x07, 0xab, 0xd2, 0x0d, 0xfd, 0x9a, 0x10, 0xeb, 0x1b,
|
||||
0xb3, 0x70, 0xb4, 0xde, 0x6f, 0x3b, 0xad, 0xf9, 0xb0, 0xa1, 0xa5, 0x01, 0x79, 0x33, 0x04, 0x25,
|
||||
0x8b, 0x1f, 0x04, 0xe3, 0x93, 0xe1, 0xd4, 0xef, 0x0c, 0xdc, 0xd3, 0x6e, 0xd8, 0xc2, 0x02, 0x45,
|
||||
0x1e, 0xde, 0xf5, 0x41, 0x1f, 0x12, 0xf7, 0x39, 0x14, 0xb6, 0x76, 0xf8, 0x97, 0x3e, 0x25, 0x0f,
|
||||
0x5e, 0x80, 0x64, 0xab, 0x62, 0xcc, 0x13, 0xb1, 0x65, 0x7c, 0xad, 0x2b, 0x76, 0x1c, 0xde, 0x41,
|
||||
0x6b, 0xdd, 0x8f, 0x3b, 0xb5, 0x16, 0xa8, 0x73, 0x9b, 0xba, 0x12, 0x0d, 0xfe, 0x77, 0x74, 0xf6,
|
||||
0x7b, 0xf4, 0xce, 0x3e, 0x3d, 0xbd, 0x20, 0x4f, 0x0c, 0x12, 0x81, 0xbc, 0x01, 0xf9, 0xbd, 0xc8,
|
||||
0x15, 0xc7, 0x9a, 0x9b, 0x28, 0xf6, 0x72, 0x98, 0xfd, 0x15, 0xcb, 0x36, 0x20, 0xa3, 0x1d, 0x53,
|
||||
0x90, 0xdb, 0xf6, 0x69, 0x61, 0xd8, 0xac, 0xd7, 0x8c, 0xbf, 0x00, 0x99, 0xe3, 0xdb, 0x9a, 0x0e,
|
||||
0x6a, 0x20, 0x34, 0x22, 0x1f, 0x8d, 0x20, 0x93, 0x90, 0xc4, 0x0a, 0x96, 0xbf, 0xce, 0x24, 0xac,
|
||||
0x40, 0x9a, 0x6b, 0x5a, 0xae, 0xb1, 0x85, 0x8e, 0x2f, 0x3b, 0xbe, 0x13, 0x06, 0xb5, 0xfc, 0x90,
|
||||
0x3a, 0xf8, 0xd3, 0xd5, 0x8d, 0x47, 0x7d, 0x72, 0xf4, 0x8c, 0xc7, 0x8b, 0x14, 0x96, 0x36, 0xeb,
|
||||
0xd2, 0xd4, 0x7d, 0x2b, 0x52, 0x96, 0x14, 0xf3, 0xf9, 0xc4, 0xce, 0x46, 0x0d, 0xe0, 0xb9, 0x50,
|
||||
0xa4, 0x80, 0x9c, 0xc9, 0xa9, 0x34, 0x71, 0x5a, 0xe6, 0xe2, 0x37, 0xe0, 0x48, 0x99, 0x64, 0x2a,
|
||||
0x5b, 0xcf, 0xa5, 0x78, 0xc9, 0x8d, 0x1b, 0x1d, 0x31, 0xce, 0x65, 0x85, 0xd0, 0x8f, 0xc9, 0x5b,
|
||||
0x23, 0x58, 0xc5, 0xbb, 0x54, 0x59, 0x89, 0xa7, 0x25, 0x6d, 0x90, 0x7e, 0x4e, 0x1e, 0x9b, 0x20,
|
||||
0x9f, 0x43, 0x31, 0x61, 0x79, 0xa9, 0x3d, 0xd2, 0xf1, 0xef, 0xa3, 0xe8, 0x27, 0xc4, 0xd3, 0x31,
|
||||
0xe4, 0xb6, 0xd5, 0x1f, 0x35, 0x06, 0xcd, 0x10, 0xa1, 0x15, 0xd0, 0x6f, 0xc8, 0x49, 0xe3, 0xb5,
|
||||
0x47, 0x2c, 0xd7, 0xaf, 0x81, 0xc9, 0xe8, 0xd9, 0xd5, 0x0f, 0xfc, 0x76, 0xad, 0x68, 0x08, 0xe8,
|
||||
0x57, 0xe4, 0xc4, 0x5c, 0xae, 0x5d, 0xcd, 0xb0, 0x7c, 0xb9, 0x02, 0x9e, 0x80, 0x4f, 0x74, 0x68,
|
||||
0x07, 0x58, 0xcc, 0xe7, 0x3a, 0x9a, 0x59, 0x4f, 0x97, 0x42, 0xa8, 0x5c, 0xc9, 0x38, 0xf3, 0x7b,
|
||||
0x26, 0x9f, 0x3d, 0x54, 0xf0, 0x7b, 0x87, 0x74, 0xab, 0xd0, 0x71, 0x9b, 0x8d, 0x39, 0x53, 0x2c,
|
||||
0x4e, 0xaf, 0x63, 0x1e, 0xaf, 0x01, 0x57, 0x8f, 0x1d, 0x9c, 0xd7, 0x09, 0xdc, 0x58, 0x21, 0x64,
|
||||
0x29, 0x4b, 0x62, 0x3d, 0xcb, 0xa6, 0xb2, 0x4d, 0x08, 0xab, 0x30, 0x5c, 0x03, 0x57, 0x21, 0x24,
|
||||
0xe2, 0x06, 0x64, 0x61, 0x2b, 0xdc, 0x06, 0xb1, 0x03, 0x6c, 0x59, 0x6c, 0x99, 0x4b, 0x93, 0x3e,
|
||||
0x21, 0xf7, 0xb5, 0xd4, 0x16, 0xd8, 0x18, 0xf4, 0x67, 0x72, 0x62, 0xa2, 0x58, 0x62, 0x3b, 0xb2,
|
||||
0x04, 0x66, 0x52, 0xdc, 0xb0, 0x25, 0x48, 0xdf, 0x1b, 0xb8, 0xa7, 0xbd, 0x8b, 0x0f, 0x1b, 0x35,
|
||||
0xb9, 0xa3, 0xd0, 0x79, 0x86, 0x07, 0x8e, 0x07, 0x3f, 0x91, 0x77, 0x0e, 0x1c, 0xc1, 0x7e, 0x1b,
|
||||
0x26, 0x09, 0xe4, 0xb9, 0x90, 0xe3, 0x51, 0xf9, 0x1d, 0xa8, 0x11, 0xec, 0xd5, 0x08, 0x12, 0x09,
|
||||
0x6a, 0x3c, 0xb2, 0x0f, 0x51, 0xd9, 0x01, 0x6b, 0xad, 0x5e, 0xdc, 0x47, 0xb8, 0x2a, 0xcd, 0x90,
|
||||
0xe8, 0xbd, 0x71, 0x42, 0xbc, 0xd1, 0x34, 0x8a, 0xaa, 0x9d, 0x66, 0x2d, 0x4c, 0x7f, 0x3c, 0x43,
|
||||
0xd8, 0xd5, 0xb0, 0x31, 0xf0, 0xaa, 0x61, 0x9a, 0x8a, 0x97, 0xe8, 0xe4, 0x9e, 0x76, 0x52, 0xd9,
|
||||
0x97, 0xdf, 0xfe, 0x75, 0xdb, 0x77, 0xfe, 0xb9, 0xed, 0x3b, 0xff, 0xde, 0xf6, 0x9d, 0x3f, 0xfe,
|
||||
0xeb, 0xbf, 0xf1, 0xcb, 0xa7, 0x6b, 0xa6, 0x36, 0xbb, 0xc5, 0x59, 0x22, 0xb6, 0xe7, 0x9b, 0x38,
|
||||
0xdf, 0xb0, 0x44, 0xc8, 0x0c, 0x3f, 0x7b, 0xf9, 0x2e, 0x3d, 0x6f, 0x7f, 0x0c, 0x17, 0x9e, 0xb6,
|
||||
0xbf, 0x78, 0x15, 0x00, 0x00, 0xff, 0xff, 0x4f, 0xaf, 0xda, 0x68, 0x25, 0x07, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Config) Marshal() (dAtA []byte, err error) {
|
||||
|
@ -978,9 +981,9 @@ func (m *TLS) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
i -= len(m.XXX_unrecognized)
|
||||
copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
if m.PreferServerCipherSuites {
|
||||
if m.Deprecated_PreferServerCipherSuites {
|
||||
i--
|
||||
if m.PreferServerCipherSuites {
|
||||
if m.Deprecated_PreferServerCipherSuites {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
|
@ -1451,7 +1454,7 @@ func (m *TLS) Size() (n int) {
|
|||
if l > 0 {
|
||||
n += 1 + l + sovConfig(uint64(l))
|
||||
}
|
||||
if m.PreferServerCipherSuites {
|
||||
if m.Deprecated_PreferServerCipherSuites {
|
||||
n += 2
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
|
@ -2338,7 +2341,7 @@ func (m *TLS) Unmarshal(dAtA []byte) error {
|
|||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field PreferServerCipherSuites", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Deprecated_PreferServerCipherSuites", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
|
@ -2355,7 +2358,7 @@ func (m *TLS) Unmarshal(dAtA []byte) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
m.PreferServerCipherSuites = bool(v != 0)
|
||||
m.Deprecated_PreferServerCipherSuites = bool(v != 0)
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipConfig(dAtA[iNdEx:])
|
||||
|
|
|
@ -32,7 +32,9 @@ message TLS {
|
|||
bool VerifyServerHostname = 2;
|
||||
string CipherSuites = 3;
|
||||
string MinVersion = 4;
|
||||
bool PreferServerCipherSuites = 5;
|
||||
// Deprecated_PreferServerCipherSuites is deprecated. It is no longer
|
||||
// populated and should be ignored by clients.
|
||||
bool Deprecated_PreferServerCipherSuites = 5 [deprecated = true];
|
||||
}
|
||||
|
||||
message ACL {
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/hashicorp/consul/logging"
|
||||
"github.com/hashicorp/consul/proto/pbconfig"
|
||||
)
|
||||
|
||||
// ALPNWrapper is a function that is used to wrap a non-TLS connection and
|
||||
|
@ -44,42 +45,14 @@ var tlsLookup = map[string]uint16{
|
|||
"tls13": tls.VersionTLS13,
|
||||
}
|
||||
|
||||
// Config used to create tls.Config
|
||||
type Config struct {
|
||||
// ProtocolConfig contains configuration for a given protocol.
|
||||
type ProtocolConfig struct {
|
||||
// VerifyIncoming is used to verify the authenticity of incoming
|
||||
// connections. This means that TCP requests are forbidden, only
|
||||
// allowing for TLS. TLS connections must match a provided certificate
|
||||
// authority. This can be used to force client auth.
|
||||
VerifyIncoming bool
|
||||
|
||||
// VerifyIncomingRPC is used to verify the authenticity of incoming RPC
|
||||
// connections. This means that TCP requests are forbidden, only
|
||||
// allowing for TLS. TLS connections must match a provided certificate
|
||||
// authority. This can be used to force client auth.
|
||||
VerifyIncomingRPC bool
|
||||
|
||||
// VerifyIncomingHTTPS is used to verify the authenticity of incoming
|
||||
// HTTPS connections. This means that TCP requests are forbidden, only
|
||||
// allowing for TLS. TLS connections must match a provided certificate
|
||||
// authority. This can be used to force client auth.
|
||||
VerifyIncomingHTTPS bool
|
||||
|
||||
// VerifyOutgoing is used to verify the authenticity of outgoing
|
||||
// connections. This means that TLS requests are used, and TCP
|
||||
// requests are not made. TLS connections must match a provided
|
||||
// certificate authority. This is used to verify authenticity of server
|
||||
// nodes.
|
||||
VerifyOutgoing bool
|
||||
|
||||
// VerifyServerHostname is used to enable hostname verification of
|
||||
// servers. This ensures that the certificate presented is valid for
|
||||
// server.<datacenter>.<domain>. This prevents a compromised client
|
||||
// from being restarted as a server, and then intercepting request
|
||||
// traffic as well as being added as a raft peer. This should be
|
||||
// enabled by default with VerifyOutgoing, but for legacy reasons we
|
||||
// cannot break existing clients.
|
||||
VerifyServerHostname bool
|
||||
|
||||
// CAFile is a path to a certificate authority file. This is used with
|
||||
// VerifyIncoming or VerifyOutgoing to verify the TLS connection.
|
||||
CAFile string
|
||||
|
@ -97,6 +70,62 @@ type Config struct {
|
|||
// connections. Must be provided to serve TLS connections.
|
||||
KeyFile string
|
||||
|
||||
// TLSMinVersion is the minimum accepted TLS version that can be used.
|
||||
TLSMinVersion string
|
||||
|
||||
// CipherSuites is the list of TLS cipher suites to use.
|
||||
//
|
||||
// The values should be a list of the following values:
|
||||
//
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
|
||||
// TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
// TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||
// TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
|
||||
// TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
// TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||
// TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
//
|
||||
// todo(fs): IMHO, we should also support the raw 0xNNNN values from
|
||||
// todo(fs): https://golang.org/pkg/crypto/tls/#pkg-constants
|
||||
// todo(fs): since they are standardized by IANA.
|
||||
CipherSuites []uint16
|
||||
|
||||
// VerifyOutgoing is used to verify the authenticity of outgoing
|
||||
// connections. This means that TLS requests are used, and TCP
|
||||
// requests are not made. TLS connections must match a provided
|
||||
// certificate authority. This is used to verify authenticity of server
|
||||
// nodes.
|
||||
//
|
||||
// Note: this setting doesn't apply to the gRPC configuration, as Consul
|
||||
// makes no outgoing connections using this protocol.
|
||||
VerifyOutgoing bool
|
||||
|
||||
// VerifyServerHostname is used to enable hostname verification of
|
||||
// servers. This ensures that the certificate presented is valid for
|
||||
// server.<datacenter>.<domain>. This prevents a compromised client
|
||||
// from being restarted as a server, and then intercepting request
|
||||
// traffic as well as being added as a raft peer. This should be
|
||||
// enabled by default with VerifyOutgoing, but for legacy reasons we
|
||||
// cannot break existing clients.
|
||||
//
|
||||
// Note: this setting only applies to the Internal RPC configuration.
|
||||
VerifyServerHostname bool
|
||||
}
|
||||
|
||||
// Config configures the Configurator.
|
||||
type Config struct {
|
||||
// InternalRPC is used to configure the internal multiplexed RPC protocol.
|
||||
InternalRPC ProtocolConfig
|
||||
|
||||
// GRPC is used to configure the external (e.g. xDS) gRPC protocol.
|
||||
GRPC ProtocolConfig
|
||||
|
||||
// HTTPS is used to configure the external HTTPS protocol.
|
||||
HTTPS ProtocolConfig
|
||||
|
||||
// Node name is the name we use to advertise. Defaults to hostname.
|
||||
NodeName string
|
||||
|
||||
|
@ -107,16 +136,6 @@ type Config struct {
|
|||
// Domain is the Consul TLD being used. Defaults to "consul."
|
||||
Domain string
|
||||
|
||||
// TLSMinVersion is the minimum accepted TLS version that can be used.
|
||||
TLSMinVersion string
|
||||
|
||||
// CipherSuites is the list of TLS cipher suites to use.
|
||||
CipherSuites []uint16
|
||||
|
||||
// PreferServerCipherSuites specifies whether to prefer the server's
|
||||
// ciphersuite over the client ciphersuites.
|
||||
PreferServerCipherSuites bool
|
||||
|
||||
// EnableAgentTLSForChecks is used to apply the agent's TLS settings in
|
||||
// order to configure the HTTP client used for health checks. Enabling
|
||||
// this allows HTTP checks to present a client certificate and verify
|
||||
|
@ -151,27 +170,30 @@ func SpecificDC(dc string, tlsWrap DCWrapper) Wrapper {
|
|||
}
|
||||
}
|
||||
|
||||
// autoTLS stores configuration that is received from the auto-encrypt or
|
||||
// auto-config features.
|
||||
type autoTLS struct {
|
||||
extraCAPems []string
|
||||
connectCAPems []string
|
||||
// protocolConfig contains the loaded state (e.g. x509 certificates) for a given
|
||||
// ProtocolConfig.
|
||||
type protocolConfig struct {
|
||||
// cert is the TLS certificate configured manually by the cert_file/key_file
|
||||
// options in the configuration file.
|
||||
cert *tls.Certificate
|
||||
verifyServerHostname bool
|
||||
}
|
||||
|
||||
// manual stores the TLS CA and cert received from Configurator.Update which
|
||||
// generally comes from the agent configuration.
|
||||
type manual struct {
|
||||
caPems []string
|
||||
cert *tls.Certificate
|
||||
// caPool containing only the caPems. This CertPool should be used instead of
|
||||
// the Configurator.caPool when only the Agent TLS CA is allowed.
|
||||
caPool *x509.CertPool
|
||||
// manualCAPEMs contains the PEM-encoded CA certificates provided manually by
|
||||
// the ca_file/ca_path options in the configuration file.
|
||||
manualCAPEMs []string
|
||||
|
||||
// manualCAPool is a pool containing only manualCAPEM, for cases where it is
|
||||
// not appropriate to trust the Connect CA (e.g. when verifying server identity
|
||||
// in AuthorizeServerConn).
|
||||
manualCAPool *x509.CertPool
|
||||
|
||||
// combinedCAPool is a pool containing both manualCAPEMs and the certificates
|
||||
// received from auto-config/auto-encrypt.
|
||||
combinedCAPool *x509.CertPool
|
||||
}
|
||||
|
||||
// Configurator provides tls.Config and net.Dial wrappers to enable TLS for
|
||||
// clients and servers, for both HTTPS and RPC requests.
|
||||
// clients and servers, for internal RPC, and external gRPC and HTTPS connections.
|
||||
//
|
||||
// Configurator receives an initial TLS configuration from agent configuration,
|
||||
// and receives updates from config reloads, auto-encrypt, and auto-config.
|
||||
type Configurator struct {
|
||||
|
@ -183,13 +205,23 @@ type Configurator struct {
|
|||
// lock synchronizes access to all fields on this struct except for logger and version.
|
||||
lock sync.RWMutex
|
||||
base *Config
|
||||
autoTLS autoTLS
|
||||
manual manual
|
||||
caPool *x509.CertPool
|
||||
// peerDatacenterUseTLS is a map of DC name to a bool indicating if the DC
|
||||
// uses TLS for RPC requests.
|
||||
peerDatacenterUseTLS map[string]bool
|
||||
|
||||
grpc protocolConfig
|
||||
https protocolConfig
|
||||
internalRPC protocolConfig
|
||||
|
||||
// autoTLS stores configuration that is received from the auto-encrypt or
|
||||
// auto-config features.
|
||||
autoTLS struct {
|
||||
extraCAPems []string
|
||||
connectCAPems []string
|
||||
cert *tls.Certificate
|
||||
verifyServerHostname bool
|
||||
}
|
||||
|
||||
// logger is not protected by a lock. It must never be changed after
|
||||
// Configurator is created.
|
||||
logger hclog.Logger
|
||||
|
@ -215,11 +247,12 @@ func NewConfigurator(config Config, logger hclog.Logger) (*Configurator, error)
|
|||
return c, nil
|
||||
}
|
||||
|
||||
// ManualCAPems returns the currently loaded CAs in PEM format.
|
||||
// ManualCAPems returns the currently loaded CAs for the internal RPC protocol
|
||||
// in PEM format. It is used in the auto-config/auto-encrypt endpoints.
|
||||
func (c *Configurator) ManualCAPems() []string {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.manual.caPems
|
||||
return c.internalRPC.manualCAPEMs
|
||||
}
|
||||
|
||||
// Update updates the internal configuration which is used to generate
|
||||
|
@ -229,36 +262,92 @@ func (c *Configurator) Update(config Config) error {
|
|||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
cert, err := loadKeyPair(config.CertFile, config.KeyFile)
|
||||
grpc, err := c.loadProtocolConfig(config, config.GRPC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pems, err := LoadCAs(config.CAFile, config.CAPath)
|
||||
|
||||
https, err := c.loadProtocolConfig(config, config.HTTPS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
caPool, err := newX509CertPool(pems, c.autoTLS.extraCAPems, c.autoTLS.connectCAPems)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = validateConfig(config, caPool, cert); err != nil {
|
||||
return err
|
||||
}
|
||||
manualCAPool, err := newX509CertPool(pems)
|
||||
|
||||
internalRPC, err := c.loadProtocolConfig(config, config.InternalRPC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.base = &config
|
||||
c.manual.cert = cert
|
||||
c.manual.caPems = pems
|
||||
c.manual.caPool = manualCAPool
|
||||
c.caPool = caPool
|
||||
c.grpc = *grpc
|
||||
c.https = *https
|
||||
c.internalRPC = *internalRPC
|
||||
|
||||
atomic.AddUint64(&c.version, 1)
|
||||
c.log("Update")
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadProtocolConfig loads the certificates etc. for a given ProtocolConfig
|
||||
// and performs validation.
|
||||
func (c *Configurator) loadProtocolConfig(base Config, lc ProtocolConfig) (*protocolConfig, error) {
|
||||
if min := lc.TLSMinVersion; min != "" {
|
||||
if _, ok := tlsLookup[min]; !ok {
|
||||
versions := strings.Join(tlsVersions(), ", ")
|
||||
return nil, fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [%s]", min, versions)
|
||||
}
|
||||
}
|
||||
|
||||
cert, err := loadKeyPair(lc.CertFile, lc.KeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pems, err := LoadCAs(lc.CAFile, lc.CAPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
manualPool, err := newX509CertPool(pems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
combinedPool, err := newX509CertPool(pems, c.autoTLS.connectCAPems, c.autoTLS.extraCAPems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if lc.VerifyIncoming {
|
||||
// Both auto-config and auto-encrypt require verifying the connection from the
|
||||
// client to the server for secure operation. In order to be able to verify the
|
||||
// server's certificate we must have some CA certs already provided. Therefore,
|
||||
// even though both of those features can push down extra CA certificates which
|
||||
// could be used to verify incoming connections, we still must consider it an
|
||||
// error if none are provided in the initial configuration as those features
|
||||
// cannot be successfully enabled without providing CA certificates to use those
|
||||
// features.
|
||||
if combinedPool == nil {
|
||||
return nil, fmt.Errorf("VerifyIncoming set but no CA certificates were provided")
|
||||
}
|
||||
|
||||
// We will use the auto_encrypt/auto_config cert for TLS in the incoming APIs
|
||||
// when available. Therefore the check here will ensure that either we enabled
|
||||
// one of those two features or a certificate and key were provided manually
|
||||
if cert == nil && !base.AutoTLS {
|
||||
return nil, fmt.Errorf("VerifyIncoming requires either a Cert and Key pair in the configuration file, or auto_encrypt/auto_config be enabled")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we have a CA if VerifyOutgoing is set.
|
||||
if lc.VerifyOutgoing && combinedPool == nil {
|
||||
return nil, fmt.Errorf("VerifyOutgoing set but no CA certificates were provided")
|
||||
}
|
||||
|
||||
return &protocolConfig{
|
||||
cert: cert,
|
||||
manualCAPEMs: pems,
|
||||
manualCAPool: manualPool,
|
||||
combinedCAPool: combinedPool,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateAutoTLSCA updates the autoEncrypt.caPems. This is supposed to be called
|
||||
// from the server in order to be able to accept TLS connections with TLS
|
||||
// certificates.
|
||||
|
@ -267,15 +356,30 @@ func (c *Configurator) UpdateAutoTLSCA(connectCAPems []string) error {
|
|||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
pool, err := newX509CertPool(c.manual.caPems, c.autoTLS.extraCAPems, connectCAPems)
|
||||
makePool := func(l protocolConfig) (*x509.CertPool, error) {
|
||||
return newX509CertPool(l.manualCAPEMs, c.autoTLS.extraCAPems, connectCAPems)
|
||||
}
|
||||
|
||||
// Make all of the pools up-front (before assigning anything) so that if any of
|
||||
// them fails, we aren't left in a half-applied state.
|
||||
internalRPCPool, err := makePool(c.internalRPC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = validateConfig(*c.base, pool, c.manual.cert); err != nil {
|
||||
grpcPool, err := makePool(c.grpc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
httpsPool, err := makePool(c.https)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.autoTLS.connectCAPems = connectCAPems
|
||||
c.caPool = pool
|
||||
c.internalRPC.combinedCAPool = internalRPCPool
|
||||
c.grpc.combinedCAPool = grpcPool
|
||||
c.https.combinedCAPool = httpsPool
|
||||
|
||||
atomic.AddUint64(&c.version, 1)
|
||||
c.log("UpdateAutoTLSCA")
|
||||
return nil
|
||||
|
@ -308,15 +412,33 @@ func (c *Configurator) UpdateAutoTLS(manualCAPems, connectCAPems []string, pub,
|
|||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
pool, err := newX509CertPool(c.manual.caPems, manualCAPems, connectCAPems)
|
||||
makePool := func(l protocolConfig) (*x509.CertPool, error) {
|
||||
return newX509CertPool(l.manualCAPEMs, manualCAPems, connectCAPems)
|
||||
}
|
||||
|
||||
// Make all of the pools up-front (before assigning anything) so that if any of
|
||||
// them fails, we aren't left in a half-applied state.
|
||||
internalRPCPool, err := makePool(c.internalRPC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
grpcPool, err := makePool(c.grpc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
httpsPool, err := makePool(c.https)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.autoTLS.extraCAPems = manualCAPems
|
||||
c.autoTLS.connectCAPems = connectCAPems
|
||||
c.autoTLS.cert = &cert
|
||||
c.caPool = pool
|
||||
c.autoTLS.verifyServerHostname = verifyServerHostname
|
||||
c.internalRPC.combinedCAPool = internalRPCPool
|
||||
c.grpc.combinedCAPool = grpcPool
|
||||
c.https.combinedCAPool = httpsPool
|
||||
|
||||
atomic.AddUint64(&c.version, 1)
|
||||
c.log("UpdateAutoTLS")
|
||||
return nil
|
||||
|
@ -368,46 +490,6 @@ func newX509CertPool(groups ...[]string) (*x509.CertPool, error) {
|
|||
return pool, nil
|
||||
}
|
||||
|
||||
// validateConfig checks that config is valid and does not conflict with the pool
|
||||
// or cert.
|
||||
func validateConfig(config Config, pool *x509.CertPool, cert *tls.Certificate) error {
|
||||
// Check if a minimum TLS version was set
|
||||
if config.TLSMinVersion != "" {
|
||||
if _, ok := tlsLookup[config.TLSMinVersion]; !ok {
|
||||
versions := strings.Join(tlsVersions(), ", ")
|
||||
return fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [%s]", config.TLSMinVersion, versions)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we have a CA if VerifyOutgoing is set
|
||||
if config.VerifyOutgoing && pool == nil {
|
||||
return fmt.Errorf("VerifyOutgoing set, and no CA certificate provided!")
|
||||
}
|
||||
|
||||
// Ensure we have a CA and cert if VerifyIncoming is set
|
||||
if config.anyVerifyIncoming() {
|
||||
if pool == nil {
|
||||
// both auto-config and auto-encrypt require verifying the connection from the client to the server for secure
|
||||
// operation. In order to be able to verify the servers certificate we must have some CA certs already provided.
|
||||
// Therefore, even though both of those features can push down extra CA certificates which could be used to
|
||||
// verify incoming connections, we still must consider it an error if none are provided in the initial configuration
|
||||
// as those features cannot be successfully enabled without providing CA certificates to use those features.
|
||||
return fmt.Errorf("VerifyIncoming set but no CA certificates were provided")
|
||||
}
|
||||
|
||||
// We will use the auto_encrypt/auto_config cert for TLS in the incoming APIs when available. Therefore the check
|
||||
// here will ensure that either we enabled one of those two features or a certificate and key were provided manually
|
||||
if cert == nil && !config.AutoTLS {
|
||||
return fmt.Errorf("VerifyIncoming requires either a Cert and Key pair in the configuration file, or auto_encrypt/auto_config be enabled")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Config) anyVerifyIncoming() bool {
|
||||
return c.VerifyIncoming || c.VerifyIncomingRPC || c.VerifyIncomingHTTPS
|
||||
}
|
||||
|
||||
func loadKeyPair(certFile, keyFile string) (*tls.Certificate, error) {
|
||||
if certFile == "" || keyFile == "" {
|
||||
return nil, nil
|
||||
|
@ -465,33 +547,43 @@ func LoadCAs(caFile, caPath string) ([]string, error) {
|
|||
return pems, nil
|
||||
}
|
||||
|
||||
// internalRPCTLSConfig generates a *tls.Config for the internal RPC protocol.
|
||||
//
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) internalRPCTLSConfig(verifyIncoming bool) *tls.Config {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
config := c.commonTLSConfig(
|
||||
c.internalRPC,
|
||||
c.base.InternalRPC,
|
||||
verifyIncoming,
|
||||
)
|
||||
config.InsecureSkipVerify = !c.base.InternalRPC.VerifyServerHostname
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// commonTLSConfig generates a *tls.Config from the base configuration the
|
||||
// Configurator has. It accepts an additional flag in case a config is needed
|
||||
// for incoming TLS connections.
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) commonTLSConfig(verifyIncoming bool) *tls.Config {
|
||||
// this needs to be outside of RLock because it acquires an RLock itself
|
||||
verifyServerHostname := c.VerifyServerHostname()
|
||||
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: !verifyServerHostname,
|
||||
}
|
||||
func (c *Configurator) commonTLSConfig(state protocolConfig, cfg ProtocolConfig, verifyIncoming bool) *tls.Config {
|
||||
var tlsConfig tls.Config
|
||||
|
||||
// Set the cipher suites
|
||||
if len(c.base.CipherSuites) != 0 {
|
||||
tlsConfig.CipherSuites = c.base.CipherSuites
|
||||
if len(cfg.CipherSuites) != 0 {
|
||||
tlsConfig.CipherSuites = cfg.CipherSuites
|
||||
}
|
||||
|
||||
tlsConfig.PreferServerCipherSuites = c.base.PreferServerCipherSuites
|
||||
|
||||
// GetCertificate is used when acting as a server and responding to
|
||||
// client requests. Default to the manually configured cert, but allow
|
||||
// autoEncrypt cert too so that a client can encrypt incoming
|
||||
// connections without having a manual cert configured.
|
||||
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
return c.Cert(), nil
|
||||
if state.cert != nil {
|
||||
return state.cert, nil
|
||||
}
|
||||
return c.autoTLS.cert, nil
|
||||
}
|
||||
|
||||
// GetClientCertificate is used when acting as a client and responding
|
||||
|
@ -500,7 +592,7 @@ func (c *Configurator) commonTLSConfig(verifyIncoming bool) *tls.Config {
|
|||
tlsConfig.GetClientCertificate = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
|
||||
cert := c.autoTLS.cert
|
||||
if cert == nil {
|
||||
cert = c.manual.cert
|
||||
cert = state.cert
|
||||
}
|
||||
|
||||
if cert == nil {
|
||||
|
@ -512,39 +604,53 @@ func (c *Configurator) commonTLSConfig(verifyIncoming bool) *tls.Config {
|
|||
return cert, nil
|
||||
}
|
||||
|
||||
tlsConfig.ClientCAs = c.caPool
|
||||
tlsConfig.RootCAs = c.caPool
|
||||
tlsConfig.ClientCAs = state.combinedCAPool
|
||||
tlsConfig.RootCAs = state.combinedCAPool
|
||||
|
||||
// This is possible because tlsLookup also contains "" with golang's
|
||||
// default (tls10). And because the initial check makes sure the
|
||||
// version correctly matches.
|
||||
tlsConfig.MinVersion = tlsLookup[c.base.TLSMinVersion]
|
||||
tlsConfig.MinVersion = tlsLookup[cfg.TLSMinVersion]
|
||||
|
||||
// Set ClientAuth if necessary
|
||||
if verifyIncoming {
|
||||
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
}
|
||||
|
||||
return tlsConfig
|
||||
return &tlsConfig
|
||||
}
|
||||
|
||||
// Cert returns the certificate used for connections on the internal RPC protocol.
|
||||
//
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) Cert() *tls.Certificate {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
cert := c.manual.cert
|
||||
cert := c.internalRPC.cert
|
||||
if cert == nil {
|
||||
cert = c.autoTLS.cert
|
||||
}
|
||||
return cert
|
||||
}
|
||||
|
||||
// VerifyIncomingRPC returns true if the configuration has enabled either
|
||||
// VerifyIncoming, or VerifyIncomingRPC
|
||||
// GRPCTLSConfigured returns whether there's a TLS certificate configured for
|
||||
// gRPC (either manually or by auto-config/auto-encrypt). It is checked, along
|
||||
// with the presence of an HTTPS port, to determine whether to enable TLS on
|
||||
// incoming gRPC connections.
|
||||
//
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) GRPCTLSConfigured() bool {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.grpc.cert != nil || c.autoTLS.cert != nil
|
||||
}
|
||||
|
||||
// VerifyIncomingRPC returns true if we should verify incoming connnections to
|
||||
// the internal RPC protocol.
|
||||
func (c *Configurator) VerifyIncomingRPC() bool {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.base.VerifyIncoming || c.base.VerifyIncomingRPC
|
||||
return c.base.InternalRPC.VerifyIncoming
|
||||
}
|
||||
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
|
@ -553,15 +659,15 @@ func (c *Configurator) outgoingRPCTLSEnabled() bool {
|
|||
defer c.lock.RUnlock()
|
||||
|
||||
// use TLS if AutoEncrypt or VerifyOutgoing are enabled.
|
||||
return c.base.AutoTLS || c.base.VerifyOutgoing
|
||||
return c.base.AutoTLS || c.base.InternalRPC.VerifyOutgoing
|
||||
}
|
||||
|
||||
// MutualTLSCapable returns true if Configurator has a CA and a local TLS
|
||||
// certificate configured.
|
||||
// MutualTLSCapable returns true if Configurator has a CA and a local TL
|
||||
// certificate configured on the internal RPC protocol.
|
||||
func (c *Configurator) MutualTLSCapable() bool {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.caPool != nil && (c.autoTLS.cert != nil || c.manual.cert != nil)
|
||||
return c.internalRPC.combinedCAPool != nil && (c.autoTLS.cert != nil || c.internalRPC.cert != nil)
|
||||
}
|
||||
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
|
@ -571,13 +677,14 @@ func (c *Configurator) verifyOutgoing() bool {
|
|||
|
||||
// If AutoEncryptTLS is enabled and there is a CA, then verify
|
||||
// outgoing.
|
||||
if c.base.AutoTLS && c.caPool != nil {
|
||||
if c.base.AutoTLS && c.internalRPC.combinedCAPool != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return c.base.VerifyOutgoing
|
||||
return c.base.InternalRPC.VerifyOutgoing
|
||||
}
|
||||
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) ServerSNI(dc, nodeName string) string {
|
||||
// Strip the trailing '.' from the domain if any
|
||||
domain := strings.TrimSuffix(c.domain(), ".")
|
||||
|
@ -610,19 +717,45 @@ func (c *Configurator) serverNameOrNodeName() string {
|
|||
func (c *Configurator) VerifyServerHostname() bool {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.base.VerifyServerHostname || c.autoTLS.verifyServerHostname
|
||||
return c.base.InternalRPC.VerifyServerHostname || c.autoTLS.verifyServerHostname
|
||||
}
|
||||
|
||||
// IncomingGRPCConfig generates a *tls.Config for incoming GRPC connections.
|
||||
func (c *Configurator) IncomingGRPCConfig() *tls.Config {
|
||||
c.log("IncomingGRPCConfig")
|
||||
// AutoConfigTLSSettings constructs the pbconfig.TLS that will be returned by
|
||||
// servers in the auto-config endpoint.
|
||||
func (c *Configurator) AutoConfigTLSSettings() (*pbconfig.TLS, error) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
// false has the effect that this config doesn't require a client cert
|
||||
// verification. This is because there is no verify_incoming_grpc
|
||||
// configuration option. And using verify_incoming would be backwards
|
||||
// incompatible, because even if it was set before, it didn't have an
|
||||
// effect on the grpc server.
|
||||
config := c.commonTLSConfig(false)
|
||||
cfg := c.base.InternalRPC
|
||||
|
||||
cipherString, err := CipherString(cfg.CipherSuites)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pbconfig.TLS{
|
||||
VerifyOutgoing: cfg.VerifyOutgoing,
|
||||
VerifyServerHostname: cfg.VerifyServerHostname || c.autoTLS.verifyServerHostname,
|
||||
MinVersion: cfg.TLSMinVersion,
|
||||
CipherSuites: cipherString,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IncomingGRPCConfig generates a *tls.Config for incoming external (e.g. xDS)
|
||||
// GRPC connections.
|
||||
//
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) IncomingGRPCConfig() *tls.Config {
|
||||
c.log("IncomingGRPConfig")
|
||||
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
config := c.commonTLSConfig(
|
||||
c.grpc,
|
||||
c.base.GRPC,
|
||||
c.base.GRPC.VerifyIncoming,
|
||||
)
|
||||
config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
return c.IncomingGRPCConfig(), nil
|
||||
}
|
||||
|
@ -632,7 +765,7 @@ func (c *Configurator) IncomingGRPCConfig() *tls.Config {
|
|||
// IncomingRPCConfig generates a *tls.Config for incoming RPC connections.
|
||||
func (c *Configurator) IncomingRPCConfig() *tls.Config {
|
||||
c.log("IncomingRPCConfig")
|
||||
config := c.commonTLSConfig(c.VerifyIncomingRPC())
|
||||
config := c.internalRPCTLSConfig(c.base.InternalRPC.VerifyIncoming)
|
||||
config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
return c.IncomingRPCConfig(), nil
|
||||
}
|
||||
|
@ -645,7 +778,7 @@ func (c *Configurator) IncomingALPNRPCConfig(alpnProtos []string) *tls.Config {
|
|||
c.log("IncomingALPNRPCConfig")
|
||||
// Since the ALPN-RPC variation is indirectly exposed to the internet via
|
||||
// mesh gateways we force mTLS and full server name verification.
|
||||
config := c.commonTLSConfig(true)
|
||||
config := c.internalRPCTLSConfig(true)
|
||||
config.InsecureSkipVerify = false
|
||||
|
||||
config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
|
@ -662,7 +795,7 @@ func (c *Configurator) IncomingALPNRPCConfig(alpnProtos []string) *tls.Config {
|
|||
// usecase ever.
|
||||
func (c *Configurator) IncomingInsecureRPCConfig() *tls.Config {
|
||||
c.log("IncomingInsecureRPCConfig")
|
||||
config := c.commonTLSConfig(false)
|
||||
config := c.internalRPCTLSConfig(false)
|
||||
config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
return c.IncomingInsecureRPCConfig(), nil
|
||||
}
|
||||
|
@ -674,10 +807,13 @@ func (c *Configurator) IncomingHTTPSConfig() *tls.Config {
|
|||
c.log("IncomingHTTPSConfig")
|
||||
|
||||
c.lock.RLock()
|
||||
verifyIncoming := c.base.VerifyIncoming || c.base.VerifyIncomingHTTPS
|
||||
c.lock.RUnlock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
config := c.commonTLSConfig(verifyIncoming)
|
||||
config := c.commonTLSConfig(
|
||||
c.https,
|
||||
c.base.HTTPS,
|
||||
c.base.HTTPS.VerifyIncoming,
|
||||
)
|
||||
config.NextProtos = []string{"h2", "http/1.1"}
|
||||
config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
return c.IncomingHTTPSConfig(), nil
|
||||
|
@ -706,22 +842,22 @@ func (c *Configurator) OutgoingTLSConfigForCheck(skipVerify bool, serverName str
|
|||
if serverName == "" {
|
||||
serverName = c.serverNameOrNodeName()
|
||||
}
|
||||
config := c.commonTLSConfig(false)
|
||||
config := c.internalRPCTLSConfig(false)
|
||||
config.InsecureSkipVerify = skipVerify
|
||||
config.ServerName = serverName
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// OutgoingRPCConfig generates a *tls.Config for outgoing RPC connections. If
|
||||
// there is a CA or VerifyOutgoing is set, a *tls.Config will be provided,
|
||||
// otherwise we assume that no TLS should be used.
|
||||
// OutgoingRPCConfig generates a *tls.Config for outgoing internal RPC
|
||||
// connections. If there is a CA or VerifyOutgoing is set, a *tls.Config
|
||||
// will be provided, otherwise we assume that no TLS should be used.
|
||||
func (c *Configurator) OutgoingRPCConfig() *tls.Config {
|
||||
c.log("OutgoingRPCConfig")
|
||||
if !c.outgoingRPCTLSEnabled() {
|
||||
return nil
|
||||
}
|
||||
return c.commonTLSConfig(false)
|
||||
return c.internalRPCTLSConfig(false)
|
||||
}
|
||||
|
||||
// outgoingALPNRPCConfig generates a *tls.Config for outgoing RPC connections
|
||||
|
@ -737,7 +873,7 @@ func (c *Configurator) outgoingALPNRPCConfig() *tls.Config {
|
|||
|
||||
// Since the ALPN-RPC variation is indirectly exposed to the internet via
|
||||
// mesh gateways we force mTLS and full server name verification.
|
||||
config := c.commonTLSConfig(true)
|
||||
config := c.internalRPCTLSConfig(true)
|
||||
config.InsecureSkipVerify = false
|
||||
return config
|
||||
}
|
||||
|
@ -912,7 +1048,7 @@ func (c *Configurator) AuthorizeServerConn(dc string, conn TLSConn) error {
|
|||
}
|
||||
|
||||
c.lock.RLock()
|
||||
caPool := c.manual.caPool
|
||||
caPool := c.internalRPC.manualCAPool
|
||||
c.lock.RUnlock()
|
||||
|
||||
expected := c.ServerSNI(dc, "")
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -258,12 +258,20 @@ retry_join = [
|
|||
"consul-server3"
|
||||
]
|
||||
encrypt = "aPuGh+5UDskRAbkLaXRzFoSOcSM+5vAK+NEYOWHJH7w="
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
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"
|
||||
|
||||
tls {
|
||||
defaults {
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
@ -281,12 +289,18 @@ key_file = "/consul/config/certs/dc1-server-consul-0-key.pem"
|
|||
},
|
||||
"retry_join": ["consul-server1", "consul-server2"],
|
||||
"encrypt": "aPuGh+5UDskRAbkLaXRzFoSOcSM+5vAK+NEYOWHJH7w=",
|
||||
"tls": {
|
||||
"defaults": {
|
||||
"verify_incoming": true,
|
||||
"verify_outgoing": true,
|
||||
"verify_server_hostname": true,
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -2446,114 +2446,197 @@ There are also a number of common configuration options supported by all provide
|
|||
## TLS Configuration Reference
|
||||
|
||||
This section documents all of the configuration settings that apply to Agent TLS. Agent
|
||||
TLS is used by the HTTP API, server RPC, and xDS interfaces. Some of these settings may also be
|
||||
applied automatically by [auto_config](#auto_config) or [auto_encrypt](#auto_encrypt).
|
||||
TLS is used by the HTTP API, internal RPC, and gRPC/xDS interfaces. Some of these settings
|
||||
may also be applied automatically by [auto_config](#auto_config) or [auto_encrypt](#auto_encrypt).
|
||||
|
||||
~> **Security Note:** The Certificate Authority (CA) specified by `ca_file` or `ca_path`
|
||||
should be a private CA, not a public one. We recommend using a dedicated CA
|
||||
which should not be used with any other systems. Any certificate signed by the
|
||||
CA will be allowed to communicate with the cluster and a specially crafted certificate
|
||||
signed by the CA can be used to gain full access to Consul.
|
||||
~> **Security Note:** The Certificate Authority (CA) configured on the internal RPC interface
|
||||
(either explicitly by `tls.internal_rpc` or implicitly by `tls.defaults`) should be a private
|
||||
CA, not a public one. We recommend using a dedicated CA which should not be used with any other
|
||||
systems. Any certificate signed by the CA will be allowed to communicate with the cluster and a
|
||||
specially crafted certificate signed by the CA can be used to gain full access to Consul.
|
||||
|
||||
- `ca_file` This provides a file path to a PEM-encoded certificate
|
||||
authority. The certificate authority is used to check the authenticity of client
|
||||
and server connections with the appropriate [`verify_incoming`](#verify_incoming)
|
||||
or [`verify_outgoing`](#verify_outgoing) flags.
|
||||
- `tls` Added in Consul 1.12, for previous versions see
|
||||
[Deprecated Options](#tls_deprecated_options).
|
||||
|
||||
- `ca_path` This provides a path to a directory of PEM-encoded
|
||||
certificate authority files. These certificate authorities are used to check the
|
||||
authenticity of client and server connections with the appropriate [`verify_incoming`](#verify_incoming) or [`verify_outgoing`](#verify_outgoing) flags.
|
||||
- `defaults` ((#tls_defaults)) Provides default settings that will be applied
|
||||
to every interface unless explicitly overridden by `tls.grpc`, `tls.https`,
|
||||
or `tls.internal_rpc`.
|
||||
|
||||
- `cert_file` This provides a file path to a PEM-encoded
|
||||
certificate. The certificate is provided to clients or servers to verify the agent's
|
||||
authenticity. It must be provided along with [`key_file`](#key_file).
|
||||
- `ca_file` ((#tls_defaults_ca_file)) This provides a file path to a
|
||||
PEM-encoded certificate authority. The certificate authority is used to
|
||||
check the authenticity of client and server connections with the
|
||||
appropriate [`verify_incoming`](#tls_defaults_verify_incoming) or
|
||||
[`verify_outgoing`](#tls_defaults_verify_outgoing) flags.
|
||||
|
||||
- `key_file` This provides a the file path to a PEM-encoded
|
||||
private key. The key is used with the certificate to verify the agent's authenticity.
|
||||
This must be provided along with [`cert_file`](#cert_file).
|
||||
- `ca_path` ((#tls_defaults_ca_path)) This provides a path to a directory
|
||||
of PEM-encoded certificate authority files. These certificate authorities
|
||||
are used to check the authenticity of client and server connections with
|
||||
the appropriate [`verify_incoming`](#tls_defaults_verify_incoming) or
|
||||
[`verify_outgoing`](#tls_defaults_verify_outgoing) flags.
|
||||
|
||||
- `cert_file` ((#tls_defaults_cert_file)) This provides a file path to a
|
||||
PEM-encoded certificate. The certificate is provided to clients or servers
|
||||
to verify the agent's authenticity. It must be provided along with
|
||||
[`key_file`](#tls_defaults_key_file).
|
||||
|
||||
- `key_file` ((#tls_defaults_key_file)) This provides a the file path to a
|
||||
PEM-encoded private key. The key is used with the certificate to verify
|
||||
the agent's authenticity. This must be provided along with
|
||||
[`cert_file`](#tls_defaults_cert_file).
|
||||
|
||||
- `tls_min_version` ((#tls_defaults_tls_min_version)) 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` ((#tls_defaults_tls_cipher_suites)) This specifies
|
||||
the list of supported ciphersuites as a comma-separated-list. Applicable
|
||||
to TLS 1.2 and below only. The list of all supported ciphersuites is
|
||||
available through [this search](https://github.com/hashicorp/consul/search?q=cipherMap+%3A%3D+map&unscoped_q=cipherMap+%3A%3D+map).
|
||||
|
||||
~> **Note:** The ordering of cipher suites will not be guaranteed from
|
||||
Consul 1.11 onwards. See this [post](https://go.dev/blog/tls-cipher-suites)
|
||||
for details.
|
||||
|
||||
- `verify_incoming` - ((#tls_defaults_verify_incoming)) If set to true,
|
||||
Consul requires that all incoming connections make use of TLS and that
|
||||
the client provides a certificate signed by a Certificate Authority from
|
||||
the [`ca_file`](#tls_defaults_ca_file) or [`ca_path`](#tls_defaults_ca_path).
|
||||
By default, this is false, and Consul will not enforce the use of TLS or
|
||||
verify a client's authenticity.
|
||||
|
||||
- `verify_outgoing` - ((#tls_defaults_verify_outgoing)) If set to true,
|
||||
Consul requires that all outgoing connections from this agent make use
|
||||
of TLS and that the server provides a certificate that is signed by a
|
||||
Certificate Authority from the [`ca_file`](#tls_defaults_ca_file) or
|
||||
[`ca_path`](#tls_defaults_ca_path). By default, this is false, and Consul
|
||||
will not make use of TLS for outgoing connections. This applies to clients
|
||||
and servers as both will make outgoing connections. This setting *does not*
|
||||
apply to the gRPC interface as Consul makes no outgoing connections on this
|
||||
interface.
|
||||
|
||||
- `grpc` ((#tls_grpc)) Provides settings for the gRPC/xDS interface. To enable
|
||||
the gRPC interface you must define a port via [`ports.grpc`](#grpc_port).
|
||||
To enable TLS on the gRPC interface you also must define an HTTPS port via
|
||||
[`ports.https`](#https_port).
|
||||
|
||||
- `ca_file` ((#tls_grpc_ca_file)) Overrides [`tls.defaults.ca_file`](#tls_defaults_ca_file).
|
||||
|
||||
- `ca_path` ((#tls_grpc_ca_path)) Overrides [`tls.defaults.ca_path`](#tls_defaults_ca_path).
|
||||
|
||||
- `cert_file` ((#tls_grpc_cert_file)) Overrides [`tls.defaults.cert_file`](#tls_defaults_cert_file).
|
||||
|
||||
- `key_file` ((#tls_grpc_key_file)) Overrides [`tls.defaults.key_file`](#tls_defaults_key_file).
|
||||
|
||||
- `tls_min_version` ((#tls_grpc_tls_min_version)) Overrides [`tls.defaults.tls_min_version`](#tls_defaults_tls_min_version).
|
||||
|
||||
- `tls_cipher_suites` ((#tls_grpc_tls_cipher_suites)) Overrides [`tls.defaults.tls_cipher_suites`](#tls_defaults_tls_cipher_suites).
|
||||
|
||||
- `verify_incoming` - ((#tls_grpc_verify_incoming)) Overrides [`tls.defaults.verify_incoming`](#tls_defaults_verify_incoming).
|
||||
|
||||
- `https` ((#tls_https)) Provides settings for the HTTPS interface. To enable
|
||||
the HTTPS interface you must define a port via [`ports.https`](#https_port).
|
||||
|
||||
- `ca_file` ((#tls_https_ca_file)) Overrides [`tls.defaults.ca_file`](#tls_defaults_ca_file).
|
||||
|
||||
- `ca_path` ((#tls_https_ca_path)) Overrides [`tls.defaults.ca_path`](#tls_defaults_ca_path).
|
||||
|
||||
- `cert_file` ((#tls_https_cert_file)) Overrides [`tls.defaults.cert_file`](#tls_defaults_cert_file).
|
||||
|
||||
- `key_file` ((#tls_https_key_file)) Overrides [`tls.defaults.key_file`](#tls_defaults_key_file).
|
||||
|
||||
- `tls_min_version` ((#tls_https_tls_min_version)) Overrides [`tls.defaults.tls_min_version`](#tls_defaults_tls_min_version).
|
||||
|
||||
- `tls_cipher_suites` ((#tls_https_tls_cipher_suites)) Overrides [`tls.defaults.tls_cipher_suites`](#tls_defaults_tls_cipher_suites).
|
||||
|
||||
- `verify_incoming` - ((#tls_https_verify_incoming)) Overrides [`tls.defaults.verify_incoming`](#tls_defaults_verify_incoming).
|
||||
|
||||
- `verify_outgoing` - ((#tls_https_verify_outgoing)) Overrides [`tls.defaults.verify_outgoing`](#tls_defaults_verify_outgoing).
|
||||
|
||||
- `internal_rpc` ((#tls_internal_rpc)) Provides settings for the internal
|
||||
"server" RPC interface configured by [`ports.server`](#server_rpc_port).
|
||||
|
||||
- `ca_file` ((#tls_internal_rpc_ca_file)) Overrides [`tls.defaults.ca_file`](#tls_defaults_ca_file).
|
||||
|
||||
- `ca_path` ((#tls_internal_rpc_ca_path)) Overrides [`tls.defaults.ca_path`](#tls_defaults_ca_path).
|
||||
|
||||
- `cert_file` ((#tls_internal_rpc_cert_file)) Overrides [`tls.defaults.cert_file`](#tls_defaults_cert_file).
|
||||
|
||||
- `key_file` ((#tls_internal_rpc_key_file)) Overrides [`tls.defaults.key_file`](#tls_defaults_key_file).
|
||||
|
||||
- `tls_min_version` ((#tls_internal_rpc_tls_min_version)) Overrides [`tls.defaults.tls_min_version`](#tls_defaults_tls_min_version).
|
||||
|
||||
- `tls_cipher_suites` ((#tls_internal_rpc_tls_cipher_suites)) Overrides [`tls.defaults.tls_cipher_suites`](#tls_defaults_tls_cipher_suites).
|
||||
|
||||
- `verify_incoming` - ((#tls_internal_rpc_verify_incoming)) Overrides [`tls.defaults.verify_incoming`](#tls_defaults_verify_incoming).
|
||||
|
||||
~> **Security Note:** `verify_incoming` *must* be set to true to prevent
|
||||
anyone with access to the internal RPC port from gaining full access to
|
||||
the Consul cluster.
|
||||
|
||||
- `verify_outgoing` ((#tls_internal_rpc_verify_outgoing)) Overrides [`tls.defaults.verify_outgoing`](#tls_defaults_verify_outgoing).
|
||||
|
||||
~> **Security Note:** Servers that specify `verify_outgoing = true` will
|
||||
always talk to other servers over TLS, but they still _accept_ non-TLS
|
||||
connections to allow for a transition of all clients to TLS. Currently the
|
||||
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
|
||||
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. This setting *must* be enabled to prevent a
|
||||
compromised client from gaining full read and write access to all cluster
|
||||
data *including all ACL tokens and Connect CA root keys*.
|
||||
|
||||
- `server_name` When provided, this overrides the [`node_name`](#_node)
|
||||
for the TLS certificate. It can be used to ensure that the certificate name matches
|
||||
the hostname we declare.
|
||||
|
||||
- `tls_min_version` Added in Consul 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.
|
||||
### Deprecated Options ((#tls_deprecated_options))
|
||||
|
||||
- `tls_cipher_suites` Added in Consul 0.8.2, this specifies the list of
|
||||
supported ciphersuites as a comma-separated-list. Applicable to TLS 1.2 and below only.
|
||||
The list of all supported ciphersuites is available through
|
||||
[this search](https://github.com/hashicorp/consul/search?q=cipherMap+%3A%3D+map&unscoped_q=cipherMap+%3A%3D+map).
|
||||
The following options were deprecated in Consul 1.12, please use the
|
||||
[`tls`](#tls) stanza instead.
|
||||
|
||||
~> **Note:** The ordering of cipher suites will not be guaranteed from Consul 1.11 onwards. See this
|
||||
[post](https://go.dev/blog/tls-cipher-suites) for details.
|
||||
- `ca_file` See: [`tls.defaults.ca_file`](#tls_defaults_ca_file).
|
||||
|
||||
- `tls_prefer_server_cipher_suites` Added in Consul 0.8.2, this
|
||||
will cause Consul to prefer the server's ciphersuite over the client ciphersuites.
|
||||
- `ca_path` See: [`tls.defaults.ca_path`](#tls_defaults_ca_path).
|
||||
|
||||
~> **Note:** This config will be deprecated in Consul 1.11. See this
|
||||
[post](https://go.dev/blog/tls-cipher-suites) for details.
|
||||
- `cert_file` See: [`tls.defaults.cert_file`](#tls_defaults_cert_file).
|
||||
|
||||
- `verify_incoming` - If set to true, Consul
|
||||
requires that all incoming connections make use of TLS and that the client
|
||||
provides a certificate signed by a Certificate Authority from the
|
||||
[`ca_file`](#ca_file) or [`ca_path`](#ca_path). This applies to both server
|
||||
RPC and to the HTTPS API. By default, this is false, and Consul will not
|
||||
enforce the use of TLS or verify a client's authenticity. Turning on
|
||||
`verify_incoming` on consul clients protects the HTTPS endpoint, by ensuring
|
||||
that the certificate that is presented by a 3rd party tool to the HTTPS
|
||||
endpoint was created by the CA that the consul client was setup with. If the
|
||||
UI is served, the same checks are performed.
|
||||
- `key_file` See: [`tls.defaults.key_file`](#tls_defaults_key_file).
|
||||
|
||||
- `verify_incoming_rpc` - When set to true, Consul
|
||||
requires that all incoming RPC connections use TLS and that the client
|
||||
provides a certificate signed by a Certificate Authority from the [`ca_file`](#ca_file)
|
||||
or [`ca_path`](#ca_path). By default, this is false, and Consul will not enforce
|
||||
the use of TLS or verify a client's authenticity.
|
||||
- `tls_min_version` Added in Consul 0.7.4.
|
||||
See: [`tls.defaults.tls_min_version`](#tls_defaults_tls_min_version).
|
||||
|
||||
~> **Security Note:** `verify_incoming_rpc` _must_ be set to true to prevent anyone
|
||||
with access to the RPC port from gaining full access to the Consul cluster.
|
||||
- `tls_cipher_suites` Added in Consul 0.8.2.
|
||||
See: [`tls.defaults.tls_cipher_suites`](#tls_defaults_tls_cipher_suites).
|
||||
|
||||
- `verify_incoming_https` - If set to true,
|
||||
Consul requires that all incoming HTTPS connections make use of TLS and that the
|
||||
client provides a certificate signed by a Certificate Authority from the [`ca_file`](#ca_file)
|
||||
or [`ca_path`](#ca_path). By default, this is false, and Consul will not enforce
|
||||
the use of TLS or verify a client's authenticity. To enable the HTTPS API, you
|
||||
must define an HTTPS port via the [`ports`](#ports) configuration. By default,
|
||||
HTTPS is disabled.
|
||||
- `tls_prefer_server_cipher_suites` Added in Consul 0.8.2. This setting will
|
||||
be ignored (see [this post](https://go.dev/blog/tls-cipher-suites) for details).
|
||||
|
||||
- `verify_outgoing` - If set to true, Consul requires
|
||||
that all outgoing connections from this agent make use of TLS and that the server
|
||||
provides a certificate that is signed by a Certificate Authority from the [`ca_file`](#ca_file)
|
||||
or [`ca_path`](#ca_path). By default, this is false, and Consul will not make use
|
||||
of TLS for outgoing connections. This applies to clients and servers as both will
|
||||
make outgoing connections.
|
||||
- `verify_incoming` See: [`tls.defaults.verify_incoming`](#tls_defaults_verify_incoming).
|
||||
|
||||
~> **Security Note:** Note that servers that specify `verify_outgoing = true` will always talk to other servers over TLS, but they still _accept_
|
||||
non-TLS connections to allow for a transition of all clients to TLS.
|
||||
Currently the 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_incoming_rpc` See: [`tls.internal_rpc.verify_incoming`](#tls_internal_rpc_verify_incoming).
|
||||
|
||||
- `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. This setting _must_ be enabled
|
||||
to prevent a compromised client from gaining full read and write access to all
|
||||
cluster data _including all ACL tokens and Connect CA root keys_. This is new in 0.5.1.
|
||||
- `verify_incoming_https` See: [`tls.https.verify_incoming`](#tls_https_verify_incoming).
|
||||
|
||||
~> **Security Note:** From versions 0.5.1 to 1.4.0, due to a bug, setting
|
||||
this flag alone _does not_ imply `verify_outgoing` and leaves client to server
|
||||
and server to server RPCs unencrypted despite the documentation stating otherwise. See
|
||||
[CVE-2018-19653](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-19653)
|
||||
for more details. For those versions you **must also set `verify_outgoing = true`** to ensure encrypted RPC connections.
|
||||
- `verify_outgoing` See: [`tls.defaults.verify_outgoing`](#tls_defaults_verify_outgoing).
|
||||
|
||||
- `verify_server_hostname` See: [`tls.internal_rpc.verify_server_hostname`](#tls_internal_rpc_verify_server_hostname).
|
||||
|
||||
### Example Configuration File, with TLS
|
||||
|
||||
~> **Security Note:** all three verify options should be set as `true` to enable secure mTLS communication, enabling both
|
||||
encryption and authentication. Failing to set [`verify_incoming`](#verify_incoming) or [`verify_outgoing`](#verify_outgoing)
|
||||
will result in TLS not being enabled at all, even when specifying a [`ca_file`](#ca_file), [`cert_file`](#cert_file), and [`key_file`](#key_file).
|
||||
~> **Security Note:** all three verify options should be set as `true` to enable
|
||||
secure mTLS communication, enabling both encryption and authentication. Failing
|
||||
to set [`verify_incoming`](#tls_defaults_verify_incoming) or
|
||||
[`verify_outgoing`](#tls_defaults_verify_outgoing) either in the
|
||||
interface-specific stanza (e.g. `tls.internal_rpc`, `tls.https`) or in
|
||||
`tls.defaults` will result in TLS not being enabled at all, even when specifying
|
||||
a [`ca_file`](#tls_defaults_ca_file), [`cert_file`](#tls_defaults_cert_file),
|
||||
and [`key_file`](#tls_defaults_key_file).
|
||||
|
||||
See, especially, the use of the `ports` setting highlighted below.
|
||||
|
||||
|
@ -2575,12 +2658,19 @@ ports {
|
|||
https = 8501
|
||||
}
|
||||
|
||||
key_file = "/etc/pki/tls/private/my.key"
|
||||
cert_file = "/etc/pki/tls/certs/my.crt"
|
||||
ca_file = "/etc/pki/tls/certs/ca-bundle.crt"
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
tls {
|
||||
defaults {
|
||||
key_file = "/etc/pki/tls/private/my.key"
|
||||
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_server_hostname = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
@ -2600,12 +2690,18 @@ verify_server_hostname = true
|
|||
"ports": {
|
||||
"https": 8501
|
||||
},
|
||||
"tls": {
|
||||
"defaults": {
|
||||
"key_file": "/etc/pki/tls/private/my.key",
|
||||
"cert_file": "/etc/pki/tls/certs/my.crt",
|
||||
"ca_file": "/etc/pki/tls/certs/ca-bundle.crt",
|
||||
"verify_incoming": true,
|
||||
"verify_outgoing": true,
|
||||
"verify_outgoing": true
|
||||
},
|
||||
"internal_rpc": {
|
||||
"verify_server_hostname": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -2613,8 +2709,8 @@ verify_server_hostname = true
|
|||
|
||||
</CodeTabs>
|
||||
|
||||
Consul will not enable TLS for the HTTP API unless the `https` port has been
|
||||
assigned a port number `> 0`. We recommend using `8501` for `https` as this
|
||||
Consul will not enable TLS for the HTTP or gRPC API unless the `https` port has
|
||||
been assigned a port number `> 0`. We recommend using `8501` for `https` as this
|
||||
default will automatically work with some tooling.
|
||||
|
||||
## Ports Used
|
||||
|
|
|
@ -46,7 +46,7 @@ configuration file include:
|
|||
- [certificate authority settings](/docs/agent/options#connect)
|
||||
- [token replication](/docs/agent/options#acl_tokens_replication)
|
||||
- [dev mode](/docs/agent/options#_dev)
|
||||
- [server host name verification](/docs/agent/options#verify_server_hostname)
|
||||
- [server host name verification](/docs/agent/options#tls_internal_rpc_verify_server_hostname)
|
||||
|
||||
If you would like to use Envoy as your Connect proxy you will need to [enable
|
||||
gRPC](/docs/agent/options#grpc_port).
|
||||
|
|
|
@ -157,8 +157,12 @@ auto_encrypt = {
|
|||
tls = true
|
||||
ip_san = ["$ECS_IPV4"]
|
||||
}
|
||||
ca_file = "/tmp/consul-ca-cert.pem"
|
||||
verify_outgoing = true
|
||||
tls {
|
||||
defaults {
|
||||
ca_file = "/tmp/consul-ca-cert.pem"
|
||||
verify_outgoing = true
|
||||
}
|
||||
}
|
||||
|
||||
# Configure ACLs
|
||||
acl {
|
||||
|
@ -178,10 +182,10 @@ EOF
|
|||
The following table describes the additional fields that must be included in the Consul client configuration file.
|
||||
|
||||
| Field name | Type | Description |
|
||||
| --------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ |
|
||||
| --------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------ |
|
||||
| [`encrypt`](/docs/agent/options#_encrypt) | string | Specifies the gossip encryption key |
|
||||
| [`ca_file`](/docs/agent/options#ca_file) | string | Specifies the Consul server CA cert for TLS verification. |
|
||||
| [`acl.enabled`](/docs/agent/options#acl_enabled) | boolen | Enable ACLs for this agent. |
|
||||
| [`tls.defaults.ca_file`](/docs/agent/options#tls_defaults_ca_file) | string | Specifies the Consul server CA cert for TLS verification. |
|
||||
| [`acl.enabled`](/docs/agent/options#acl_enabled) | boolean | Enable ACLs for this agent. |
|
||||
| [`acl.tokens.agent`](/docs/agent/options#acl_tokens_agent) | string | Specifies the Consul client token which authorizes this agent with Consul servers. |
|
||||
|
||||
## Configure `consul-ecs-mesh-init` and `consul-ecs-health-sync`
|
||||
|
|
|
@ -294,11 +294,11 @@ Use these links to navigate to a particular top-level stanza.
|
|||
in the server certificate. This is useful when you need to access the
|
||||
Consul server(s) externally, for example, if you're using the UI.
|
||||
|
||||
- `verify` ((#v-global-tls-verify)) (`boolean: true`) - If true, `verify_outgoing`, `verify_server_hostname`,
|
||||
and `verify_incoming_rpc` will be set to `true` for Consul servers and clients.
|
||||
Set this to false to incrementally roll out TLS on an existing Consul cluster.
|
||||
Please see https://consul.io/docs/k8s/operations/tls-on-existing-cluster
|
||||
for more details.
|
||||
- `verify` ((#v-global-tls-verify)) (`boolean: true`) - If true, `tls.defaults.verify_outgoing`,
|
||||
`tls.internal_rpc.verify_server_hostname`, and `tls.internal_rpc.verify_incoming` will be set
|
||||
to `true` for Consul servers and clients. Set this to false to incrementally roll out TLS
|
||||
on an existing Consul cluster.
|
||||
Please see https://consul.io/docs/k8s/operations/tls-on-existing-cluster for more details.
|
||||
|
||||
- `httpsOnly` ((#v-global-tls-httpsonly)) (`boolean: true`) - If true, the Helm chart will configure Consul to disable the HTTP port on
|
||||
both clients and servers and to only accept HTTPS connections.
|
||||
|
|
|
@ -56,7 +56,7 @@ You may also consider adopting Consul Enterprise for
|
|||
|
||||
-> **Note:** Consul on Kubernetes currently does not support external servers that require mutual authentication
|
||||
for the HTTPS clients of the Consul servers, that is when servers have either
|
||||
`verify_incoming` or `verify_incoming_https` set to `true`.
|
||||
`tls.defaults.verify_incoming` or `tls.https.verify_incoming` set to `true`.
|
||||
As noted in the [Security Model](/docs/security#secure-configuration),
|
||||
that setting isn't strictly necessary to support Consul's threat model as it is recommended that
|
||||
all requests contain a valid ACL token.
|
||||
|
|
|
@ -75,9 +75,13 @@ The following sections detail how to export this data.
|
|||
<CodeBlockConfig filename="server.hcl">
|
||||
|
||||
```hcl
|
||||
tls {
|
||||
defaults {
|
||||
cert_file = "vm-dc-server-consul-0.pem"
|
||||
key_file = "vm-dc-server-consul-0-key.pem"
|
||||
ca_file = "consul-agent-ca.pem"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
@ -160,9 +164,19 @@ A final example server config file might look like:
|
|||
|
||||
```hcl
|
||||
# From above
|
||||
cert_file = "vm-dc-server-consul-0.pem"
|
||||
key_file = "vm-dc-server-consul-0-key.pem"
|
||||
ca_file = "consul-agent-ca.pem"
|
||||
tls {
|
||||
defaults {
|
||||
cert_file = "vm-dc-server-consul-0.pem"
|
||||
key_file = "vm-dc-server-consul-0-key.pem"
|
||||
ca_file = "consul-agent-ca.pem"
|
||||
}
|
||||
|
||||
internal_rpc {
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
}
|
||||
}
|
||||
primary_gateways = ["1.2.3.4:443"]
|
||||
acl {
|
||||
enabled = true
|
||||
|
@ -185,9 +199,6 @@ connect {
|
|||
enabled = true
|
||||
enable_mesh_gateway_wan_federation = true
|
||||
}
|
||||
verify_incoming_rpc = true
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
ports {
|
||||
https = 8501
|
||||
http = -1
|
||||
|
|
|
@ -75,17 +75,17 @@ CA then signs keys for each of the agents, as in
|
|||
~> Certificates need to be created with x509v3 extendedKeyUsage attributes for both clientAuth and serverAuth since Consul uses a single cert/key pair for both server and client communications.
|
||||
|
||||
TLS can be used to verify the authenticity of the servers or verify the authenticity of clients.
|
||||
These modes are controlled by the [`verify_outgoing`](/docs/agent/options#verify_outgoing),
|
||||
[`verify_server_hostname`](/docs/agent/options#verify_server_hostname),
|
||||
and [`verify_incoming`](/docs/agent/options#verify_incoming) options, respectively.
|
||||
These modes are controlled by the [`verify_outgoing`](/docs/agent/options#tls_internal_rpc_verify_outgoing),
|
||||
[`verify_server_hostname`](/docs/agent/options#tls_internal_rpc_verify_server_hostname),
|
||||
and [`verify_incoming`](/docs/agent/options#tls_internal_rpc_verify_incoming) options, respectively.
|
||||
|
||||
If [`verify_outgoing`](/docs/agent/options#verify_outgoing) is set, agents verify the
|
||||
If [`verify_outgoing`](/docs/agent/options#tls_internal_rpc_verify_outgoing) is set, agents verify the
|
||||
authenticity of Consul for outgoing connections. Server nodes must present a certificate signed
|
||||
by a common certificate authority present on all agents, set via the agent's
|
||||
[`ca_file`](/docs/agent/options#ca_file) and [`ca_path`](/docs/agent/options#ca_path)
|
||||
options. All server nodes must have an appropriate key pair set using [`cert_file`](/docs/agent/options#cert_file) and [`key_file`](/docs/agent/options#key_file).
|
||||
[`ca_file`](/docs/agent/options#tls_internal_rpc_ca_file) and [`ca_path`](/docs/agent/options#tls_internal_rpc_ca_path)
|
||||
options. All server nodes must have an appropriate key pair set using [`cert_file`](/docs/agent/options#tls_internal_rpc_cert_file) and [`key_file`](/docs/agent/options#tls_internal_rpc_key_file).
|
||||
|
||||
If [`verify_server_hostname`](/docs/agent/options#verify_server_hostname) is set, then
|
||||
If [`verify_server_hostname`](/docs/agent/options#tls_internal_rpc_verify_server_hostname) is set, then
|
||||
outgoing connections perform hostname verification. All servers must have a certificate
|
||||
valid for `server.<datacenter>.<domain>` or the client will reject the handshake. This is
|
||||
a new configuration as of 0.5.1, and it is used to prevent a compromised client from being
|
||||
|
@ -93,12 +93,12 @@ able to restart in server mode and perform a MITM (Man-In-The-Middle) attack. Ne
|
|||
to true, and generate the proper certificates, but this is defaulted to false to avoid breaking
|
||||
existing deployments.
|
||||
|
||||
If [`verify_incoming`](/docs/agent/options#verify_incoming) is set, the servers verify the
|
||||
If [`verify_incoming`](/docs/agent/options#tls_internal_rpc_verify_incoming) is set, the servers verify the
|
||||
authenticity of all incoming connections. All clients must have a valid key pair set using
|
||||
[`cert_file`](/docs/agent/options#cert_file) and
|
||||
[`key_file`](/docs/agent/options#key_file). Servers will
|
||||
[`cert_file`](/docs/agent/options#tls_internal_rpc_cert_file) and
|
||||
[`key_file`](/docs/agent/options#tls_internal_rpc_key_file). Servers will
|
||||
also disallow any non-TLS connections. To force clients to use TLS,
|
||||
[`verify_outgoing`](/docs/agent/options#verify_outgoing) must also be set.
|
||||
[`verify_outgoing`](/docs/agent/options#tls_internal_rpc_verify_outgoing) must also be set.
|
||||
|
||||
TLS is used to secure the RPC calls between agents, but gossip between nodes is done over UDP
|
||||
and is secured using a symmetric key. See above for enabling gossip encryption.
|
||||
|
|
|
@ -72,29 +72,33 @@ environment and adapt these configurations accordingly.
|
|||
- **mTLS** - Mutual authentication of both the TLS server and client x509 certificates prevents internal abuse through
|
||||
unauthorized access to Consul agents within the cluster.
|
||||
|
||||
- [`verify_incoming`](/docs/agent/options#verify_incoming) - By default this is false, and should almost always be set
|
||||
to true to require TLS verification for incoming client connections. This applies to both server RPC and to the
|
||||
HTTPS API.
|
||||
- [`tls.defaults.verify_incoming`](/docs/agent/options#tls_defaults_verify_incoming) - By default this is false, and
|
||||
should almost always be set to true to require TLS verification for incoming client connections. This applies to the
|
||||
internal RPC, HTTPS and gRPC APIs.
|
||||
|
||||
- [`verify_incoming_https`](/docs/agent/options#verify_incoming_https) - By default this is false, and should be set
|
||||
to true to require clients to provide a valid TLS certificate when the Consul HTTPS API is enabled. TLS for the API
|
||||
may be not be necessary if it is exclusively served over a loopback interface such as `localhost`.
|
||||
- [`tls.https.verify_incoming`](/docs/agent/options#tls_https_verify_incoming) - By default this is false, and should
|
||||
be set to true to require clients to provide a valid TLS certificate when the Consul HTTPS API is enabled. TLS for
|
||||
the API may be not be necessary if it is exclusively served over a loopback interface such as `localhost`.
|
||||
|
||||
- [`verify_incoming_rpc`](/docs/agent/options#verify_incoming_rpc) - By default this is false, and should almost
|
||||
always be set to true to require clients to provide a valid TLS certificate for Consul agent RPCs.
|
||||
- [`tls.internal_rpc.verify_incoming`](/docs/agent/options#tls_internal_rpc_verify_incoming) - By default this is false,
|
||||
and should almost always be set to true to require clients to provide a valid TLS certificate for Consul agent RPCs.
|
||||
|
||||
- [`verify_outgoing`](/docs/agent/options#verify_outgoing) - By default this is false, and should be set to true to
|
||||
require TLS for outgoing connections from server or client agents. Servers that specify `verify_outgoing = true`
|
||||
will always talk to other servers over TLS, but they still accept non-TLS connections to allow for a transition of
|
||||
all clients to TLS. Currently the only way to enforce that no client can communicate with a server unencrypted is
|
||||
to also enable `verify_incoming` which requires client certificates too.
|
||||
- [`tls.grpc.verify_incoming`](/docs/agent/options#tls_grpc_verify_incoming) - By default this is false, and should
|
||||
be set to true to require clients to provide a valid TLS certificate when the Consul gRPC API is enabled. TLS for
|
||||
the API may be not be necessary if it is exclusively served over a loopback interface such as `localhost`.
|
||||
|
||||
- [`tls.internal_rpc.verify_outgoing`](/docs/agent/options#tls_internal_rpc_verify_outgoing) - By default this is false,
|
||||
and should be set to true to require TLS for outgoing connections from server or client agents. Servers that specify
|
||||
`verify_outgoing = true` will always talk to other servers over TLS, but they still accept non-TLS connections to allow
|
||||
for a transition of all clients to TLS. Currently the only way to enforce that no client can communicate with a server
|
||||
unencrypted is to also enable `verify_incoming` which requires client certificates too.
|
||||
|
||||
- [`enable_agent_tls_for_checks`](/docs/agent/options#enable_agent_tls_for_checks) - By default this is false, and
|
||||
should almost always be set to true to require mTLS to set up the client for HTTP or gRPC health checks. This was
|
||||
added in Consul 1.0.1.
|
||||
|
||||
- [`verify_server_hostname`](/docs/agent/options#verify_server_hostname) - By default this is false, and should be
|
||||
set to true to require that the TLS certificate presented by the servers matches
|
||||
- [`tls.internal_rpc.verify_server_hostname`](/docs/agent/options#tls_internal_rpc_verify_server_hostname) - By default
|
||||
this is false, and should be set to true to require that the TLS certificate presented by the servers matches
|
||||
`server.<datacenter>.<domain>` hostname for outgoing TLS connections. The default configuration does not verify the
|
||||
hostname of the certificate, only that it is signed by a trusted CA. This setting is critical to prevent a
|
||||
compromised client agent from being restarted as a server and having all cluster state including all ACL tokens and
|
||||
|
@ -105,7 +109,7 @@ environment and adapt these configurations accordingly.
|
|||
in 1.4.1.
|
||||
|
||||
- [`auto_encrypt`](/docs/agent/options#auto_encrypt) - Enables automated TLS certificate distribution for client
|
||||
agent RPC communication using the Connect CA. Using this configuration a [`ca_file`](/docs/agent/options#ca_file)
|
||||
agent RPC communication using the Connect CA. Using this configuration a [`ca_file`](/docs/agent/options#tls_defaults_ca_file)
|
||||
and ACL token would still need to be distributed to client agents.
|
||||
|
||||
- [`allow_tls`](/docs/agent/options#allow_tls) - By default this is false, and should be set to true on server
|
||||
|
@ -117,13 +121,19 @@ environment and adapt these configurations accordingly.
|
|||
**Example Server Agent TLS Configuration**
|
||||
|
||||
```hcl
|
||||
tls {
|
||||
defaults {
|
||||
verify_incoming = true
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
auto_encrypt {
|
||||
allow_tls = true
|
||||
|
@ -133,19 +143,26 @@ environment and adapt these configurations accordingly.
|
|||
**Example Client Agent TLS Configuration**
|
||||
|
||||
```hcl
|
||||
tls {
|
||||
defaults {
|
||||
verify_incoming = false
|
||||
verify_outgoing = true
|
||||
verify_server_hostname = true
|
||||
|
||||
ca_file = "consul-agent-ca.pem"
|
||||
}
|
||||
|
||||
internal_rpc {
|
||||
verify_server_hostname = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto_encrypt {
|
||||
tls = true
|
||||
}
|
||||
```
|
||||
|
||||
-> The client agent TLS configuration from above sets [`verify_incoming`](/docs/agent/options#verify_incoming) to
|
||||
false which assumes all incoming traffic is restricted to `localhost`. The primary benefit for this configuration
|
||||
-> The client agent TLS configuration from above sets [`verify_incoming`](/docs/agent/options#tls_defaults_verify_incoming)
|
||||
to false which assumes all incoming traffic is restricted to `localhost`. The primary benefit for this configuration
|
||||
would be to avoid provisioning client TLS certificates (in addition to ACL tokens) for all tools or applications
|
||||
using the local Consul agent. In this case ACLs should be enabled to provide authorization and only ACL tokens would
|
||||
need to be distributed.
|
||||
|
@ -223,15 +240,12 @@ environment and adapt these configurations accordingly.
|
|||
- **Linux Security Modules** - Use of security modules that can be directly integrated into operating systems such as
|
||||
AppArmor, SElinux, and Seccomp on Consul agent hosts.
|
||||
|
||||
- **Customize TLS Settings** - TLS settings such as the [available cipher suites](/docs/agent/options#tls_cipher_suites),
|
||||
- **Customize TLS Settings** - TLS settings such as the [available cipher suites](/docs/agent/options#tls_defaults_tls_cipher_suites),
|
||||
should be tuned to fit the needs of your environment.
|
||||
|
||||
- [`tls_min_version`](/docs/agent/options#tls_min_version) - Used to specify the minimum TLS version to use.
|
||||
- [`tls_min_version`](/docs/agent/options#tls_defaults_tls_min_version) - Used to specify the minimum TLS version to use.
|
||||
|
||||
- [`tls_cipher_suites`](/docs/agent/options#tls_cipher_suites) - Used to specify which TLS cipher suites are allowed.
|
||||
|
||||
- [`tls_prefer_server_cipher_suites`](/docs/agent/options#tls_prefer_server_cipher_suites) - Used to specify which TLS
|
||||
cipher suites are preferred on the server side.
|
||||
- [`tls_cipher_suites`](/docs/agent/options#tls_defaults_tls_cipher_suites) - Used to specify which TLS cipher suites are allowed.
|
||||
|
||||
- **Customize HTTP Response Headers** - Additional security headers, such as
|
||||
[`X-XSS-Protection`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection), can be
|
||||
|
|
Loading…
Reference in New Issue