diff --git a/api/v1alpha1/backend_types.go b/api/v1alpha1/backend_types.go
index 6bba7515960..a86158ae8cd 100644
--- a/api/v1alpha1/backend_types.go
+++ b/api/v1alpha1/backend_types.go
@@ -204,6 +204,18 @@ type BackendTLSSettings struct {
// +kubebuilder:default=false
// +optional
InsecureSkipVerify *bool `json:"insecureSkipVerify,omitempty"`
+
+ // SNI is specifies the SNI value used when establishing an upstream TLS connection to the backend.
+ //
+ // Envoy Gateway will use the HTTP host header value for SNI, when all resources referenced in BackendRefs are:
+ // 1. Backend resources that do not set SNI, or
+ // 2. Service/ServiceImport resources that do not have a BackendTLSPolicy attached to them
+ //
+ // When a BackendTLSPolicy attaches to a Backend resource, the BackendTLSPolicy's Hostname value takes precedence
+ // over this value.
+ //
+ // +optional
+ SNI *gwapiv1.PreciseHostname `json:"sni,omitempty"`
}
// BackendType defines the type of the Backend.
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index f3040d553d7..6a6b11e3ce0 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -579,6 +579,11 @@ func (in *BackendTLSSettings) DeepCopyInto(out *BackendTLSSettings) {
*out = new(bool)
**out = **in
}
+ if in.SNI != nil {
+ in, out := &in.SNI, &out.SNI
+ *out = new(v1.PreciseHostname)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTLSSettings.
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backends.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backends.yaml
index ebe795978ca..f23e05e45e1 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backends.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backends.yaml
@@ -223,6 +223,20 @@ spec:
InsecureSkipVerify indicates whether the upstream's certificate verification
should be skipped. Defaults to "false".
type: boolean
+ sni:
+ description: |-
+ SNI is specifies the SNI value used when establishing an upstream TLS connection to the backend.
+
+ Envoy Gateway will use the HTTP host header value for SNI, when all resources referenced in BackendRefs are:
+ 1. Backend resources that do not set SNI, or
+ 2. Service/ServiceImport resources that do not have a BackendTLSPolicy attached to them
+
+ When a BackendTLSPolicy attaches to a Backend resource, the BackendTLSPolicy's Hostname value takes precedence
+ over this value.
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
wellKnownCACertificates:
description: |-
WellKnownCACertificates specifies whether system CA certificates may be used in
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
index 3f16dee1ef5..5d5dd476d61 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backends.yaml
@@ -222,6 +222,20 @@ spec:
InsecureSkipVerify indicates whether the upstream's certificate verification
should be skipped. Defaults to "false".
type: boolean
+ sni:
+ description: |-
+ SNI is specifies the SNI value used when establishing an upstream TLS connection to the backend.
+
+ Envoy Gateway will use the HTTP host header value for SNI, when all resources referenced in BackendRefs are:
+ 1. Backend resources that do not set SNI, or
+ 2. Service/ServiceImport resources that do not have a BackendTLSPolicy attached to them
+
+ When a BackendTLSPolicy attaches to a Backend resource, the BackendTLSPolicy's Hostname value takes precedence
+ over this value.
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
wellKnownCACertificates:
description: |-
WellKnownCACertificates specifies whether system CA certificates may be used in
diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go
index 45fc1883943..43cce65abc5 100644
--- a/internal/gatewayapi/backendtlspolicy.go
+++ b/internal/gatewayapi/backendtlspolicy.go
@@ -76,6 +76,8 @@ func (t *Translator) applyBackendTLSSetting(
return t.applyEnvoyProxyBackendTLSSetting(upstreamConfig, resources, envoyProxy)
}
+// Merges TLS settings from Gateway API BackendTLSPolicy and Envoy Gateway Backend TL.
+// BackendTLSPolicy takes precedence for identical attributes that are set in both.
func mergeBackendTLSConfigs(
backendTLSSettingsConfig *ir.TLSUpstreamConfig,
backendTLSPolicyConfig *ir.TLSUpstreamConfig,
@@ -91,8 +93,8 @@ func mergeBackendTLSConfigs(
return backendTLSSettingsConfig
}
- // If both are set, we merge them, with BackendTLSPolicy settings taking precedence
mergedConfig := backendTLSSettingsConfig.DeepCopy()
+
if backendTLSPolicyConfig.CACertificate != nil {
mergedConfig.CACertificate = backendTLSPolicyConfig.CACertificate
}
@@ -117,6 +119,10 @@ func (t *Translator) processBackendTLSSettings(
InsecureSkipVerify: ptr.Deref(backend.Spec.TLS.InsecureSkipVerify, false),
}
+ if backend.Spec.TLS.SNI != nil {
+ tlsConfig.SNI = ptr.To(string(*backend.Spec.TLS.SNI))
+ }
+
if !tlsConfig.InsecureSkipVerify {
tlsConfig.UseSystemTrustStore = ptr.Deref(backend.Spec.TLS.WellKnownCACertificates, "") == gwapiv1a3.WellKnownCACertificatesSystem
diff --git a/internal/gatewayapi/ext_service.go b/internal/gatewayapi/ext_service.go
index 82e6f7369c7..b65401ac841 100644
--- a/internal/gatewayapi/ext_service.go
+++ b/internal/gatewayapi/ext_service.go
@@ -83,6 +83,7 @@ func (t *Translator) translateExtServiceBackendRefs(
if rs.HasMixedEndpoints() {
return nil, errors.New("external service destinations having multiple endpoint types are not supported")
}
+
return rs, nil
}
diff --git a/internal/gatewayapi/testdata/backend-with-auto-san-sni.in.yaml b/internal/gatewayapi/testdata/backend-with-auto-san-sni.in.yaml
new file mode 100644
index 00000000000..ec6d2532a47
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-with-auto-san-sni.in.yaml
@@ -0,0 +1,225 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-btls
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-without-sni
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-btls
+ sectionName: http
+ hostnames:
+ - backend-without-sni.example.com
+ rules:
+ - matches:
+ - path:
+ type: Exact
+ value: "/backend-without-sni"
+ backendRefs:
+ - kind: Backend
+ group: gateway.envoyproxy.io
+ name: backend-without-sni
+ namespace: backends
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-with-sni
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-btls
+ sectionName: http
+ hostnames:
+ - backend-with-sni.example.com
+ rules:
+ - matches:
+ - path:
+ type: Exact
+ value: "/backend-with-sni"
+ backendRefs:
+ - kind: Backend
+ group: gateway.envoyproxy.io
+ name: backend-with-sni
+ namespace: backends
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-with-sni-and-btlsp
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-btls
+ sectionName: http
+ hostnames:
+ - backend-with-sni-and-btlsp.example.com
+ rules:
+ - matches:
+ - path:
+ type: Exact
+ value: "/backend-with-sni-and-btlsp"
+ backendRefs:
+ - kind: Backend
+ group: gateway.envoyproxy.io
+ name: backend-with-sni-and-btlsp
+ namespace: backends
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-without-sni-and-btlsp
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-btls
+ sectionName: http
+ hostnames:
+ - "backend-without-sni-and-btlsp.example.com"
+ rules:
+ - matches:
+ - path:
+ type: Exact
+ value: "/backend-without-sni-and-btlsp"
+ backendRefs:
+ - kind: Backend
+ group: gateway.envoyproxy.io
+ name: backend-without-sni-and-btlsp
+ namespace: backends
+ port: 8080
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ name: refg-route-svc
+ namespace: backends
+ spec:
+ from:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ namespace: envoy-gateway
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ namespace: envoy-gateway
+ - group: gateway.networking.k8s.io
+ kind: BackendTLSPolicy
+ namespace: policies
+ to:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-without-sni
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - name: ca-secret
+ group: ""
+ kind: Secret
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-with-sni
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - name: ca-secret
+ group: ""
+ kind: Secret
+ sni: "backend.sni.com"
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-without-sni-and-btlsp
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - name: ca-secret
+ group: ""
+ kind: Secret
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-with-sni-and-btlsp
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - name: ca-secret
+ group: ""
+ kind: Secret
+ sni: "backend.sni.com"
+secrets:
+ - apiVersion: v1
+ kind: Secret
+ metadata:
+ name: ca-secret
+ namespace: backends
+ data:
+ ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+
+backendTLSPolicies:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls
+ namespace: backends
+ spec:
+ targetRefs:
+ - kind: Backend
+ group: gateway.envoyproxy.io
+ name: backend-without-sni-and-btlsp
+ - kind: Backend
+ group: gateway.envoyproxy.io
+ name: backend-with-sni-and-btlsp
+ validation:
+ caCertificateRefs:
+ - name: ca-secret
+ group: ""
+ kind: Secret
+ hostname: example.com
+ subjectAltNames:
+ - type: URI
+ uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ - hostname: subdomain.secondexample.com
diff --git a/internal/gatewayapi/testdata/backend-with-auto-san-sni.out.yaml b/internal/gatewayapi/testdata/backend-with-auto-san-sni.out.yaml
new file mode 100644
index 00000000000..f44f583f858
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-with-auto-san-sni.out.yaml
@@ -0,0 +1,543 @@
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls
+ namespace: backends
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-without-sni-and-btlsp
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-with-sni-and-btlsp
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: Secret
+ name: ca-secret
+ hostname: example.com
+ subjectAltNames:
+ - type: URI
+ uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ - hostname: subdomain.secondexample.com
+ type: ""
+ status:
+ ancestors:
+ - ancestorRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-without-sni
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - group: ""
+ kind: Secret
+ name: ca-secret
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-with-sni
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - group: ""
+ kind: Secret
+ name: ca-secret
+ sni: backend.sni.com
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-without-sni-and-btlsp
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - group: ""
+ kind: Secret
+ name: ca-secret
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-with-sni-and-btlsp
+ namespace: backends
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - group: ""
+ kind: Secret
+ name: ca-secret
+ sni: backend.sni.com
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-btls
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 4
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-without-sni
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - backend-without-sni.example.com
+ parentRefs:
+ - name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-without-sni
+ namespace: backends
+ port: 8080
+ matches:
+ - path:
+ type: Exact
+ value: /backend-without-sni
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-with-sni
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - backend-with-sni.example.com
+ parentRefs:
+ - name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-with-sni
+ namespace: backends
+ port: 8080
+ matches:
+ - path:
+ type: Exact
+ value: /backend-with-sni
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-with-sni-and-btlsp
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - backend-with-sni-and-btlsp.example.com
+ parentRefs:
+ - name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-with-sni-and-btlsp
+ namespace: backends
+ port: 8080
+ matches:
+ - path:
+ type: Exact
+ value: /backend-with-sni-and-btlsp
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-backend-without-sni-and-btlsp
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - backend-without-sni-and-btlsp.example.com
+ parentRefs:
+ - name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-without-sni-and-btlsp
+ namespace: backends
+ port: 8080
+ matches:
+ - path:
+ type: Exact
+ value: /backend-without-sni-and-btlsp
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-btls:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-btls/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-btls
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-btls
+ namespace: envoy-gateway-system
+xdsIR:
+ envoy-gateway/gateway-btls:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ metadata:
+ name: envoy-envoy-gateway-gateway-btls-a945b5bb
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-btls
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-btls-a945b5bb
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-btls
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 80
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-btls
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-btls/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-without-sni-and-btlsp
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-without-sni-and-btlsp/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ metadata:
+ kind: Backend
+ name: backend-without-sni-and-btlsp
+ namespace: backends
+ name: httproute/envoy-gateway/httproute-backend-without-sni-and-btlsp/rule/0/backend/0
+ protocol: HTTP
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/backends-ca
+ sni: example.com
+ subjectAltNames:
+ - uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ weight: 1
+ hostname: backend-without-sni-and-btlsp.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-without-sni-and-btlsp
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-without-sni-and-btlsp/rule/0/match/0/backend-without-sni-and-btlsp_example_com
+ pathMatch:
+ distinct: false
+ exact: /backend-without-sni-and-btlsp
+ name: ""
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-with-sni-and-btlsp
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-with-sni-and-btlsp/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ metadata:
+ kind: Backend
+ name: backend-with-sni-and-btlsp
+ namespace: backends
+ name: httproute/envoy-gateway/httproute-backend-with-sni-and-btlsp/rule/0/backend/0
+ protocol: HTTP
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/backends-ca
+ sni: example.com
+ subjectAltNames:
+ - uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ weight: 1
+ hostname: backend-with-sni-and-btlsp.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-with-sni-and-btlsp
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-with-sni-and-btlsp/rule/0/match/0/backend-with-sni-and-btlsp_example_com
+ pathMatch:
+ distinct: false
+ exact: /backend-with-sni-and-btlsp
+ name: ""
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-without-sni
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-without-sni/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ metadata:
+ kind: Backend
+ name: backend-without-sni
+ namespace: backends
+ name: httproute/envoy-gateway/httproute-backend-without-sni/rule/0/backend/0
+ protocol: HTTP
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: backend-without-sni/backends-ca
+ weight: 1
+ hostname: backend-without-sni.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-without-sni
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-without-sni/rule/0/match/0/backend-without-sni_example_com
+ pathMatch:
+ distinct: false
+ exact: /backend-without-sni
+ name: ""
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-with-sni
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-with-sni/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ metadata:
+ kind: Backend
+ name: backend-with-sni
+ namespace: backends
+ name: httproute/envoy-gateway/httproute-backend-with-sni/rule/0/backend/0
+ protocol: HTTP
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: backend-with-sni/backends-ca
+ sni: backend.sni.com
+ weight: 1
+ hostname: backend-with-sni.example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-backend-with-sni
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-backend-with-sni/rule/0/match/0/backend-with-sni_example_com
+ pathMatch:
+ distinct: false
+ exact: /backend-with-sni
+ name: ""
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go
index 48d4c4d86c3..151e3942189 100644
--- a/internal/xds/translator/cluster.go
+++ b/internal/xds/translator/cluster.go
@@ -209,11 +209,34 @@ func buildXdsCluster(args *xdsClusterArgs) (*buildClusterResult, error) {
cluster.TransportSocket = args.tSocket
}
+ // scan through settings to determine cluster-level configuration options, as some of them
+ // influence transport socket specific settings
requiresAutoHTTPConfig := false
- for i, ds := range args.settings {
+ requiresHTTP2Options := false
+ hasLiteralSNI := false
+ for _, ds := range args.settings {
+ if ds.Protocol == ir.GRPC ||
+ ds.Protocol == ir.HTTP2 {
+ requiresHTTP2Options = true
+ }
+
if ds.TLS != nil {
requiresAutoHTTPConfig = true
- socket, err := buildXdsUpstreamTLSSocketWthCert(ds.TLS)
+
+ // it's safe to set autoSNI on cluster level only if all endpoints do not set literal SNIs.
+ // Otherwise, autoSNI will override transport-socket level SNI.
+ // See here: https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/securing#connect-to-an-endpoint-with-sni
+ if ds.TLS.SNI != nil {
+ hasLiteralSNI = true
+ }
+ }
+ }
+ // only enable auto sni if TLS is configured
+ requiresAutoSNI := !hasLiteralSNI && requiresAutoHTTPConfig
+
+ for i, ds := range args.settings {
+ if ds.TLS != nil {
+ socket, err := buildXdsUpstreamTLSSocketWthCert(ds.TLS, requiresAutoSNI, args.endpointType)
if err != nil {
// TODO: Log something here
return nil, err
@@ -247,7 +270,7 @@ func buildXdsCluster(args *xdsClusterArgs) (*buildClusterResult, error) {
}
// build common, HTTP/1 and HTTP/2 protocol options for cluster
- epo, secrets, err := buildTypedExtensionProtocolOptions(args, requiresAutoHTTPConfig)
+ epo, secrets, err := buildTypedExtensionProtocolOptions(args, requiresAutoHTTPConfig, requiresHTTP2Options, requiresAutoSNI)
if err != nil {
return nil, err
}
@@ -810,16 +833,7 @@ func buildWeightedLocalities(metadata *corev3.Metadata, ds *ir.DestinationSettin
return locality
}
-func buildTypedExtensionProtocolOptions(args *xdsClusterArgs, requiresAutoHTTPConfig bool) (map[string]*anypb.Any, []*tlsv3.Secret, error) {
- requiresHTTP2Options := false
- for _, ds := range args.settings {
- if ds.Protocol == ir.GRPC ||
- ds.Protocol == ir.HTTP2 {
- requiresHTTP2Options = true
- break
- }
- }
-
+func buildTypedExtensionProtocolOptions(args *xdsClusterArgs, requiresAutoHTTPConfig, requiresHTTP2Options, requiresAutoSNI bool) (map[string]*anypb.Any, []*tlsv3.Secret, error) {
requiresCommonHTTPOptions := (args.timeout != nil && args.timeout.HTTP != nil &&
(args.timeout.HTTP.MaxConnectionDuration != nil || args.timeout.HTTP.ConnectionIdleTimeout != nil)) ||
(args.circuitBreaker != nil && args.circuitBreaker.MaxRequestsPerConnection != nil)
@@ -828,8 +842,10 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs, requiresAutoHTTPCo
(args.http1Settings.EnableTrailers || args.http1Settings.PreserveHeaderCase || args.http1Settings.HTTP10 != nil)
requiresHTTPFilters := len(args.settings) > 0 && args.settings[0].Filters != nil && args.settings[0].Filters.CredentialInjection != nil
+
requiredHTTPProtocolOptions := args.useClientProtocol || requiresAutoHTTPConfig ||
- requiresCommonHTTPOptions || requiresHTTP1Options || requiresHTTP2Options || requiresHTTPFilters
+ requiresCommonHTTPOptions || requiresHTTP1Options || requiresHTTP2Options || requiresHTTPFilters || requiresAutoSNI
+
if !requiredHTTPProtocolOptions {
return nil, nil, nil
}
@@ -903,6 +919,10 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs, requiresAutoHTTPCo
AutoSni: true,
AutoSanValidation: true,
}
+ } else if requiresAutoSNI {
+ protocolOptions.UpstreamHttpProtocolOptions = &corev3.UpstreamHttpProtocolOptions{
+ AutoSni: true,
+ }
}
var (
diff --git a/internal/xds/translator/testdata/in/xds-ir/backend-with-auto-san-sni.yaml b/internal/xds/translator/testdata/in/xds-ir/backend-with-auto-san-sni.yaml
new file mode 100644
index 00000000000..e84a26d6c0a
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/backend-with-auto-san-sni.yaml
@@ -0,0 +1,64 @@
+http:
+ - name: "first-listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "auto-sni-route"
+ hostname: "*"
+ destination:
+ name: "auto-sni-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ name: "auto-sni-route-dest/backend/0"
+ tls:
+ alpnProtocols: null
+ subjectAltNames:
+ - uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/backends-ca
+ - name: "auto-sni-san-route"
+ hostname: "*"
+ destination:
+ name: "auto-sni-san-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ name: "auto-sni-san-route-dest/backend/0"
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/backends-ca
+ - name: "mixed-sni-route"
+ hostname: "*"
+ destination:
+ name: "mixed-sni-route"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ name: "mixed-sni-route/backend/1"
+ tls:
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/backends-ca
+ - endpoints:
+ - host: "5.6.7.8"
+ port: 40000
+ name: "mixed-sni-route/backend/2"
+ tls:
+ sni: "should.not.use.auto"
+ alpnProtocols: null
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls/backends-ca
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-tls-settings.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-tls-settings.clusters.yaml
index 0150a1dd643..a50137304e8 100644
--- a/internal/xds/translator/testdata/out/xds-ir/backend-tls-settings.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-tls-settings.clusters.yaml
@@ -127,6 +127,7 @@
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ autoSniSanValidation: true
commonTlsContext:
combinedValidationContext:
defaultValidationContext: {}
@@ -159,6 +160,8 @@
initialConnectionWindowSize: 1048576
initialStreamWindowSize: 65536
httpProtocolOptions: {}
+ upstreamHttpProtocolOptions:
+ autoSni: true
- circuitBreakers:
thresholds:
- maxRetries: 1024
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml
index 83c4f108c23..0a59ee68a7b 100644
--- a/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml
@@ -44,3 +44,5 @@
initialConnectionWindowSize: 1048576
initialStreamWindowSize: 65536
httpProtocolOptions: {}
+ upstreamHttpProtocolOptions:
+ autoSni: true
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.clusters.yaml
new file mode 100644
index 00000000000..bea193897bd
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.clusters.yaml
@@ -0,0 +1,188 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: auto-sni-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ loadBalancingPolicy:
+ policies:
+ - typedExtensionConfig:
+ name: envoy.load_balancing_policies.least_request
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+ localityLbConfig:
+ localityWeightedLbConfig: {}
+ name: auto-sni-route-dest
+ perConnectionBufferLimitBytes: 32768
+ transportSocket:
+ name: dummy.transport_socket
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext: {}
+ transportSocketMatches:
+ - match:
+ name: auto-sni-route-dest/tls/0
+ name: auto-sni-route-dest/tls/0
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ sanType: URI
+ validationContextSdsSecretConfig:
+ name: policy-btls/backends-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ autoConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ httpProtocolOptions: {}
+ upstreamHttpProtocolOptions:
+ autoSni: true
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: auto-sni-san-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ loadBalancingPolicy:
+ policies:
+ - typedExtensionConfig:
+ name: envoy.load_balancing_policies.least_request
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+ localityLbConfig:
+ localityWeightedLbConfig: {}
+ name: auto-sni-san-route-dest
+ perConnectionBufferLimitBytes: 32768
+ transportSocket:
+ name: dummy.transport_socket
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext: {}
+ transportSocketMatches:
+ - match:
+ name: auto-sni-san-route-dest/tls/0
+ name: auto-sni-san-route-dest/tls/0
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ autoSniSanValidation: true
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext: {}
+ validationContextSdsSecretConfig:
+ name: policy-btls/backends-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ autoConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ httpProtocolOptions: {}
+ upstreamHttpProtocolOptions:
+ autoSni: true
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: mixed-sni-route
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ loadBalancingPolicy:
+ policies:
+ - typedExtensionConfig:
+ name: envoy.load_balancing_policies.least_request
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+ localityLbConfig:
+ localityWeightedLbConfig: {}
+ name: mixed-sni-route
+ perConnectionBufferLimitBytes: 32768
+ transportSocket:
+ name: dummy.transport_socket
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext: {}
+ transportSocketMatches:
+ - match:
+ name: mixed-sni-route/tls/0
+ name: mixed-sni-route/tls/0
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext: {}
+ validationContextSdsSecretConfig:
+ name: policy-btls/backends-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ - match:
+ name: mixed-sni-route/tls/1
+ name: mixed-sni-route/tls/1
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: should.not.use.auto
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls/backends-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: should.not.use.auto
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ autoConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ httpProtocolOptions: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.endpoints.yaml
new file mode 100644
index 00000000000..be31a643aa9
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.endpoints.yaml
@@ -0,0 +1,62 @@
+- clusterName: auto-sni-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: auto-sni-route-dest/tls/0
+ loadBalancingWeight: 1
+ locality:
+ region: auto-sni-route-dest/backend/0
+- clusterName: auto-sni-san-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: auto-sni-san-route-dest/tls/0
+ loadBalancingWeight: 1
+ locality:
+ region: auto-sni-san-route-dest/backend/0
+- clusterName: mixed-sni-route
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: mixed-sni-route/tls/0
+ loadBalancingWeight: 1
+ locality:
+ region: mixed-sni-route/backend/1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 5.6.7.8
+ portValue: 40000
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: mixed-sni-route/tls/1
+ loadBalancingWeight: 1
+ locality:
+ region: mixed-sni-route/backend/2
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.listeners.yaml
new file mode 100644
index 00000000000..5dd5e46e3cf
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.listeners.yaml
@@ -0,0 +1,35 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ maxConnectionsToAcceptPerSocketEvent: 1
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.routes.yaml
new file mode 100644
index 00000000000..b5ffd68a1ed
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.routes.yaml
@@ -0,0 +1,28 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: auto-sni-route
+ route:
+ cluster: auto-sni-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ prefix: /
+ name: auto-sni-san-route
+ route:
+ cluster: auto-sni-san-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ prefix: /
+ name: mixed-sni-route
+ route:
+ cluster: mixed-sni-route
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.secrets.yaml
new file mode 100644
index 00000000000..44a087ed6ed
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-with-auto-san-sni.secrets.yaml
@@ -0,0 +1,16 @@
+- name: policy-btls/backends-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+- name: policy-btls/backends-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+- name: policy-btls/backends-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+- name: policy-btls/backends-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go
index bb7b7ced752..a9206fce561 100644
--- a/internal/xds/translator/translator.go
+++ b/internal/xds/translator/translator.go
@@ -1167,7 +1167,7 @@ func buildXdsUpstreamTLSCASecret(tlsConfig *ir.TLSUpstreamConfig) *tlsv3.Secret
}
}
-func buildValidationContext(tlsConfig *ir.TLSUpstreamConfig) *tlsv3.CommonTlsContext_CombinedValidationContext {
+func buildValidationContext(tlsConfig *ir.TLSUpstreamConfig) (*tlsv3.CommonTlsContext_CombinedValidationContext, bool) {
validationContext := &tlsv3.CommonTlsContext_CombinedCertificateValidationContext{
ValidationContextSdsSecretConfig: &tlsv3.SdsSecretConfig{
Name: tlsConfig.CACertificate.Name,
@@ -1175,6 +1175,7 @@ func buildValidationContext(tlsConfig *ir.TLSUpstreamConfig) *tlsv3.CommonTlsCon
},
DefaultValidationContext: &tlsv3.CertificateValidationContext{},
}
+ hasSANValidations := false
if tlsConfig.SNI != nil {
validationContext.DefaultValidationContext.MatchTypedSubjectAltNames = []*tlsv3.SubjectAltNameMatcher{
@@ -1187,38 +1188,40 @@ func buildValidationContext(tlsConfig *ir.TLSUpstreamConfig) *tlsv3.CommonTlsCon
},
},
}
- for _, san := range tlsConfig.SubjectAltNames {
- var sanType tlsv3.SubjectAltNameMatcher_SanType
- var value string
-
- // Exactly one of san.Hostname or san.URI is guaranteed to be set
- if san.Hostname != nil {
- sanType = tlsv3.SubjectAltNameMatcher_DNS
- value = *san.Hostname
- } else if san.URI != nil {
- sanType = tlsv3.SubjectAltNameMatcher_URI
- value = *san.URI
- }
- validationContext.DefaultValidationContext.MatchTypedSubjectAltNames = append(
- validationContext.DefaultValidationContext.MatchTypedSubjectAltNames,
- &tlsv3.SubjectAltNameMatcher{
- SanType: sanType,
- Matcher: &matcherv3.StringMatcher{
- MatchPattern: &matcherv3.StringMatcher_Exact{
- Exact: value,
- },
+ hasSANValidations = true
+ }
+ for _, san := range tlsConfig.SubjectAltNames {
+ var sanType tlsv3.SubjectAltNameMatcher_SanType
+ var value string
+
+ // Exactly one of san.Hostname or san.URI is guaranteed to be set
+ if san.Hostname != nil {
+ sanType = tlsv3.SubjectAltNameMatcher_DNS
+ value = *san.Hostname
+ } else if san.URI != nil {
+ sanType = tlsv3.SubjectAltNameMatcher_URI
+ value = *san.URI
+ }
+ validationContext.DefaultValidationContext.MatchTypedSubjectAltNames = append(
+ validationContext.DefaultValidationContext.MatchTypedSubjectAltNames,
+ &tlsv3.SubjectAltNameMatcher{
+ SanType: sanType,
+ Matcher: &matcherv3.StringMatcher{
+ MatchPattern: &matcherv3.StringMatcher_Exact{
+ Exact: value,
},
},
- )
- }
+ },
+ )
+ hasSANValidations = true
}
return &tlsv3.CommonTlsContext_CombinedValidationContext{
CombinedValidationContext: validationContext,
- }
+ }, hasSANValidations
}
-func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3.TransportSocket, error) {
+func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig, requiresAutoSNI bool, endpointType EndpointType) (*corev3.TransportSocket, error) {
tlsCtx := &tlsv3.UpstreamTlsContext{
CommonTlsContext: &tlsv3.CommonTlsContext{
TlsCertificateSdsSecretConfigs: nil,
@@ -1227,7 +1230,19 @@ func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3.
}
if !tlsConfig.InsecureSkipVerify {
- tlsCtx.CommonTlsContext.ValidationContextType = buildValidationContext(tlsConfig)
+ ctx, hasSANValidations := buildValidationContext(tlsConfig)
+ tlsCtx.CommonTlsContext.ValidationContextType = ctx
+
+ // Auto SNI SAN validation is only be enabled in the following cases:
+ // 1. there aren't any other SAN validations
+ // 2. InsecureSkipVerify is disabled
+ // 3. SNI is configured (literal or auto)
+ // 4. Endpoint is not a dynamic resolver, which uses a different strategy for Auto SAN validation
+ // See here: https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/securing#validate-an-endpoint-s-certificates-when-connecting
+ // Also, only enable validation if InsecureSkipVerify id disabled
+ if !hasSANValidations && (tlsConfig.SNI != nil || requiresAutoSNI) && endpointType != EndpointTypeDynamicResolver {
+ tlsCtx.AutoSniSanValidation = true
+ }
}
if tlsConfig.SNI != nil {
diff --git a/release-notes/current.yaml b/release-notes/current.yaml
index 9431ec2379c..7c8bf7760f6 100644
--- a/release-notes/current.yaml
+++ b/release-notes/current.yaml
@@ -3,6 +3,8 @@ date: Pending
# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
breaking changes: |
ALPNProtocols in EnvoyProxy Backend TLS setting use [h2, http/1.1] if not set.
+ When a Backend resource specifies TLS settings and SNI is not specified or a BackendTLSPolicy is not attached to it, the value of upstream TLS SNI is determined by the HTTP Host header.
+ When a Backend resource specifies TLS settings and SNI is not specified or a BackendTLSPolicy is not attached to it, the upstream certificate is validated for DNS SAN matching the SNI value sent.
# Updates addressing vulnerabilities, security flaws, or compliance requirements.
security updates: |
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index 7a81b63093a..f5722844c2e 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -461,6 +461,7 @@ _Appears in:_
| `caCertificateRefs` | _LocalObjectReference array_ | false | | CACertificateRefs contains one or more references to Kubernetes objects that
contain TLS certificates of the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the backend.
A single reference to a Kubernetes ConfigMap or a Kubernetes Secret,
with the CA certificate in a key named `ca.crt` is currently supported.
If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be
specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,
not both. |
| `wellKnownCACertificates` | _[WellKnownCACertificatesType](#wellknowncacertificatestype)_ | false | | WellKnownCACertificates specifies whether system CA certificates may be used in
the TLS handshake between the gateway and backend pod.
If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs
must be specified with at least one entry for a valid configuration. Only one of
CACertificateRefs or WellKnownCACertificates may be specified, not both. |
| `insecureSkipVerify` | _boolean_ | false | false | InsecureSkipVerify indicates whether the upstream's certificate verification
should be skipped. Defaults to "false". |
+| `sni` | _[PreciseHostname](#precisehostname)_ | false | | SNI is specifies the SNI value used when establishing an upstream TLS connection to the backend.
Envoy Gateway will use the HTTP host header value for SNI, when all resources referenced in BackendRefs are:
1. Backend resources that do not set SNI, or
2. Service/ServiceImport resources that do not have a BackendTLSPolicy attached to them
When a BackendTLSPolicy attaches to a Backend resource, the BackendTLSPolicy's Hostname value takes precedence
over this value. |
#### BackendTelemetry
diff --git a/test/e2e/testdata/backend-tls.yaml b/test/e2e/testdata/backend-tls.yaml
index 1f6f7d06375..d9abe4001c3 100644
--- a/test/e2e/testdata/backend-tls.yaml
+++ b/test/e2e/testdata/backend-tls.yaml
@@ -212,3 +212,38 @@ spec:
group: gateway.envoyproxy.io
kind: Backend
---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: http-with-backend-tls-auto-sni
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /backend-auto-sni
+ backendRefs:
+ - name: backend-with-auto-sni
+ group: gateway.envoyproxy.io
+ kind: Backend
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-with-auto-sni
+ namespace: gateway-conformance-infra
+spec:
+ endpoints:
+ - fqdn:
+ hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local
+ port: 443
+ # The SNI value would be taken from the host header sent by the client and
+ # Envoy will validate the upstream certificate for a DNS SAN that matches SNI
+ tls:
+ caCertificateRefs:
+ - name: backend-tls-ca
+ group: ""
+ kind: ConfigMap
diff --git a/test/e2e/tests/backend_tls.go b/test/e2e/tests/backend_tls.go
index e711f794929..5e2141f9a36 100644
--- a/test/e2e/tests/backend_tls.go
+++ b/test/e2e/tests/backend_tls.go
@@ -120,6 +120,27 @@ var BackendTLSTest = suite.ConformanceTest{
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
})
+
+ t.Run("With BackendTLSPolicy and Backend.TLS.AutoSNI", func(t *testing.T) {
+ routeNN := types.NamespacedName{Name: "http-with-backend-tls-auto-sni", Namespace: ConformanceInfraNamespace}
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+
+ expectedResponse := http.ExpectedResponse{
+ Request: http.Request{
+ Host: "example.com",
+ Path: "/backend-auto-sni",
+ },
+ Response: http.Response{
+ StatusCode: 200,
+ },
+ Namespace: ConformanceInfraNamespace,
+ }
+
+ // make assertion
+ // Since BTLSP uses a Hostname that's incorrect, the request will only succeed if:
+ // SNI is rewritten to example.com and DNS SAN validation is done according to this SNI
+ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+ })
},
}
diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml
index 85c1336359a..9dc91e06aa3 100644
--- a/test/helm/gateway-crds-helm/all.out.yaml
+++ b/test/helm/gateway-crds-helm/all.out.yaml
@@ -17535,6 +17535,20 @@ spec:
InsecureSkipVerify indicates whether the upstream's certificate verification
should be skipped. Defaults to "false".
type: boolean
+ sni:
+ description: |-
+ SNI is specifies the SNI value used when establishing an upstream TLS connection to the backend.
+
+ Envoy Gateway will use the HTTP host header value for SNI, when all resources referenced in BackendRefs are:
+ 1. Backend resources that do not set SNI, or
+ 2. Service/ServiceImport resources that do not have a BackendTLSPolicy attached to them
+
+ When a BackendTLSPolicy attaches to a Backend resource, the BackendTLSPolicy's Hostname value takes precedence
+ over this value.
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
wellKnownCACertificates:
description: |-
WellKnownCACertificates specifies whether system CA certificates may be used in
diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
index c3a59e5c31c..89c627a3c5e 100644
--- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
+++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
@@ -223,6 +223,20 @@ spec:
InsecureSkipVerify indicates whether the upstream's certificate verification
should be skipped. Defaults to "false".
type: boolean
+ sni:
+ description: |-
+ SNI is specifies the SNI value used when establishing an upstream TLS connection to the backend.
+
+ Envoy Gateway will use the HTTP host header value for SNI, when all resources referenced in BackendRefs are:
+ 1. Backend resources that do not set SNI, or
+ 2. Service/ServiceImport resources that do not have a BackendTLSPolicy attached to them
+
+ When a BackendTLSPolicy attaches to a Backend resource, the BackendTLSPolicy's Hostname value takes precedence
+ over this value.
+ maxLength: 253
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
wellKnownCACertificates:
description: |-
WellKnownCACertificates specifies whether system CA certificates may be used in