Skip to content

Commit 35420d5

Browse files
fix(tranlator): SubjectAltNames were being dropped from BackendTLSPolicy.validation (#6092)
* Add support for SubjectAltNames from BackendTLSPolicy.validation Signed-off-by: Ankush Agarwal <[email protected]>
1 parent d776c6f commit 35420d5

File tree

9 files changed

+424
-0
lines changed

9 files changed

+424
-0
lines changed

internal/gatewayapi/backendtlspolicy.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,25 @@ func getBackendTLSPolicy(
207207
}
208208

209209
func getBackendTLSBundle(backendTLSPolicy *gwapiv1a3.BackendTLSPolicy, resources *resource.Resources) (*ir.TLSUpstreamConfig, error) {
210+
// Translate SubjectAltNames from gwapiv1a3 to ir
211+
var subjectAltNames []ir.SubjectAltName
212+
for _, san := range backendTLSPolicy.Spec.Validation.SubjectAltNames {
213+
var subjectAltName ir.SubjectAltName
214+
switch san.Type {
215+
case "DNS":
216+
subjectAltName.Hostname = ptr.To(string(san.Hostname))
217+
case "URI":
218+
subjectAltName.URI = ptr.To(string(san.URI))
219+
default:
220+
continue // skip unknown types
221+
}
222+
subjectAltNames = append(subjectAltNames, subjectAltName)
223+
}
224+
210225
tlsBundle := &ir.TLSUpstreamConfig{
211226
SNI: ptr.To(string(backendTLSPolicy.Spec.Validation.Hostname)),
212227
UseSystemTrustStore: ptr.Deref(backendTLSPolicy.Spec.Validation.WellKnownCACertificates, "") == gwapiv1a3.WellKnownCACertificatesSystem,
228+
SubjectAltNames: subjectAltNames,
213229
}
214230
if tlsBundle.UseSystemTrustStore {
215231
tlsBundle.CACertificate = &ir.TLSCACertificate{
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
gateways:
2+
- apiVersion: gateway.networking.k8s.io/v1
3+
kind: Gateway
4+
metadata:
5+
name: gateway-btls
6+
namespace: envoy-gateway
7+
spec:
8+
gatewayClassName: envoy-gateway-class
9+
listeners:
10+
- name: http
11+
protocol: HTTP
12+
port: 80
13+
allowedRoutes:
14+
namespaces:
15+
from: All
16+
httpRoutes:
17+
- apiVersion: gateway.networking.k8s.io/v1
18+
kind: HTTPRoute
19+
metadata:
20+
name: httproute-btls
21+
namespace: envoy-gateway
22+
spec:
23+
parentRefs:
24+
- namespace: envoy-gateway
25+
name: gateway-btls
26+
sectionName: http
27+
rules:
28+
- matches:
29+
- path:
30+
type: Exact
31+
value: "/exact"
32+
backendRefs:
33+
- name: http-backend
34+
namespace: backends
35+
port: 8080
36+
37+
referenceGrants:
38+
- apiVersion: gateway.networking.k8s.io/v1alpha2
39+
kind: ReferenceGrant
40+
metadata:
41+
name: refg-route-svc
42+
namespace: backends
43+
spec:
44+
from:
45+
- group: gateway.networking.k8s.io
46+
kind: HTTPRoute
47+
namespace: envoy-gateway
48+
- group: gateway.networking.k8s.io
49+
kind: Gateway
50+
namespace: envoy-gateway
51+
to:
52+
- group: ""
53+
kind: Service
54+
55+
services:
56+
- apiVersion: v1
57+
kind: Service
58+
metadata:
59+
name: http-backend
60+
namespace: backends
61+
spec:
62+
clusterIP: 10.11.12.13
63+
ports:
64+
- port: 8080
65+
name: http
66+
protocol: TCP
67+
targetPort: 8080
68+
69+
endpointSlices:
70+
- apiVersion: discovery.k8s.io/v1
71+
kind: EndpointSlice
72+
metadata:
73+
name: endpointslice-http-backend
74+
namespace: backends
75+
labels:
76+
kubernetes.io/service-name: http-backend
77+
addressType: IPv4
78+
ports:
79+
- name: http
80+
protocol: TCP
81+
port: 8080
82+
endpoints:
83+
- addresses:
84+
- "10.244.0.11"
85+
conditions:
86+
ready: true
87+
88+
configMaps:
89+
- apiVersion: v1
90+
kind: ConfigMap
91+
metadata:
92+
name: ca-cmap
93+
namespace: backends
94+
data:
95+
ca.crt: |
96+
-----BEGIN CERTIFICATE-----
97+
MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL
98+
BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw
99+
MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G
100+
A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc
101+
1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM
102+
yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b
103+
kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU
104+
Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq
105+
ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR
106+
bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48
107+
6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/
108+
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz
109+
2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J
110+
i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE
111+
A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg
112+
d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1
113+
3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q==
114+
-----END CERTIFICATE-----
115+
backendTLSPolicies:
116+
- apiVersion: gateway.networking.k8s.io/v1alpha2
117+
kind: BackendTLSPolicy
118+
metadata:
119+
name: policy-btls
120+
namespace: backends
121+
spec:
122+
targetRefs:
123+
- group: ""
124+
kind: Service
125+
name: http-backend
126+
sectionName: http
127+
validation:
128+
caCertificateRefs:
129+
- name: ca-cmap
130+
group: ""
131+
kind: ConfigMap
132+
hostname: example.com
133+
subjectAltNames:
134+
- type: URI
135+
uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
136+
- type: DNS
137+
hostname: subdomain.secondexample.com
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
backendTLSPolicies:
2+
- apiVersion: gateway.networking.k8s.io/v1alpha2
3+
kind: BackendTLSPolicy
4+
metadata:
5+
creationTimestamp: null
6+
name: policy-btls
7+
namespace: backends
8+
spec:
9+
targetRefs:
10+
- group: ""
11+
kind: Service
12+
name: http-backend
13+
sectionName: http
14+
validation:
15+
caCertificateRefs:
16+
- group: ""
17+
kind: ConfigMap
18+
name: ca-cmap
19+
hostname: example.com
20+
subjectAltNames:
21+
- type: URI
22+
uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
23+
- hostname: subdomain.secondexample.com
24+
type: DNS
25+
status:
26+
ancestors:
27+
- ancestorRef:
28+
name: gateway-btls
29+
namespace: envoy-gateway
30+
sectionName: http
31+
conditions:
32+
- lastTransitionTime: null
33+
message: Policy has been accepted.
34+
reason: Accepted
35+
status: "True"
36+
type: Accepted
37+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
38+
gateways:
39+
- apiVersion: gateway.networking.k8s.io/v1
40+
kind: Gateway
41+
metadata:
42+
creationTimestamp: null
43+
name: gateway-btls
44+
namespace: envoy-gateway
45+
spec:
46+
gatewayClassName: envoy-gateway-class
47+
listeners:
48+
- allowedRoutes:
49+
namespaces:
50+
from: All
51+
name: http
52+
port: 80
53+
protocol: HTTP
54+
status:
55+
listeners:
56+
- attachedRoutes: 1
57+
conditions:
58+
- lastTransitionTime: null
59+
message: Sending translated listener configuration to the data plane
60+
reason: Programmed
61+
status: "True"
62+
type: Programmed
63+
- lastTransitionTime: null
64+
message: Listener has been successfully translated
65+
reason: Accepted
66+
status: "True"
67+
type: Accepted
68+
- lastTransitionTime: null
69+
message: Listener references have been resolved
70+
reason: ResolvedRefs
71+
status: "True"
72+
type: ResolvedRefs
73+
name: http
74+
supportedKinds:
75+
- group: gateway.networking.k8s.io
76+
kind: HTTPRoute
77+
- group: gateway.networking.k8s.io
78+
kind: GRPCRoute
79+
httpRoutes:
80+
- apiVersion: gateway.networking.k8s.io/v1
81+
kind: HTTPRoute
82+
metadata:
83+
creationTimestamp: null
84+
name: httproute-btls
85+
namespace: envoy-gateway
86+
spec:
87+
parentRefs:
88+
- name: gateway-btls
89+
namespace: envoy-gateway
90+
sectionName: http
91+
rules:
92+
- backendRefs:
93+
- name: http-backend
94+
namespace: backends
95+
port: 8080
96+
matches:
97+
- path:
98+
type: Exact
99+
value: /exact
100+
status:
101+
parents:
102+
- conditions:
103+
- lastTransitionTime: null
104+
message: Route is accepted
105+
reason: Accepted
106+
status: "True"
107+
type: Accepted
108+
- lastTransitionTime: null
109+
message: Resolved all the Object references for the Route
110+
reason: ResolvedRefs
111+
status: "True"
112+
type: ResolvedRefs
113+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
114+
parentRef:
115+
name: gateway-btls
116+
namespace: envoy-gateway
117+
sectionName: http
118+
infraIR:
119+
envoy-gateway/gateway-btls:
120+
proxy:
121+
listeners:
122+
- address: null
123+
name: envoy-gateway/gateway-btls/http
124+
ports:
125+
- containerPort: 10080
126+
name: http-80
127+
protocol: HTTP
128+
servicePort: 80
129+
metadata:
130+
labels:
131+
gateway.envoyproxy.io/owning-gateway-name: gateway-btls
132+
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
133+
name: envoy-gateway/gateway-btls
134+
namespace: envoy-gateway-system
135+
xdsIR:
136+
envoy-gateway/gateway-btls:
137+
accessLog:
138+
json:
139+
- path: /dev/stdout
140+
http:
141+
- address: 0.0.0.0
142+
hostnames:
143+
- '*'
144+
isHTTP2: false
145+
metadata:
146+
kind: Gateway
147+
name: gateway-btls
148+
namespace: envoy-gateway
149+
sectionName: http
150+
name: envoy-gateway/gateway-btls/http
151+
path:
152+
escapedSlashesAction: UnescapeAndRedirect
153+
mergeSlashes: true
154+
port: 10080
155+
routes:
156+
- destination:
157+
name: httproute/envoy-gateway/httproute-btls/rule/0
158+
settings:
159+
- addressType: IP
160+
endpoints:
161+
- host: 10.244.0.11
162+
port: 8080
163+
name: httproute/envoy-gateway/httproute-btls/rule/0/backend/0
164+
protocol: HTTP
165+
tls:
166+
alpnProtocols: null
167+
caCertificate:
168+
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
169+
name: policy-btls/backends-ca
170+
sni: example.com
171+
subjectAltNames:
172+
- uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
173+
- hostname: subdomain.secondexample.com
174+
weight: 1
175+
hostname: '*'
176+
isHTTP2: false
177+
metadata:
178+
kind: HTTPRoute
179+
name: httproute-btls
180+
namespace: envoy-gateway
181+
name: httproute/envoy-gateway/httproute-btls/rule/0/match/0/*
182+
pathMatch:
183+
distinct: false
184+
exact: /exact
185+
name: ""
186+
readyListener:
187+
address: 0.0.0.0
188+
ipFamily: IPv4
189+
path: /ready
190+
port: 19003

internal/ir/xds.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,20 @@ type TLSCACertificate struct {
445445
Certificate []byte `json:"certificate,omitempty" yaml:"certificate,omitempty"`
446446
}
447447

448+
// SubjectAltName holds the subject alternative name for the certificate
449+
// This is the internal representation of the SubjectAltName in the Gateway API
450+
// https://github.com/kubernetes-sigs/gateway-api/blob/6fbbd90954c2a30a6502cbb22ec6e7f3359ed3a0/apis/v1alpha3/backendtlspolicy_types.go#L177
451+
// +k8s:deepcopy-gen=true
452+
type SubjectAltName struct {
453+
// Only one of the following fields should be set.
454+
// Hostname contains Subject Alternative Name specified in DNS name format.
455+
Hostname *string `json:"hostname,omitempty" yaml:"hostname,omitempty"`
456+
// URI contains Subject Alternative Name specified in a full URI format.
457+
// It MUST include both a scheme (e.g., "http" or "ftp") and a scheme-specific-part.
458+
// Common values include SPIFFE IDs like "spiffe://mycluster.example.com/ns/myns/sa/svc1sa".
459+
URI *string `json:"uri,omitempty" yaml:"uri,omitempty"`
460+
}
461+
448462
func (t TLSCertificate) Validate() error {
449463
var errs error
450464
if len(t.Certificate) == 0 {
@@ -2855,6 +2869,7 @@ type TLSUpstreamConfig struct {
28552869
UseSystemTrustStore bool `json:"useSystemTrustStore,omitempty" yaml:"useSystemTrustStore,omitempty"`
28562870
CACertificate *TLSCACertificate `json:"caCertificate,omitempty" yaml:"caCertificate,omitempty"`
28572871
TLSConfig `json:",inline"`
2872+
SubjectAltNames []SubjectAltName `json:"subjectAltNames,omitempty" yaml:"subjectAltNames,omitempty"`
28582873
}
28592874

28602875
func (t *TLSUpstreamConfig) ToTLSConfig() (*tls.Config, error) {

0 commit comments

Comments
 (0)