mirror of https://github.com/status-im/consul.git
ingress: allow setting TLS min version and cipher suites in ingress gateway config entries (#11576)
* xds: refactor ingress listener SDS configuration * xds: update resolveListenerSDS call args in listeners_test * ingress: add TLS min, max and cipher suites to GatewayTLSConfig * xds: implement envoyTLSVersions and envoyTLSCipherSuites * xds: merge TLS config * xds: configure TLS parameters with ingress TLS context from leaf * xds: nil check in resolveListenerTLSConfig validation * xds: nil check in makeTLSParameters* functions * changelog: add entry for TLS params on ingress config entries * xds: remove indirection for TLS params in TLSConfig structs * xds: return tlsContext, nil instead of ambiguous err Co-authored-by: Chris S. Kim <ckim@hashicorp.com> * xds: switch zero checks to types.TLSVersionUnspecified * ingress: add validation for ingress config entry TLS params * ingress: validate listener TLS config * xds: add basic ingress with TLS params tests * xds: add ingress listeners mixed TLS min version defaults precedence test * xds: add more explicit tests for ingress listeners inheriting gateway defaults * xds: add test for single TLS listener on gateway without TLS defaults * xds: regen golden files for TLSVersionInvalid zero value, add TLSVersionAuto listener test * types/tls: change TLSVersion to string * types/tls: update TLSCipherSuite to string type * types/tls: implement validation functions for TLSVersion and TLSCipherSuites, make some maps private * api: add TLS params to GatewayTLSConfig, add tests * api: add TLSMinVersion to ingress gateway config entry test JSON * xds: switch to Envoy TLS cipher suite encoding from types package * xds: fixup validation for TLSv1_3 min version with cipher suites * add some kitchen sink tests and add a missing struct tag * xds: check if mergedCfg.TLSVersion is in TLSVersionsWithConfigurableCipherSuites * xds: update connectTLSEnabled comment * xds: remove unsued resolveGatewayServiceTLSConfig function * xds: add makeCommonTLSContextFromLeafWithoutParams * types/tls: add LessThan comparator function for concrete values * types/tls: change tlsVersions validation map from string to TLSVersion keys * types/tls: remove unused envoyTLSCipherSuites * types/tls: enable chacha20 cipher suites for Consul agent * types/tls: remove insecure cipher suites from allowed config TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 and TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 are both explicitly listed as insecure and disabled in the Go source. Refs https://cs.opensource.google/go/go/+/refs/tags/go1.17.3:src/crypto/tls/cipher_suites.go;l=329-330 * types/tls: add ValidateConsulAgentCipherSuites function, make direct lookup map private * types/tls: return all unmatched cipher suites in validation errors * xds: check that Envoy API value matching TLS version is found when building TlsParameters * types/tls: check that value is found in map before appending to slice in MarshalEnvoyTLSCipherSuiteStrings * types/tls: cast to string rather than fmt.Printf in TLSCihperSuite.String() * xds: add TLSVersionUnspecified to list of configurable cipher suites * structs: update note about config entry warning * xds: remove TLS min version cipher suite unconfigurable test placeholder * types/tls: update tests to remove assumption about private map values Co-authored-by: R.B. Boyer <rb@hashicorp.com>
This commit is contained in:
parent
a4af0a6bb0
commit
1b1a97e8f9
|
@ -0,0 +1,3 @@
|
|||
```release-note:feature
|
||||
ingress: allow setting TLS min version and cipher suites in ingress gateway config entries
|
||||
```
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/lib/stringslice"
|
||||
"github.com/hashicorp/consul/types"
|
||||
)
|
||||
|
||||
// IngressGatewayConfigEntry manages the configuration for an ingress service
|
||||
|
@ -99,6 +100,13 @@ type GatewayTLSConfig struct {
|
|||
|
||||
// SDS allows configuring TLS certificate from an SDS service.
|
||||
SDS *GatewayTLSSDSConfig `json:",omitempty"`
|
||||
|
||||
TLSMinVersion types.TLSVersion `json:",omitempty" alias:"tls_min_version"`
|
||||
TLSMaxVersion types.TLSVersion `json:",omitempty" alias:"tls_max_version"`
|
||||
|
||||
// Define a subset of cipher suites to restrict
|
||||
// Only applicable to connections negotiated via TLS 1.2 or earlier
|
||||
CipherSuites []types.TLSCipherSuite `json:",omitempty" alias:"cipher_suites"`
|
||||
}
|
||||
|
||||
type GatewayServiceTLSConfig struct {
|
||||
|
@ -231,11 +239,49 @@ func (e *IngressGatewayConfigEntry) validateServiceSDS(lis IngressListener, svc
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateGatewayTLSConfig(tlsCfg GatewayTLSConfig) error {
|
||||
if tlsCfg.TLSMinVersion != types.TLSVersionUnspecified {
|
||||
if err := types.ValidateTLSVersion(tlsCfg.TLSMinVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tlsCfg.TLSMaxVersion != types.TLSVersionUnspecified {
|
||||
if err := types.ValidateTLSVersion(tlsCfg.TLSMaxVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tlsCfg.TLSMinVersion != types.TLSVersionUnspecified {
|
||||
if err, maxLessThanMin := tlsCfg.TLSMaxVersion.LessThan(tlsCfg.TLSMinVersion); err == nil && maxLessThanMin {
|
||||
return fmt.Errorf("configuring max version %s less than the configured min version %s is invalid", tlsCfg.TLSMaxVersion, tlsCfg.TLSMinVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(tlsCfg.CipherSuites) != 0 {
|
||||
if _, ok := types.TLSVersionsWithConfigurableCipherSuites[tlsCfg.TLSMinVersion]; !ok {
|
||||
return fmt.Errorf("configuring CipherSuites is only applicable to conncetions negotiated with TLS 1.2 or earlier, TLSMinVersion is set to %s", tlsCfg.TLSMinVersion)
|
||||
}
|
||||
|
||||
// NOTE: it would be nice to emit a warning but not return an error from
|
||||
// here if TLSMaxVersion is unspecified, TLS_AUTO or TLSv1_3
|
||||
if err := types.ValidateEnvoyCipherSuites(tlsCfg.CipherSuites); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *IngressGatewayConfigEntry) Validate() error {
|
||||
if err := validateConfigEntryMeta(e.Meta); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateGatewayTLSConfig(e.TLS); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
validProtocols := map[string]bool{
|
||||
"tcp": true,
|
||||
"http": true,
|
||||
|
@ -264,6 +310,12 @@ func (e *IngressGatewayConfigEntry) Validate() error {
|
|||
listener.Port)
|
||||
}
|
||||
|
||||
if listener.TLS != nil {
|
||||
if err := validateGatewayTLSConfig(*listener.TLS); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
declaredHosts := make(map[string]bool)
|
||||
serviceNames := make(map[ServiceID]struct{})
|
||||
for _, s := range listener.Services {
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/cache"
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
"github.com/hashicorp/consul/types"
|
||||
)
|
||||
|
||||
func TestConfigEntries_ACLs(t *testing.T) {
|
||||
|
@ -1107,6 +1108,7 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
// TODO(rb): test SDS stuff here in both places (global/service)
|
||||
name: "ingress-gateway: kitchen sink",
|
||||
snake: `
|
||||
kind = "ingress-gateway"
|
||||
|
@ -1118,6 +1120,12 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
|
||||
tls {
|
||||
enabled = true
|
||||
tls_min_version = "TLSv1_1"
|
||||
tls_max_version = "TLSv1_2"
|
||||
cipher_suites = [
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
}
|
||||
|
||||
listeners = [
|
||||
|
@ -1181,6 +1189,12 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
}
|
||||
TLS {
|
||||
Enabled = true
|
||||
TLSMinVersion = "TLSv1_1"
|
||||
TLSMaxVersion = "TLSv1_2"
|
||||
CipherSuites = [
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
}
|
||||
Listeners = [
|
||||
{
|
||||
|
@ -1242,7 +1256,13 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
"gir": "zim",
|
||||
},
|
||||
TLS: GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
Enabled: true,
|
||||
TLSMinVersion: types.TLSv1_1,
|
||||
TLSMaxVersion: types.TLSv1_2,
|
||||
CipherSuites: []types.TLSCipherSuite{
|
||||
types.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
types.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
},
|
||||
},
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
|
|
|
@ -186,7 +186,7 @@ func makePassthroughClusters(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message,
|
|||
ConnectTimeout: ptypes.DurationProto(5 * time.Second),
|
||||
}
|
||||
|
||||
commonTLSContext := makeCommonTLSContextFromLeaf(cfgSnap, cfgSnap.Leaf())
|
||||
commonTLSContext := makeCommonTLSContextFromLeafWithoutParams(cfgSnap, cfgSnap.Leaf())
|
||||
err := injectSANMatcher(commonTLSContext, passthrough.SpiffeID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", passthrough.SNI, err)
|
||||
|
@ -550,7 +550,7 @@ func (s *ResourceGenerator) makeUpstreamClusterForPreparedQuery(upstream structs
|
|||
}
|
||||
|
||||
// Enable TLS upstream with the configured client certificate.
|
||||
commonTLSContext := makeCommonTLSContextFromLeaf(cfgSnap, cfgSnap.Leaf())
|
||||
commonTLSContext := makeCommonTLSContextFromLeafWithoutParams(cfgSnap, cfgSnap.Leaf())
|
||||
err = injectSANMatcher(commonTLSContext, spiffeIDs...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", sni, err)
|
||||
|
@ -728,7 +728,7 @@ func (s *ResourceGenerator) makeUpstreamClustersForDiscoveryChain(
|
|||
c.Http2ProtocolOptions = &envoy_core_v3.Http2ProtocolOptions{}
|
||||
}
|
||||
|
||||
commonTLSContext := makeCommonTLSContextFromLeaf(cfgSnap, cfgSnap.Leaf())
|
||||
commonTLSContext := makeCommonTLSContextFromLeafWithoutParams(cfgSnap, cfgSnap.Leaf())
|
||||
err = injectSANMatcher(commonTLSContext, spiffeIDs...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", sni, err)
|
||||
|
|
|
@ -740,7 +740,7 @@ func injectHTTPFilterOnFilterChains(
|
|||
func (s *ResourceGenerator) injectConnectTLSOnFilterChains(cfgSnap *proxycfg.ConfigSnapshot, listener *envoy_listener_v3.Listener) error {
|
||||
for idx := range listener.FilterChains {
|
||||
tlsContext := &envoy_tls_v3.DownstreamTlsContext{
|
||||
CommonTlsContext: makeCommonTLSContextFromLeaf(cfgSnap, cfgSnap.Leaf()),
|
||||
CommonTlsContext: makeCommonTLSContextFromLeafWithoutParams(cfgSnap, cfgSnap.Leaf()),
|
||||
RequireClientCertificate: &wrappers.BoolValue{Value: true},
|
||||
}
|
||||
transportSocket, err := makeDownstreamTLSTransportSocket(tlsContext)
|
||||
|
@ -1062,7 +1062,7 @@ func (s *ResourceGenerator) makeFilterChainTerminatingGateway(
|
|||
protocol string,
|
||||
) (*envoy_listener_v3.FilterChain, error) {
|
||||
tlsContext := &envoy_tls_v3.DownstreamTlsContext{
|
||||
CommonTlsContext: makeCommonTLSContextFromLeaf(cfgSnap, cfgSnap.TerminatingGateway.ServiceLeaves[service]),
|
||||
CommonTlsContext: makeCommonTLSContextFromLeafWithoutParams(cfgSnap, cfgSnap.TerminatingGateway.ServiceLeaves[service]),
|
||||
RequireClientCertificate: &wrappers.BoolValue{Value: true},
|
||||
}
|
||||
transportSocket, err := makeDownstreamTLSTransportSocket(tlsContext)
|
||||
|
@ -1536,7 +1536,11 @@ func makeEnvoyHTTPFilter(name string, cfg proto.Message) (*envoy_http_v3.HttpFil
|
|||
}, nil
|
||||
}
|
||||
|
||||
func makeCommonTLSContextFromLeaf(cfgSnap *proxycfg.ConfigSnapshot, leaf *structs.IssuedCert) *envoy_tls_v3.CommonTlsContext {
|
||||
func makeCommonTLSContextFromLeafWithoutParams(cfgSnap *proxycfg.ConfigSnapshot, leaf *structs.IssuedCert) *envoy_tls_v3.CommonTlsContext {
|
||||
return makeCommonTLSContextFromLeaf(cfgSnap, leaf, nil)
|
||||
}
|
||||
|
||||
func makeCommonTLSContextFromLeaf(cfgSnap *proxycfg.ConfigSnapshot, leaf *structs.IssuedCert, tlsParams *envoy_tls_v3.TlsParameters) *envoy_tls_v3.CommonTlsContext {
|
||||
// Concatenate all the root PEMs into one.
|
||||
if cfgSnap.Roots == nil {
|
||||
return nil
|
||||
|
@ -1547,8 +1551,12 @@ func makeCommonTLSContextFromLeaf(cfgSnap *proxycfg.ConfigSnapshot, leaf *struct
|
|||
rootPEMS += ca.EnsureTrailingNewline(root.RootCert)
|
||||
}
|
||||
|
||||
if tlsParams == nil {
|
||||
tlsParams = &envoy_tls_v3.TlsParameters{}
|
||||
}
|
||||
|
||||
return &envoy_tls_v3.CommonTlsContext{
|
||||
TlsParams: &envoy_tls_v3.TlsParameters{},
|
||||
TlsParams: tlsParams,
|
||||
TlsCertificates: []*envoy_tls_v3.TlsCertificate{
|
||||
{
|
||||
CertificateChain: &envoy_core_v3.DataSource{
|
||||
|
|
|
@ -8,43 +8,26 @@ import (
|
|||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes/duration"
|
||||
"github.com/golang/protobuf/ptypes/wrappers"
|
||||
|
||||
"github.com/hashicorp/consul/agent/proxycfg"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/types"
|
||||
)
|
||||
|
||||
func (s *ResourceGenerator) makeIngressGatewayListeners(address string, cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) {
|
||||
var resources []proto.Message
|
||||
|
||||
for listenerKey, upstreams := range cfgSnap.IngressGateway.Upstreams {
|
||||
var tlsContext *envoy_tls_v3.DownstreamTlsContext
|
||||
|
||||
listenerCfg, ok := cfgSnap.IngressGateway.Listeners[listenerKey]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no listener config found for listener on port %d", listenerKey.Port)
|
||||
}
|
||||
// Enable connect TLS if it is enabled at the Gateway or specific listener
|
||||
// level.
|
||||
connectTLSEnabled := cfgSnap.IngressGateway.TLSConfig.Enabled ||
|
||||
(listenerCfg.TLS != nil && listenerCfg.TLS.Enabled)
|
||||
|
||||
sdsCfg, err := resolveListenerSDSConfig(cfgSnap, listenerCfg)
|
||||
tlsContext, err := makeDownstreamTLSContextFromSnapshotListenerConfig(cfgSnap, listenerCfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sdsCfg != nil {
|
||||
// Set up listener TLS from SDS
|
||||
tlsContext = &envoy_tls_v3.DownstreamTlsContext{
|
||||
CommonTlsContext: makeCommonTLSContextFromSDS(*sdsCfg),
|
||||
RequireClientCertificate: &wrappers.BoolValue{Value: false},
|
||||
}
|
||||
} else if connectTLSEnabled {
|
||||
tlsContext = &envoy_tls_v3.DownstreamTlsContext{
|
||||
CommonTlsContext: makeCommonTLSContextFromLeaf(cfgSnap, cfgSnap.Leaf()),
|
||||
RequireClientCertificate: &wrappers.BoolValue{Value: false},
|
||||
}
|
||||
}
|
||||
|
||||
if listenerKey.Protocol == "tcp" {
|
||||
// We rely on the invariant of upstreams slice always having at least 1
|
||||
// member, because this key/value pair is created only when a
|
||||
|
@ -154,21 +137,116 @@ func (s *ResourceGenerator) makeIngressGatewayListeners(address string, cfgSnap
|
|||
return resources, nil
|
||||
}
|
||||
|
||||
func resolveListenerSDSConfig(cfgSnap *proxycfg.ConfigSnapshot, listenerCfg structs.IngressListener) (*structs.GatewayTLSSDSConfig, error) {
|
||||
var mergedCfg structs.GatewayTLSSDSConfig
|
||||
func makeDownstreamTLSContextFromSnapshotListenerConfig(cfgSnap *proxycfg.ConfigSnapshot, listenerCfg structs.IngressListener) (*envoy_tls_v3.DownstreamTlsContext, error) {
|
||||
var downstreamContext *envoy_tls_v3.DownstreamTlsContext
|
||||
|
||||
gwSDS := cfgSnap.IngressGateway.TLSConfig.SDS
|
||||
if gwSDS != nil {
|
||||
mergedCfg.ClusterName = gwSDS.ClusterName
|
||||
mergedCfg.CertResource = gwSDS.CertResource
|
||||
tlsContext, err := makeCommonTLSContextFromSnapshotListenerConfig(cfgSnap, listenerCfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if listenerCfg.TLS != nil && listenerCfg.TLS.SDS != nil {
|
||||
if listenerCfg.TLS.SDS.ClusterName != "" {
|
||||
mergedCfg.ClusterName = listenerCfg.TLS.SDS.ClusterName
|
||||
if tlsContext != nil {
|
||||
downstreamContext = &envoy_tls_v3.DownstreamTlsContext{
|
||||
CommonTlsContext: tlsContext,
|
||||
RequireClientCertificate: &wrappers.BoolValue{Value: false},
|
||||
}
|
||||
if listenerCfg.TLS.SDS.CertResource != "" {
|
||||
mergedCfg.CertResource = listenerCfg.TLS.SDS.CertResource
|
||||
}
|
||||
|
||||
return downstreamContext, nil
|
||||
}
|
||||
|
||||
func makeCommonTLSContextFromSnapshotListenerConfig(cfgSnap *proxycfg.ConfigSnapshot, listenerCfg structs.IngressListener) (*envoy_tls_v3.CommonTlsContext, error) {
|
||||
var tlsContext *envoy_tls_v3.CommonTlsContext
|
||||
|
||||
// Enable connect TLS if it is enabled at the Gateway or specific listener
|
||||
// level.
|
||||
gatewayTLSCfg := cfgSnap.IngressGateway.TLSConfig
|
||||
|
||||
// It is not possible to explicitly _disable_ TLS on a listener if it's
|
||||
// enabled on the gateway, because false is the zero-value of the struct field
|
||||
// and therefore indistinguishable from it being unspecified.
|
||||
connectTLSEnabled := gatewayTLSCfg.Enabled ||
|
||||
(listenerCfg.TLS != nil && listenerCfg.TLS.Enabled)
|
||||
|
||||
tlsCfg, err := resolveListenerTLSConfig(&gatewayTLSCfg, listenerCfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tlsCfg.SDS != nil {
|
||||
// Set up listener TLS from SDS
|
||||
tlsContext = makeCommonTLSContextFromGatewayTLSConfig(*tlsCfg)
|
||||
} else if connectTLSEnabled {
|
||||
tlsContext = makeCommonTLSContextFromLeaf(cfgSnap, cfgSnap.Leaf(), makeTLSParametersFromGatewayTLSConfig(*tlsCfg))
|
||||
}
|
||||
|
||||
return tlsContext, nil
|
||||
}
|
||||
|
||||
func resolveListenerTLSConfig(gatewayTLSCfg *structs.GatewayTLSConfig, listenerCfg structs.IngressListener) (*structs.GatewayTLSConfig, error) {
|
||||
var mergedCfg structs.GatewayTLSConfig
|
||||
|
||||
resolvedSDSCfg, err := resolveListenerSDSConfig(gatewayTLSCfg.SDS, listenerCfg.TLS, listenerCfg.Port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mergedCfg.SDS = resolvedSDSCfg
|
||||
|
||||
if gatewayTLSCfg != nil {
|
||||
mergedCfg.TLSMinVersion = gatewayTLSCfg.TLSMinVersion
|
||||
mergedCfg.TLSMaxVersion = gatewayTLSCfg.TLSMaxVersion
|
||||
mergedCfg.CipherSuites = gatewayTLSCfg.CipherSuites
|
||||
}
|
||||
|
||||
if listenerCfg.TLS != nil {
|
||||
if listenerCfg.TLS.TLSMinVersion != types.TLSVersionUnspecified {
|
||||
mergedCfg.TLSMinVersion = listenerCfg.TLS.TLSMinVersion
|
||||
}
|
||||
if listenerCfg.TLS.TLSMaxVersion != types.TLSVersionUnspecified {
|
||||
mergedCfg.TLSMaxVersion = listenerCfg.TLS.TLSMaxVersion
|
||||
}
|
||||
if len(listenerCfg.TLS.CipherSuites) != 0 {
|
||||
mergedCfg.CipherSuites = listenerCfg.TLS.CipherSuites
|
||||
}
|
||||
}
|
||||
|
||||
var TLSVersionsWithConfigurableCipherSuites = map[types.TLSVersion]struct{}{
|
||||
// Remove these two if Envoy ever sets TLS 1.3 as default minimum
|
||||
types.TLSVersionUnspecified: {},
|
||||
types.TLSVersionAuto: {},
|
||||
|
||||
types.TLSv1_0: {},
|
||||
types.TLSv1_1: {},
|
||||
types.TLSv1_2: {},
|
||||
}
|
||||
|
||||
// Validate. Configuring cipher suites is only applicable to connections negotiated
|
||||
// via TLS 1.2 or earlier. Other cases shouldn't be possible as we validate them at
|
||||
// input but be resilient to bugs later.
|
||||
if len(mergedCfg.CipherSuites) != 0 {
|
||||
if _, ok := TLSVersionsWithConfigurableCipherSuites[mergedCfg.TLSMinVersion]; !ok {
|
||||
return nil, fmt.Errorf("configuring CipherSuites is only applicable to connections negotiated with TLS 1.2 or earlier, TLSMinVersion is set to %s in listener or gateway config", mergedCfg.TLSMinVersion)
|
||||
}
|
||||
}
|
||||
|
||||
return &mergedCfg, nil
|
||||
}
|
||||
|
||||
func resolveListenerSDSConfig(gatewaySDSCfg *structs.GatewayTLSSDSConfig, listenerTLSCfg *structs.GatewayTLSConfig, listenerPort int) (*structs.GatewayTLSSDSConfig, error) {
|
||||
var mergedCfg structs.GatewayTLSSDSConfig
|
||||
|
||||
if gatewaySDSCfg != nil {
|
||||
mergedCfg.ClusterName = gatewaySDSCfg.ClusterName
|
||||
mergedCfg.CertResource = gatewaySDSCfg.CertResource
|
||||
}
|
||||
|
||||
if listenerTLSCfg != nil && listenerTLSCfg.SDS != nil {
|
||||
if listenerTLSCfg.SDS.ClusterName != "" {
|
||||
mergedCfg.ClusterName = listenerTLSCfg.SDS.ClusterName
|
||||
}
|
||||
if listenerTLSCfg.SDS.CertResource != "" {
|
||||
mergedCfg.CertResource = listenerTLSCfg.SDS.CertResource
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,10 +261,10 @@ func resolveListenerSDSConfig(cfgSnap *proxycfg.ConfigSnapshot, listenerCfg stru
|
|||
return &mergedCfg, nil
|
||||
|
||||
case mergedCfg.ClusterName == "" && mergedCfg.CertResource != "":
|
||||
return nil, fmt.Errorf("missing SDS cluster name for listener on port %d", listenerCfg.Port)
|
||||
return nil, fmt.Errorf("missing SDS cluster name for listener on port %d", listenerPort)
|
||||
|
||||
case mergedCfg.ClusterName != "" && mergedCfg.CertResource == "":
|
||||
return nil, fmt.Errorf("missing SDS cert resource for listener on port %d", listenerCfg.Port)
|
||||
return nil, fmt.Errorf("missing SDS cert resource for listener on port %d", listenerPort)
|
||||
}
|
||||
|
||||
return &mergedCfg, nil
|
||||
|
@ -260,7 +338,7 @@ func makeSDSOverrideFilterChains(cfgSnap *proxycfg.ConfigSnapshot,
|
|||
}
|
||||
|
||||
tlsContext := &envoy_tls_v3.DownstreamTlsContext{
|
||||
CommonTlsContext: makeCommonTLSContextFromSDS(*svc.TLS.SDS),
|
||||
CommonTlsContext: makeCommonTLSContextFromGatewayServiceTLSConfig(*svc.TLS),
|
||||
RequireClientCertificate: &wrappers.BoolValue{Value: false},
|
||||
}
|
||||
|
||||
|
@ -284,33 +362,71 @@ func makeSDSOverrideFilterChains(cfgSnap *proxycfg.ConfigSnapshot,
|
|||
return chains, nil
|
||||
}
|
||||
|
||||
func makeCommonTLSContextFromSDS(sdsCfg structs.GatewayTLSSDSConfig) *envoy_tls_v3.CommonTlsContext {
|
||||
var envoyTLSVersions = map[types.TLSVersion]envoy_tls_v3.TlsParameters_TlsProtocol{
|
||||
types.TLSVersionAuto: envoy_tls_v3.TlsParameters_TLS_AUTO,
|
||||
types.TLSv1_0: envoy_tls_v3.TlsParameters_TLSv1_0,
|
||||
types.TLSv1_1: envoy_tls_v3.TlsParameters_TLSv1_1,
|
||||
types.TLSv1_2: envoy_tls_v3.TlsParameters_TLSv1_2,
|
||||
types.TLSv1_3: envoy_tls_v3.TlsParameters_TLSv1_3,
|
||||
}
|
||||
|
||||
func makeTLSParametersFromGatewayTLSConfig(tlsCfg structs.GatewayTLSConfig) *envoy_tls_v3.TlsParameters {
|
||||
tlsParams := envoy_tls_v3.TlsParameters{}
|
||||
|
||||
if tlsCfg.TLSMinVersion != types.TLSVersionUnspecified {
|
||||
if minVersion, ok := envoyTLSVersions[tlsCfg.TLSMinVersion]; ok {
|
||||
tlsParams.TlsMinimumProtocolVersion = minVersion
|
||||
}
|
||||
}
|
||||
if tlsCfg.TLSMaxVersion != types.TLSVersionUnspecified {
|
||||
if maxVersion, ok := envoyTLSVersions[tlsCfg.TLSMaxVersion]; ok {
|
||||
tlsParams.TlsMaximumProtocolVersion = maxVersion
|
||||
}
|
||||
}
|
||||
if len(tlsCfg.CipherSuites) != 0 {
|
||||
tlsParams.CipherSuites = types.MarshalEnvoyTLSCipherSuiteStrings(tlsCfg.CipherSuites)
|
||||
}
|
||||
|
||||
return &tlsParams
|
||||
}
|
||||
|
||||
func makeCommonTLSContextFromGatewayTLSConfig(tlsCfg structs.GatewayTLSConfig) *envoy_tls_v3.CommonTlsContext {
|
||||
return &envoy_tls_v3.CommonTlsContext{
|
||||
TlsParams: &envoy_tls_v3.TlsParameters{},
|
||||
TlsCertificateSdsSecretConfigs: []*envoy_tls_v3.SdsSecretConfig{
|
||||
{
|
||||
Name: sdsCfg.CertResource,
|
||||
SdsConfig: &envoy_core_v3.ConfigSource{
|
||||
ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{
|
||||
ApiConfigSource: &envoy_core_v3.ApiConfigSource{
|
||||
ApiType: envoy_core_v3.ApiConfigSource_GRPC,
|
||||
TransportApiVersion: envoy_core_v3.ApiVersion_V3,
|
||||
// Note ClusterNames can't be set here - that's only for REST type
|
||||
// we need a full GRPC config instead.
|
||||
GrpcServices: []*envoy_core_v3.GrpcService{
|
||||
{
|
||||
TargetSpecifier: &envoy_core_v3.GrpcService_EnvoyGrpc_{
|
||||
EnvoyGrpc: &envoy_core_v3.GrpcService_EnvoyGrpc{
|
||||
ClusterName: sdsCfg.ClusterName,
|
||||
},
|
||||
TlsParams: makeTLSParametersFromGatewayTLSConfig(tlsCfg),
|
||||
TlsCertificateSdsSecretConfigs: makeTLSCertificateSdsSecretConfigsFromSDS(*tlsCfg.SDS),
|
||||
}
|
||||
}
|
||||
|
||||
func makeCommonTLSContextFromGatewayServiceTLSConfig(tlsCfg structs.GatewayServiceTLSConfig) *envoy_tls_v3.CommonTlsContext {
|
||||
return &envoy_tls_v3.CommonTlsContext{
|
||||
TlsParams: &envoy_tls_v3.TlsParameters{},
|
||||
TlsCertificateSdsSecretConfigs: makeTLSCertificateSdsSecretConfigsFromSDS(*tlsCfg.SDS),
|
||||
}
|
||||
}
|
||||
func makeTLSCertificateSdsSecretConfigsFromSDS(sdsCfg structs.GatewayTLSSDSConfig) []*envoy_tls_v3.SdsSecretConfig {
|
||||
return []*envoy_tls_v3.SdsSecretConfig{
|
||||
{
|
||||
Name: sdsCfg.CertResource,
|
||||
SdsConfig: &envoy_core_v3.ConfigSource{
|
||||
ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{
|
||||
ApiConfigSource: &envoy_core_v3.ApiConfigSource{
|
||||
ApiType: envoy_core_v3.ApiConfigSource_GRPC,
|
||||
TransportApiVersion: envoy_core_v3.ApiVersion_V3,
|
||||
// Note ClusterNames can't be set here - that's only for REST type
|
||||
// we need a full GRPC config instead.
|
||||
GrpcServices: []*envoy_core_v3.GrpcService{
|
||||
{
|
||||
TargetSpecifier: &envoy_core_v3.GrpcService_EnvoyGrpc_{
|
||||
EnvoyGrpc: &envoy_core_v3.GrpcService_EnvoyGrpc{
|
||||
ClusterName: sdsCfg.ClusterName,
|
||||
},
|
||||
Timeout: &duration.Duration{Seconds: 5},
|
||||
},
|
||||
Timeout: &duration.Duration{Seconds: 5},
|
||||
},
|
||||
},
|
||||
},
|
||||
ResourceApiVersion: envoy_core_v3.ApiVersion_V3,
|
||||
},
|
||||
ResourceApiVersion: envoy_core_v3.ApiVersion_V3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -519,6 +519,30 @@ func TestListenersFromSnapshot(t *testing.T) {
|
|||
create: proxycfg.TestConfigSnapshotIngressWithTLSListener,
|
||||
setup: nil,
|
||||
},
|
||||
{
|
||||
name: "ingress-with-tls-listener-min-version",
|
||||
create: proxycfg.TestConfigSnapshotIngressWithTLSListener,
|
||||
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||
snap.IngressGateway.TLSConfig.TLSMinVersion = types.TLSv1_3
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ingress-with-tls-listener-max-version",
|
||||
create: proxycfg.TestConfigSnapshotIngressWithTLSListener,
|
||||
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||
snap.IngressGateway.TLSConfig.TLSMaxVersion = types.TLSv1_2
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ingress-with-tls-listener-cipher-suites",
|
||||
create: proxycfg.TestConfigSnapshotIngressWithTLSListener,
|
||||
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||
snap.IngressGateway.TLSConfig.CipherSuites = []types.TLSCipherSuite{
|
||||
types.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
types.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ingress-with-tls-mixed-listeners",
|
||||
// Use SDS helper even though we aren't testing SDS since it already sets
|
||||
|
@ -572,6 +596,215 @@ func TestListenersFromSnapshot(t *testing.T) {
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ingress-with-tls-min-version-listeners-gateway-defaults",
|
||||
create: proxycfg.TestConfigSnapshotIngressWithTLSListener,
|
||||
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||
snap.IngressGateway.TLSConfig.TLSMinVersion = types.TLSv1_2
|
||||
|
||||
// One listener disables TLS, one inherits TLS minimum version from the gateway
|
||||
// config, two others set different versions
|
||||
snap.IngressGateway.Upstreams = map[proxycfg.IngressListenerKey]structs.Upstreams{
|
||||
{Protocol: "http", Port: 8080}: {
|
||||
{
|
||||
DestinationName: "s1",
|
||||
LocalBindPort: 8080,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8081}: {
|
||||
{
|
||||
DestinationName: "s2",
|
||||
LocalBindPort: 8081,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8082}: {
|
||||
{
|
||||
DestinationName: "s3",
|
||||
LocalBindPort: 8082,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8083}: {
|
||||
{
|
||||
DestinationName: "s4",
|
||||
LocalBindPort: 8083,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8084}: {
|
||||
{
|
||||
DestinationName: "s4",
|
||||
LocalBindPort: 8084,
|
||||
},
|
||||
},
|
||||
}
|
||||
snap.IngressGateway.Listeners = map[proxycfg.IngressListenerKey]structs.IngressListener{
|
||||
// Omits listener TLS config, should default to gateway TLS config
|
||||
{Protocol: "http", Port: 8080}: {
|
||||
Port: 8080,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s1",
|
||||
},
|
||||
},
|
||||
},
|
||||
// Explicitly sets listener TLS config to nil, should default to gateway TLS config
|
||||
{Protocol: "http", Port: 8081}: {
|
||||
Port: 8081,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s2",
|
||||
},
|
||||
},
|
||||
TLS: nil,
|
||||
},
|
||||
// Explicitly enables TLS config, but with no listener default TLS params,
|
||||
// should default to gateway TLS config
|
||||
{Protocol: "http", Port: 8082}: {
|
||||
Port: 8082,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s3",
|
||||
},
|
||||
},
|
||||
TLS: &structs.GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
// Explicitly unset gateway default TLS min version in favor of proxy default
|
||||
{Protocol: "http", Port: 8083}: {
|
||||
Port: 8083,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s3",
|
||||
},
|
||||
},
|
||||
TLS: &structs.GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
TLSMinVersion: types.TLSVersionAuto,
|
||||
},
|
||||
},
|
||||
// Disables listener TLS
|
||||
{Protocol: "http", Port: 8084}: {
|
||||
Port: 8084,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s4",
|
||||
},
|
||||
},
|
||||
TLS: &structs.GatewayTLSConfig{
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ingress-with-single-tls-listener",
|
||||
create: proxycfg.TestConfigSnapshotIngress,
|
||||
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||
// One listener should inherit non-TLS gateway config, another
|
||||
// listener configures TLS with an explicit minimum version
|
||||
snap.IngressGateway.Upstreams = map[proxycfg.IngressListenerKey]structs.Upstreams{
|
||||
{Protocol: "http", Port: 8080}: {
|
||||
{
|
||||
DestinationName: "s1",
|
||||
LocalBindPort: 8080,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8081}: {
|
||||
{
|
||||
DestinationName: "s2",
|
||||
LocalBindPort: 8081,
|
||||
},
|
||||
},
|
||||
}
|
||||
snap.IngressGateway.Listeners = map[proxycfg.IngressListenerKey]structs.IngressListener{
|
||||
{Protocol: "http", Port: 8080}: {
|
||||
Port: 8080,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8081}: {
|
||||
Port: 8081,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s2",
|
||||
},
|
||||
},
|
||||
TLS: &structs.GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
TLSMinVersion: types.TLSv1_2,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ingress-with-tls-mixed-min-version-listeners",
|
||||
create: proxycfg.TestConfigSnapshotIngressWithTLSListener,
|
||||
setup: func(snap *proxycfg.ConfigSnapshot) {
|
||||
snap.IngressGateway.TLSConfig.TLSMinVersion = types.TLSv1_2
|
||||
|
||||
// One listener should inherit TLS minimum version from the gateway config,
|
||||
// two others each set explicit TLS minimum versions
|
||||
snap.IngressGateway.Upstreams = map[proxycfg.IngressListenerKey]structs.Upstreams{
|
||||
{Protocol: "http", Port: 8080}: {
|
||||
{
|
||||
DestinationName: "s1",
|
||||
LocalBindPort: 8080,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8081}: {
|
||||
{
|
||||
DestinationName: "s2",
|
||||
LocalBindPort: 8081,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8082}: {
|
||||
{
|
||||
DestinationName: "s3",
|
||||
LocalBindPort: 8082,
|
||||
},
|
||||
},
|
||||
}
|
||||
snap.IngressGateway.Listeners = map[proxycfg.IngressListenerKey]structs.IngressListener{
|
||||
{Protocol: "http", Port: 8080}: {
|
||||
Port: 8080,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s1",
|
||||
},
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8081}: {
|
||||
Port: 8081,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s2",
|
||||
},
|
||||
},
|
||||
TLS: &structs.GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
TLSMinVersion: types.TLSv1_0,
|
||||
},
|
||||
},
|
||||
{Protocol: "http", Port: 8082}: {
|
||||
Port: 8082,
|
||||
Services: []structs.IngressService{
|
||||
{
|
||||
Name: "s3",
|
||||
},
|
||||
},
|
||||
TLS: &structs.GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
TLSMinVersion: types.TLSv1_3,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ingress-with-sds-listener-gw-level",
|
||||
create: proxycfg.TestConfigSnapshotIngressWithGatewaySDS,
|
||||
|
@ -1208,7 +1441,7 @@ func TestResolveListenerSDSConfig(t *testing.T) {
|
|||
listenerCfg = lisCfg
|
||||
}
|
||||
|
||||
got, err := resolveListenerSDSConfig(snap, listenerCfg)
|
||||
got, err := resolveListenerSDSConfig(snap.IngressGateway.TLSConfig.SDS, listenerCfg.TLS, listenerCfg.Port)
|
||||
if tc.wantErr != "" {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), tc.wantErr)
|
||||
|
|
120
agent/xds/testdata/listeners/ingress-with-single-tls-listener.envoy-1-20-x.golden
vendored
Normal file
120
agent/xds/testdata/listeners/ingress-with-single-tls-listener.envoy-1-20-x.golden
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8080",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8080
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8080",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8080"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8081",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8081
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8081",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8081"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_2"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
}
|
||||
],
|
||||
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"nonce": "00000001"
|
||||
}
|
62
agent/xds/testdata/listeners/ingress-with-tls-listener-cipher-suites.envoy-1-20-x.golden
vendored
Normal file
62
agent/xds/testdata/listeners/ingress-with-tls-listener-cipher-suites.envoy-1-20-x.golden
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "db:1.2.3.4:9191",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 9191
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.tcp_proxy",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
|
||||
"statPrefix": "upstream.db.default.default.dc1",
|
||||
"cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"cipherSuites": [
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
"ECDHE-ECDSA-CHACHA20-POLY1305"
|
||||
]
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
}
|
||||
],
|
||||
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"nonce": "00000001"
|
||||
}
|
59
agent/xds/testdata/listeners/ingress-with-tls-listener-max-version.envoy-1-20-x.golden
vendored
Normal file
59
agent/xds/testdata/listeners/ingress-with-tls-listener-max-version.envoy-1-20-x.golden
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "db:1.2.3.4:9191",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 9191
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.tcp_proxy",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
|
||||
"statPrefix": "upstream.db.default.default.dc1",
|
||||
"cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMaximumProtocolVersion": "TLSv1_2"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
}
|
||||
],
|
||||
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"nonce": "00000001"
|
||||
}
|
59
agent/xds/testdata/listeners/ingress-with-tls-listener-min-version.envoy-1-20-x.golden
vendored
Normal file
59
agent/xds/testdata/listeners/ingress-with-tls-listener-min-version.envoy-1-20-x.golden
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "db:1.2.3.4:9191",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 9191
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.tcp_proxy",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
|
||||
"statPrefix": "upstream.db.default.default.dc1",
|
||||
"cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_3"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
}
|
||||
],
|
||||
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"nonce": "00000001"
|
||||
}
|
|
@ -0,0 +1,357 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8080",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8080
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8080",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8080"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_2"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8081",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8081
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8081",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8081"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_2"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8082",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8082
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8082",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8082"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_2"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8083",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8083
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8083",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8083"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8084",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8084
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8084",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8084"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_2"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
}
|
||||
],
|
||||
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"nonce": "00000001"
|
||||
}
|
217
agent/xds/testdata/listeners/ingress-with-tls-mixed-min-version-listeners.envoy-1-20-x.golden
vendored
Normal file
217
agent/xds/testdata/listeners/ingress-with-tls-mixed-min-version-listeners.envoy-1-20-x.golden
vendored
Normal file
|
@ -0,0 +1,217 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8080",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8080
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8080",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8080"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_2"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8081",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8081
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8081",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8081"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_0"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"name": "http:1.2.3.4:8082",
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "1.2.3.4",
|
||||
"portValue": 8082
|
||||
}
|
||||
},
|
||||
"filterChains": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
|
||||
"statPrefix": "ingress_upstream_8082",
|
||||
"rds": {
|
||||
"configSource": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
},
|
||||
"routeConfigName": "8082"
|
||||
},
|
||||
"httpFilters": [
|
||||
{
|
||||
"name": "envoy.filters.http.router"
|
||||
}
|
||||
],
|
||||
"tracing": {
|
||||
"randomSampling": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
"tlsMinimumProtocolVersion": "TLSv1_3"
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
|
||||
},
|
||||
"privateKey": {
|
||||
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requireClientCertificate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"trafficDirection": "OUTBOUND"
|
||||
}
|
||||
],
|
||||
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
|
||||
"nonce": "00000001"
|
||||
}
|
|
@ -43,6 +43,13 @@ type GatewayTLSConfig struct {
|
|||
|
||||
// SDS allows configuring TLS certificate from an SDS service.
|
||||
SDS *GatewayTLSSDSConfig `json:",omitempty"`
|
||||
|
||||
TLSMinVersion string `json:",omitempty" alias:"tls_min_version"`
|
||||
TLSMaxVersion string `json:",omitempty" alias:"tls_max_version"`
|
||||
|
||||
// Define a subset of cipher suites to restrict
|
||||
// Only applicable to connections negotiated via TLS 1.2 or earlier
|
||||
CipherSuites []string `json:",omitempty" alias:"cipher_suites"`
|
||||
}
|
||||
|
||||
type GatewayServiceTLSConfig struct {
|
||||
|
|
|
@ -26,7 +26,8 @@ func TestAPI_ConfigEntries_IngressGateway(t *testing.T) {
|
|||
Kind: IngressGateway,
|
||||
Name: "bar",
|
||||
TLS: GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
Enabled: true,
|
||||
TLSMinVersion: "TLSv1_2",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -945,6 +945,7 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
// TODO(rb): test SDS stuff here in both places (global/service)
|
||||
name: "ingress-gateway",
|
||||
body: `
|
||||
{
|
||||
|
@ -955,7 +956,13 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
"gir": "zim"
|
||||
},
|
||||
"Tls": {
|
||||
"Enabled": true
|
||||
"Enabled": true,
|
||||
"TLSMinVersion": "TLSv1_1",
|
||||
"TLSMaxVersion": "TLSv1_2",
|
||||
"CipherSuites": [
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
},
|
||||
"Listeners": [
|
||||
{
|
||||
|
@ -992,7 +999,13 @@ func TestDecodeConfigEntry(t *testing.T) {
|
|||
"gir": "zim",
|
||||
},
|
||||
TLS: GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
Enabled: true,
|
||||
TLSMinVersion: "TLSv1_1",
|
||||
TLSMaxVersion: "TLSv1_2",
|
||||
CipherSuites: []string{
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
},
|
||||
},
|
||||
Listeners: []IngressListener{
|
||||
{
|
||||
|
|
|
@ -2096,6 +2096,7 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
// TODO(rb): test SDS stuff here in both places (global/service)
|
||||
name: "ingress-gateway: kitchen sink",
|
||||
snake: `
|
||||
kind = "ingress-gateway"
|
||||
|
@ -2106,6 +2107,12 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
}
|
||||
tls {
|
||||
enabled = true
|
||||
tls_min_version = "TLSv1_1"
|
||||
tls_max_version = "TLSv1_2"
|
||||
cipher_suites = [
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
}
|
||||
listeners = [
|
||||
{
|
||||
|
@ -2133,6 +2140,12 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
}
|
||||
Tls {
|
||||
Enabled = true
|
||||
TLSMinVersion = "TLSv1_1"
|
||||
TLSMaxVersion = "TLSv1_2"
|
||||
CipherSuites = [
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
}
|
||||
Listeners = [
|
||||
{
|
||||
|
@ -2160,7 +2173,13 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
"gir": "zim"
|
||||
},
|
||||
"tls": {
|
||||
"enabled": true
|
||||
"enabled": true,
|
||||
"tls_min_version": "TLSv1_1",
|
||||
"tls_max_version": "TLSv1_2",
|
||||
"cipher_suites": [
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
},
|
||||
"listeners": [
|
||||
{
|
||||
|
@ -2188,8 +2207,14 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
"foo": "bar",
|
||||
"gir": "zim"
|
||||
},
|
||||
"Tls": {
|
||||
"Enabled": true
|
||||
"TLS": {
|
||||
"Enabled": true,
|
||||
"TLSMinVersion": "TLSv1_1",
|
||||
"TLSMaxVersion": "TLSv1_2",
|
||||
"CipherSuites": [
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
},
|
||||
"Listeners": [
|
||||
{
|
||||
|
@ -2217,7 +2242,13 @@ func TestParseConfigEntry(t *testing.T) {
|
|||
"gir": "zim",
|
||||
},
|
||||
TLS: api.GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
Enabled: true,
|
||||
TLSMinVersion: "TLSv1_1",
|
||||
TLSMaxVersion: "TLSv1_2",
|
||||
CipherSuites: []string{
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
},
|
||||
},
|
||||
Listeners: []api.IngressListener{
|
||||
{
|
||||
|
|
240
types/tls.go
240
types/tls.go
|
@ -1,43 +1,42 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TLSVersion is a strongly-typed int used for relative comparison
|
||||
// (minimum, maximum, greater than, less than) of TLS versions
|
||||
type TLSVersion int
|
||||
// TLSVersion is a strongly-typed string for TLS versions
|
||||
type TLSVersion string
|
||||
|
||||
const (
|
||||
// Error value, excluded from lookup maps
|
||||
TLSVersionInvalid TLSVersion = iota - 1
|
||||
TLSVersionInvalid TLSVersion = "TLS_INVALID"
|
||||
|
||||
// Explicit unspecified zero-value to avoid overwriting parent defaults
|
||||
TLSVersionUnspecified
|
||||
TLSVersionUnspecified TLSVersion = ""
|
||||
|
||||
// Explictly allow implementation to select TLS version
|
||||
// May be useful to supercede defaults specified at a higher layer
|
||||
TLSVersionAuto
|
||||
TLSVersionAuto TLSVersion = "TLS_AUTO"
|
||||
|
||||
_ // Placeholder for SSLv3, hopefully we won't have to add this
|
||||
|
||||
// TLS versions
|
||||
TLSv1_0
|
||||
TLSv1_1
|
||||
TLSv1_2
|
||||
TLSv1_3
|
||||
TLSv1_0 TLSVersion = "TLSv1_0"
|
||||
TLSv1_1 TLSVersion = "TLSv1_1"
|
||||
TLSv1_2 TLSVersion = "TLSv1_2"
|
||||
TLSv1_3 TLSVersion = "TLSv1_3"
|
||||
)
|
||||
|
||||
var (
|
||||
TLSVersions = map[string]TLSVersion{
|
||||
"TLS_AUTO": TLSVersionAuto,
|
||||
"TLSv1_0": TLSv1_0,
|
||||
"TLSv1_1": TLSv1_1,
|
||||
"TLSv1_2": TLSv1_2,
|
||||
"TLSv1_3": TLSv1_3,
|
||||
tlsVersions = map[TLSVersion]struct{}{
|
||||
TLSVersionAuto: {},
|
||||
TLSv1_0: {},
|
||||
TLSv1_1: {},
|
||||
TLSv1_2: {},
|
||||
TLSv1_3: {},
|
||||
}
|
||||
// NOTE: This interface is deprecated in favor of TLSVersions
|
||||
// NOTE: This interface is deprecated in favor of tlsVersions
|
||||
// and should be eventually removed in a future release.
|
||||
DeprecatedConsulAgentTLSVersions = map[string]TLSVersion{
|
||||
"": TLSVersionAuto,
|
||||
|
@ -46,24 +45,10 @@ var (
|
|||
"tls12": TLSv1_2,
|
||||
"tls13": TLSv1_3,
|
||||
}
|
||||
HumanTLSVersionStrings = map[TLSVersion]string{
|
||||
TLSVersionAuto: "Allow implementation to select TLS version",
|
||||
TLSv1_0: "TLS 1.0",
|
||||
TLSv1_1: "TLS 1.1",
|
||||
TLSv1_2: "TLS 1.2",
|
||||
TLSv1_3: "TLS 1.3",
|
||||
}
|
||||
ConsulConfigTLSVersionStrings = func() map[TLSVersion]string {
|
||||
inverted := make(map[TLSVersion]string, len(TLSVersions))
|
||||
for k, v := range TLSVersions {
|
||||
inverted[v] = k
|
||||
}
|
||||
return inverted
|
||||
}()
|
||||
// NOTE: these currently map to the deprecated config strings to support the
|
||||
// deployment pattern of upgrading servers first. This map should eventually
|
||||
// be removed and any lookups updated to use ConsulConfigTLSVersionStrings
|
||||
// with newer config strings instead in a future release.
|
||||
// be removed and any lookups updated to instead use the TLSVersion string
|
||||
// values directly in a future release.
|
||||
ConsulAutoConfigTLSVersionStrings = map[TLSVersion]string{
|
||||
TLSVersionAuto: "",
|
||||
TLSv1_0: "tls10",
|
||||
|
@ -71,33 +56,51 @@ var (
|
|||
TLSv1_2: "tls12",
|
||||
TLSv1_3: "tls13",
|
||||
}
|
||||
TLSVersionsWithConfigurableCipherSuites = map[TLSVersion]struct{}{
|
||||
// NOTE: these two are implementation-dependent, but it is not expected that
|
||||
// either Go or Envoy would default to TLS 1.3 as a minimum version in the
|
||||
// near future
|
||||
TLSVersionUnspecified: {},
|
||||
TLSVersionAuto: {},
|
||||
|
||||
TLSv1_0: {},
|
||||
TLSv1_1: {},
|
||||
TLSv1_2: {},
|
||||
}
|
||||
)
|
||||
|
||||
func (v TLSVersion) String() string {
|
||||
return ConsulConfigTLSVersionStrings[v]
|
||||
func (v *TLSVersion) String() string {
|
||||
return string(*v)
|
||||
}
|
||||
|
||||
func (v TLSVersion) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.String())
|
||||
var tlsVersionComparison = map[TLSVersion]uint{
|
||||
TLSv1_0: 1,
|
||||
TLSv1_1: 2,
|
||||
TLSv1_2: 3,
|
||||
TLSv1_3: 4,
|
||||
}
|
||||
|
||||
func (v *TLSVersion) UnmarshalJSON(bytes []byte) error {
|
||||
versionStr := string(bytes)
|
||||
|
||||
if n := len(versionStr); n > 1 && versionStr[0] == '"' && versionStr[n-1] == '"' {
|
||||
versionStr = versionStr[1 : n-1] // trim surrounding quotes
|
||||
// Will only return true for concrete versions and won't catch
|
||||
// implementation-dependent conflicts with TLSVersionAuto or unspecified values
|
||||
func (a TLSVersion) LessThan(b TLSVersion) (error, bool) {
|
||||
for _, v := range []TLSVersion{a, b} {
|
||||
if _, ok := tlsVersionComparison[v]; !ok {
|
||||
return fmt.Errorf("can't compare implementation-dependent values"), false
|
||||
}
|
||||
}
|
||||
|
||||
if version, ok := TLSVersions[versionStr]; ok {
|
||||
*v = version
|
||||
return nil
|
||||
}
|
||||
|
||||
*v = TLSVersionInvalid
|
||||
return fmt.Errorf("no matching TLS Version found for %s", versionStr)
|
||||
return nil, tlsVersionComparison[a] < tlsVersionComparison[b]
|
||||
}
|
||||
|
||||
// IANA cipher suite constants and values as defined at
|
||||
func ValidateTLSVersion(v TLSVersion) error {
|
||||
if _, ok := tlsVersions[v]; !ok {
|
||||
return fmt.Errorf("no matching TLS version found for %s", v.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IANA cipher suite string constants as defined at
|
||||
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
|
||||
// This is the total list of TLS 1.2-style cipher suites
|
||||
// which are currently supported by either Envoy 1.21 or the Consul agent
|
||||
|
@ -106,67 +109,49 @@ func (v *TLSVersion) UnmarshalJSON(bytes []byte) error {
|
|||
// and as supported cipher suites in the Go runtime change.
|
||||
//
|
||||
// The naming convention for cipher suites changed in TLS 1.3
|
||||
// but constant values should still be globally unqiue
|
||||
// Handling validation on a subset of TLSCipherSuite constants
|
||||
// would be a future exercise if cipher suites for TLS 1.3 ever
|
||||
// become configurable in BoringSSL, Envoy, or other implementation
|
||||
type TLSCipherSuite uint16
|
||||
// but constant values should still be globally unqiue.
|
||||
//
|
||||
// Handling validation on distinct sets of TLS 1.3 and TLS 1.2 TLSCipherSuite
|
||||
// constants would be a future exercise if cipher suites for TLS 1.3 ever
|
||||
// become configurable in BoringSSL, Envoy, or other implementation.
|
||||
type TLSCipherSuite string
|
||||
|
||||
const (
|
||||
// Envoy cipher suites also used by Consul agent
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0xc02b
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xcca9 // Not used by Consul agent yet
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xcca8 // Not used by Consul agent yet
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xc009
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xc013
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xc02c
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xc030
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xc00a
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xc014
|
||||
// Cipher suites used by both Envoy and Consul agent
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
|
||||
|
||||
// Older cipher suites not supported for Consul agent TLS, will eventually be removed from Envoy defaults
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009c
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA = 0x002f
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009d
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
|
||||
|
||||
// Additional cipher suites used by Consul agent but not Envoy
|
||||
// TODO: these are both explicitly listed as insecure and disabled in the Go source, should they be removed?
|
||||
// https://cs.opensource.google/go/go/+/refs/tags/go1.17.3:src/crypto/tls/cipher_suites.go;l=329-330
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0x0023
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xc027
|
||||
// Older cipher suites not supported for Consul agent TLS,
|
||||
// will eventually be removed from Envoy defaults
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256 = "TLS_RSA_WITH_AES_128_GCM_SHA256"
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA = "TLS_RSA_WITH_AES_128_CBC_SHA"
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384 = "TLS_RSA_WITH_AES_256_GCM_SHA384"
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA = "TLS_RSA_WITH_AES_256_CBC_SHA"
|
||||
)
|
||||
|
||||
var (
|
||||
TLSCipherSuites = map[string]TLSCipherSuite{
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
consulAgentTLSCipherSuites = map[TLSCipherSuite]struct{}{
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: {},
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {},
|
||||
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_RSA_WITH_AES_128_GCM_SHA256": TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA": TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_RSA_WITH_AES_256_GCM_SHA384": TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA": TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: {},
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: {},
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: {},
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: {},
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: {},
|
||||
}
|
||||
HumanTLSCipherSuiteStrings = func() map[TLSCipherSuite]string {
|
||||
inverted := make(map[TLSCipherSuite]string, len(TLSCipherSuites))
|
||||
for k, v := range TLSCipherSuites {
|
||||
inverted[v] = k
|
||||
}
|
||||
return inverted
|
||||
}()
|
||||
EnvoyTLSCipherSuiteStrings = map[TLSCipherSuite]string{
|
||||
envoyTLSCipherSuiteStrings = map[TLSCipherSuite]string{
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: "ECDHE-ECDSA-CHACHA20-POLY1305",
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "ECDHE-RSA-AES128-GCM-SHA256",
|
||||
|
@ -183,3 +168,50 @@ var (
|
|||
TLS_RSA_WITH_AES_256_CBC_SHA: "AES256-SHA",
|
||||
}
|
||||
)
|
||||
|
||||
func (c *TLSCipherSuite) String() string {
|
||||
return string(*c)
|
||||
}
|
||||
|
||||
func ValidateConsulAgentCipherSuites(cipherSuites []TLSCipherSuite) error {
|
||||
var unmatched []string
|
||||
|
||||
for _, c := range cipherSuites {
|
||||
if _, ok := consulAgentTLSCipherSuites[c]; !ok {
|
||||
unmatched = append(unmatched, c.String())
|
||||
}
|
||||
}
|
||||
|
||||
if len(unmatched) > 0 {
|
||||
return fmt.Errorf("no matching Consul Agent TLS cipher suite found for %s", strings.Join(unmatched, ","))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateEnvoyCipherSuites(cipherSuites []TLSCipherSuite) error {
|
||||
var unmatched []string
|
||||
|
||||
for _, c := range cipherSuites {
|
||||
if _, ok := envoyTLSCipherSuiteStrings[c]; !ok {
|
||||
unmatched = append(unmatched, c.String())
|
||||
}
|
||||
}
|
||||
|
||||
if len(unmatched) > 0 {
|
||||
return fmt.Errorf("no matching Envoy TLS cipher suite found for %s", strings.Join(unmatched, ","))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func MarshalEnvoyTLSCipherSuiteStrings(cipherSuites []TLSCipherSuite) []string {
|
||||
cipherSuiteStrings := []string{}
|
||||
|
||||
for _, c := range cipherSuites {
|
||||
if s, ok := envoyTLSCipherSuiteStrings[c]; ok {
|
||||
cipherSuiteStrings = append(cipherSuiteStrings, s)
|
||||
}
|
||||
}
|
||||
|
||||
return cipherSuiteStrings
|
||||
}
|
||||
|
|
|
@ -7,14 +7,12 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTLSVersion_PartialEq(t *testing.T) {
|
||||
require.Greater(t, TLSv1_3, TLSv1_2)
|
||||
require.Greater(t, TLSv1_2, TLSv1_1)
|
||||
require.Greater(t, TLSv1_1, TLSv1_0)
|
||||
|
||||
require.Less(t, TLSv1_2, TLSv1_3)
|
||||
require.Less(t, TLSv1_1, TLSv1_2)
|
||||
require.Less(t, TLSv1_0, TLSv1_1)
|
||||
func TestTLSVersion_Valid(t *testing.T) {
|
||||
require.NoError(t, ValidateTLSVersion("TLS_AUTO"))
|
||||
require.NoError(t, ValidateTLSVersion("TLSv1_0"))
|
||||
require.NoError(t, ValidateTLSVersion("TLSv1_1"))
|
||||
require.NoError(t, ValidateTLSVersion("TLSv1_2"))
|
||||
require.NoError(t, ValidateTLSVersion("TLSv1_3"))
|
||||
}
|
||||
|
||||
func TestTLSVersion_Invalid(t *testing.T) {
|
||||
|
@ -33,16 +31,19 @@ func TestTLSVersion_Zero(t *testing.T) {
|
|||
|
||||
func TestTLSVersion_ToJSON(t *testing.T) {
|
||||
var tlsVersion TLSVersion
|
||||
err := tlsVersion.UnmarshalJSON([]byte(`"foo"`))
|
||||
require.Error(t, err)
|
||||
require.Equal(t, tlsVersion, TLSVersionInvalid)
|
||||
|
||||
for str, version := range TLSVersions {
|
||||
// Unmarshalling won't catch invalid version strings,
|
||||
// must be checked in config or config entry validation
|
||||
err := json.Unmarshal([]byte(`"foo"`), &tlsVersion)
|
||||
require.NoError(t, err)
|
||||
|
||||
for version := range tlsVersions {
|
||||
str := version.String()
|
||||
versionJSON, err := json.Marshal(version)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, versionJSON, []byte(`"`+str+`"`))
|
||||
|
||||
err = tlsVersion.UnmarshalJSON([]byte(`"` + str + `"`))
|
||||
err = json.Unmarshal([]byte(`"`+str+`"`), &tlsVersion)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tlsVersion, version)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue