Use the GatewayService SNI field for upstream SAN validation
This commit is contained in:
parent
cc3c39b920
commit
116b6c57cb
|
@ -526,6 +526,30 @@ func testConfigSnapshotTerminatingGatewayLBConfig(t testing.T, variant string) *
|
|||
})
|
||||
}
|
||||
|
||||
func TestConfigSnapshotTerminatingGatewaySNI(t testing.T) *ConfigSnapshot {
|
||||
return TestConfigSnapshotTerminatingGateway(t, true, nil, []cache.UpdateEvent{
|
||||
{
|
||||
CorrelationID: "gateway-services",
|
||||
Result: &structs.IndexedGatewayServices{
|
||||
Services: []*structs.GatewayService{
|
||||
{
|
||||
Service: structs.NewServiceName("web", nil),
|
||||
CAFile: "ca.cert.pem",
|
||||
SNI: "foo.com",
|
||||
},
|
||||
{
|
||||
Service: structs.NewServiceName("api", nil),
|
||||
CAFile: "ca.cert.pem",
|
||||
CertFile: "api.cert.pem",
|
||||
KeyFile: "api.key.pem",
|
||||
SNI: "bar.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestConfigSnapshotTerminatingGatewayHostnameSubsets(t testing.T) *ConfigSnapshot {
|
||||
var (
|
||||
api = structs.NewServiceName("api", nil)
|
||||
|
|
|
@ -390,6 +390,9 @@ func (s *ResourceGenerator) injectGatewayServiceAddons(cfgSnap *proxycfg.ConfigS
|
|||
}
|
||||
if mapping.SNI != "" {
|
||||
tlsContext.Sni = mapping.SNI
|
||||
if err := injectRawSANMatcher(tlsContext.CommonTlsContext, []string{mapping.SNI}); err != nil {
|
||||
return fmt.Errorf("failed to inject SNI matcher into TLS context: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
transportSocket, err := makeUpstreamTLSTransportSocket(tlsContext)
|
||||
|
@ -803,6 +806,15 @@ func (s *ResourceGenerator) makeUpstreamClustersForDiscoveryChain(
|
|||
|
||||
// injectSANMatcher updates a TLS context so that it verifies the upstream SAN.
|
||||
func injectSANMatcher(tlsContext *envoy_tls_v3.CommonTlsContext, spiffeIDs ...connect.SpiffeIDService) error {
|
||||
var matchStrings []string
|
||||
for _, id := range spiffeIDs {
|
||||
matchStrings = append(matchStrings, id.URI().String())
|
||||
}
|
||||
|
||||
return injectRawSANMatcher(tlsContext, matchStrings)
|
||||
}
|
||||
|
||||
func injectRawSANMatcher(tlsContext *envoy_tls_v3.CommonTlsContext, matchStrings []string) error {
|
||||
validationCtx, ok := tlsContext.ValidationContextType.(*envoy_tls_v3.CommonTlsContext_ValidationContext)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type: expected CommonTlsContext_ValidationContext, got %T",
|
||||
|
@ -810,10 +822,10 @@ func injectSANMatcher(tlsContext *envoy_tls_v3.CommonTlsContext, spiffeIDs ...co
|
|||
}
|
||||
|
||||
var matchers []*envoy_matcher_v3.StringMatcher
|
||||
for _, id := range spiffeIDs {
|
||||
for _, m := range matchStrings {
|
||||
matchers = append(matchers, &envoy_matcher_v3.StringMatcher{
|
||||
MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{
|
||||
Exact: id.URI().String(),
|
||||
Exact: m,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -581,6 +581,10 @@ func TestClustersFromSnapshot(t *testing.T) {
|
|||
name: "terminating-gateway-hostname-service-subsets",
|
||||
create: proxycfg.TestConfigSnapshotTerminatingGatewayHostnameSubsets,
|
||||
},
|
||||
{
|
||||
name: "terminating-gateway-sni",
|
||||
create: proxycfg.TestConfigSnapshotTerminatingGatewaySNI,
|
||||
},
|
||||
{
|
||||
name: "terminating-gateway-ignore-extra-resolvers",
|
||||
create: proxycfg.TestConfigSnapshotTerminatingGatewayIgnoreExtraResolvers,
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
{
|
||||
"versionInfo": "00000001",
|
||||
"resources": [
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
"name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||
"type": "LOGICAL_DNS",
|
||||
"connectTimeout": "5s",
|
||||
"loadAssignment": {
|
||||
"clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||
"endpoints": [
|
||||
{
|
||||
"lbEndpoints": [
|
||||
{
|
||||
"endpoint": {
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "api.altdomain",
|
||||
"portValue": 8081
|
||||
}
|
||||
}
|
||||
},
|
||||
"healthStatus": "HEALTHY",
|
||||
"loadBalancingWeight": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"dnsRefreshRate": "10s",
|
||||
"dnsLookupFamily": "V4_ONLY",
|
||||
"outlierDetection": {
|
||||
|
||||
},
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
|
||||
},
|
||||
"tlsCertificates": [
|
||||
{
|
||||
"certificateChain": {
|
||||
"filename": "api.cert.pem"
|
||||
},
|
||||
"privateKey": {
|
||||
"filename": "api.key.pem"
|
||||
}
|
||||
}
|
||||
],
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"filename": "ca.cert.pem"
|
||||
},
|
||||
"matchSubjectAltNames": [
|
||||
{
|
||||
"exact": "bar.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"sni": "bar.com"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
"name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||
"type": "LOGICAL_DNS",
|
||||
"connectTimeout": "5s",
|
||||
"loadAssignment": {
|
||||
"clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||
"endpoints": [
|
||||
{
|
||||
"lbEndpoints": [
|
||||
{
|
||||
"endpoint": {
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "cache.mydomain",
|
||||
"portValue": 8081
|
||||
}
|
||||
}
|
||||
},
|
||||
"healthStatus": "HEALTHY",
|
||||
"loadBalancingWeight": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"dnsRefreshRate": "10s",
|
||||
"dnsLookupFamily": "V4_ONLY",
|
||||
"outlierDetection": {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
"name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||
"type": "LOGICAL_DNS",
|
||||
"connectTimeout": "5s",
|
||||
"loadAssignment": {
|
||||
"clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||
"endpoints": [
|
||||
{
|
||||
"lbEndpoints": [
|
||||
{
|
||||
"endpoint": {
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "db.mydomain",
|
||||
"portValue": 8081
|
||||
}
|
||||
}
|
||||
},
|
||||
"healthStatus": "UNHEALTHY",
|
||||
"loadBalancingWeight": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"dnsRefreshRate": "10s",
|
||||
"dnsLookupFamily": "V4_ONLY",
|
||||
"outlierDetection": {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
"name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||
"type": "EDS",
|
||||
"edsClusterConfig": {
|
||||
"edsConfig": {
|
||||
"ads": {
|
||||
|
||||
},
|
||||
"resourceApiVersion": "V3"
|
||||
}
|
||||
},
|
||||
"connectTimeout": "5s",
|
||||
"outlierDetection": {
|
||||
|
||||
},
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"tlsParams": {
|
||||
|
||||
},
|
||||
"validationContext": {
|
||||
"trustedCa": {
|
||||
"filename": "ca.cert.pem"
|
||||
},
|
||||
"matchSubjectAltNames": [
|
||||
{
|
||||
"exact": "foo.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"sni": "foo.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||
"nonce": "00000001"
|
||||
}
|
|
@ -166,6 +166,7 @@ Services = [
|
|||
{
|
||||
Name = "billing"
|
||||
CAFile = "/etc/certs/ca-chain.cert.pem"
|
||||
SNI = "billing.service.com"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -179,6 +180,7 @@ spec:
|
|||
services:
|
||||
- name: billing
|
||||
caFile: /etc/certs/ca-chain.cert.pem
|
||||
sni: billing.service.com
|
||||
```
|
||||
|
||||
```json
|
||||
|
@ -189,6 +191,7 @@ spec:
|
|||
{
|
||||
"Name": "billing",
|
||||
"CAFile": "/etc/certs/ca-chain.cert.pem"
|
||||
"SNI": "billing.service.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -217,6 +220,7 @@ Services = [
|
|||
Namespace = "finance"
|
||||
Name = "billing"
|
||||
CAFile = "/etc/certs/ca-chain.cert.pem"
|
||||
SNI = "billing.service.com"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -231,6 +235,7 @@ spec:
|
|||
- name: billing
|
||||
namespace: finance
|
||||
caFile: /etc/certs/ca-chain.cert.pem
|
||||
sni: billing.service.com
|
||||
```
|
||||
|
||||
```json
|
||||
|
@ -242,7 +247,8 @@ spec:
|
|||
{
|
||||
"Namespace": "finance",
|
||||
"Name": "billing",
|
||||
"CAFile": "/etc/certs/ca-chain.cert.pem"
|
||||
"CAFile": "/etc/certs/ca-chain.cert.pem",
|
||||
"SNI": "billing.service.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -276,6 +282,7 @@ Services = [
|
|||
CAFile = "/etc/certs/ca-chain.cert.pem"
|
||||
KeyFile = "/etc/certs/gateway.key.pem"
|
||||
CertFile = "/etc/certs/gateway.cert.pem"
|
||||
SNI = "billing.service.com"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -291,6 +298,7 @@ spec:
|
|||
caFile: /etc/certs/ca-chain.cert.pem
|
||||
keyFile: /etc/certs/gateway.key.pem
|
||||
certFile: /etc/certs/gateway.cert.pem
|
||||
sni: billing.service.com
|
||||
```
|
||||
|
||||
```json
|
||||
|
@ -302,7 +310,8 @@ spec:
|
|||
"Name": "billing",
|
||||
"CAFile": "/etc/certs/ca-chain.cert.pem",
|
||||
"KeyFile": "/etc/certs/gateway.key.pem",
|
||||
"CertFile": "/etc/certs/gateway.cert.pem"
|
||||
"CertFile": "/etc/certs/gateway.cert.pem",
|
||||
"SNI": "billing.service.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -333,6 +342,7 @@ Services = [
|
|||
CAFile = "/etc/certs/ca-chain.cert.pem"
|
||||
KeyFile = "/etc/certs/gateway.key.pem"
|
||||
CertFile = "/etc/certs/gateway.cert.pem"
|
||||
SNI = "billing.service.com"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -349,6 +359,7 @@ spec:
|
|||
caFile: /etc/certs/ca-chain.cert.pem
|
||||
keyFile: /etc/certs/gateway.key.pem
|
||||
certFile: /etc/certs/gateway.cert.pem
|
||||
sni: billing.service.com
|
||||
```
|
||||
|
||||
```json
|
||||
|
@ -362,7 +373,8 @@ spec:
|
|||
"Name": "billing",
|
||||
"CAFile": "/etc/certs/ca-chain.cert.pem",
|
||||
"KeyFile": "/etc/certs/gateway.key.pem",
|
||||
"CertFile": "/etc/certs/gateway.cert.pem"
|
||||
"CertFile": "/etc/certs/gateway.cert.pem",
|
||||
"SNI": "billing.service.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -399,7 +411,7 @@ Services = [
|
|||
},
|
||||
{
|
||||
Name = "billing"
|
||||
CAFile = "/etc/billing-ca/ca-chain.cert.pem",
|
||||
CAFile = "/etc/billing-ca/ca-chain.cert.pem"
|
||||
SNI = "billing.service.com"
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue