generated from kubernetes/kubernetes-template-project
-
Notifications
You must be signed in to change notification settings - Fork 542
Adding GEP-3567: Gateway TLS Updates for HTTP/2 Connection Coalescing #3572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
# GEP-3567: Gateway TLS Updates for HTTP/2 Connection Coalescing | ||
|
||
* Issue: [#3567](https://github.com/kubernetes-sigs/gateway-api/issues/3567) | ||
* Status: Implementable | ||
|
||
## TLDR | ||
|
||
As described in the [previous | ||
doc](https://docs.google.com/document/d/1g_TNN8eOaVDC3xesO9JFdvQbPFdSTHp1vb70TD3-Vrs/edit?tab=t.0#heading=h.qiz1tfw67tbp), | ||
the current state of TLS configuration on Gateways can lead to confusing | ||
behavior when combined with HTTP/2 connection coalescing. This GEP proposes a | ||
series of changes to the API to address these problems. | ||
|
||
## Goals | ||
|
||
* Take steps that will make it less likely for users to encounter these problems | ||
* Warn when users have configuration that is prone to these issues | ||
* Provide central source of documentation explaining both the problem and | ||
potential solutions | ||
|
||
## Non-Goals | ||
|
||
* Breaking or significantly disruptive changes to the existing API surface | ||
|
||
## Introduction | ||
|
||
Gateway API creates situations where clients might be able to send requests | ||
through a Listener that, according to the Gateway’s configuration, is not | ||
supposed to receive these requests. This can cause requests to be apparently | ||
mis-routed. | ||
|
||
The problem here is an inherent conflict between the API and the mechanics of | ||
HTTPS. Gateway API uses the “hostname” field in the Listener to constrain both | ||
the TLS certificate selection and the host header of requests. But when a server | ||
presents a TLS certificate that is valid for multiple domains, a client is free | ||
to reuse its TLS connection for requests sent to any of those domains (for | ||
HTTP2, see RFC). The SNI hostname, which the client presents only with the | ||
initial TLS handshake, doesn’t constrain the host header of the requests that | ||
the client sends. | ||
|
||
Gateway API deals with this situation imprecisely, stating: | ||
|
||
The Listener Hostname SHOULD match at both the TLS and HTTP protocol layers as described above. If an implementation does not ensure that both the SNI and Host header match the Listener hostname, it MUST clearly document that. | ||
|
||
In practice we can end up with an implementation that misroutes requests when a | ||
Gateway is configured using certificates that use multiple or wildcard SANs. | ||
|
||
### Example | ||
|
||
The following configuration ([from the Gateway API | ||
documentation](https://gateway-api.sigs.k8s.io/guides/tls/#wildcard-tls-listeners)) | ||
illustrates the problem: | ||
|
||
|
||
``` | ||
apiVersion: gateway.networking.k8s.io/v1 | ||
kind: Gateway | ||
metadata: | ||
name: wildcard-tls-gateway | ||
spec: | ||
gatewayClassName: example | ||
listeners: | ||
- name: foo-https | ||
protocol: HTTPS | ||
port: 443 | ||
hostname: foo.example.com | ||
tls: | ||
certificateRefs: | ||
- kind: Secret | ||
group: "" | ||
name: foo-example-com-cert # SAN: foo.example.com | ||
- name: wildcard-https | ||
protocol: HTTPS | ||
port: 443 | ||
hostname: "*.example.com" | ||
tls: | ||
certificateRefs: | ||
- kind: Secret | ||
group: "" | ||
name: wildcard-example-com-cert # SAN: *.example.com | ||
``` | ||
|
||
|
||
The Gateway API definition requires requests to `foo.example.com` to be | ||
associated with the `foo-https` listener, on connections negotiated with | ||
`foo-example-com-cert`. | ||
|
||
Suppose a client sends a request to `bar.example.com`, specifying that as the | ||
SNI hostname, and establishes a TLS connection attached to the `wildcard-https` | ||
Listener. And then it sends a subsequent request to `foo.example.com`. The | ||
client can correctly reuse its existing TLS connection for the second request, | ||
because the `wildcard-example-com-cert` is valid also for `foo.example.com`. But | ||
now the Gateway has a problem: Routing the request via the `wildcard-https` | ||
Listener violates the intent of the configuration, and routing via the | ||
`foo-https` Listener is inconsistent with the connection’s having been | ||
negotiated with the other Listener’s certificate. | ||
|
||
Mapping a request to a Listener matters if the Gateway configuration has | ||
different | ||
[HTTPRoutes](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRoute) | ||
bound to the different Listeners. It also matters if the Listeners have | ||
different | ||
[GatewayTlsConfigs](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GatewayTLSConfig) | ||
attached, for example if one Listener uses mutual TLS and the other does not. | ||
|
||
|
||
### Interaction with Client Cert Validation | ||
|
||
[GEP-91](https://gateway-api.sigs.k8s.io/geps/gep-91/) introduced Client | ||
Certificate Validation to Gateway Listeners as a new experimental concept. If an | ||
implementation is unable to properly isolate HTTPS listeners, this could result | ||
in this Client Cert Validation being bypassed. Before this feature can graduate | ||
beyond experimental, we’ll need to resolve this underlying issue. | ||
|
||
## Proposal | ||
|
||
### A) Add Warning in Gateway Status | ||
A new condition will be added to Gateways: `OverlappingTLSConfig`. | ||
Implementations MUST add this condition to status when a Gateway is configured | ||
with TLS configuration across multiple Listeners. Implementations MAY add this | ||
condition to status when a Gateway is configured with overlapping TLS | ||
certifications. Note that since this is a negative polarity condition, it would | ||
only be populated when it is true. | ||
|
||
### B) Modify API Spec to recommend sending 421s | ||
The Gateway spec for `listener.hostname` will be updated to recommend returning | ||
a 421 when this problem occurs. | ||
|
||
### C) Top Level Gateway TLS Config for Client Cert Validation | ||
|
||
A follow up discussion for GEP-91 will consider if Client Cert Validation should | ||
be moved or copied to a new top level Gateway TLS config instead of | ||
per-listener. | ||
|
||
## Conformance Details | ||
|
||
#### Feature Names | ||
|
||
A) None, this will be required for any implementations that support HTTP + | ||
Gateways. | ||
|
||
B) `GatewayReturn421` | ||
|
||
C) Will be covered in GEP-91 | ||
|
||
### Conformance tests | ||
|
||
A) A new conformance test will be added to ensure that the new status condition | ||
is populated when a Gateway is configured with overlapping TLS configuration. | ||
|
||
B) A new conformance test will be added to ensure that implementations return a | ||
421 when a connection is reused for a different listener with an overlapping | ||
SNI. | ||
|
||
C) Will be covered in GEP-91 | ||
|
||
## Alternatives | ||
|
||
Discussed in more detail the [original | ||
doc](https://docs.google.com/document/d/1g_TNN8eOaVDC3xesO9JFdvQbPFdSTHp1vb70TD3-Vrs/edit?tab=t.0#heading=h.qiz1tfw67tbp) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
apiVersion: internal.gateway.networking.k8s.io/v1alpha1 | ||
kind: GEPDetails | ||
number: 3567 | ||
name: Gateway TLS Updates for HTTP/2 Connection Coalescing | ||
status: Implementable | ||
# Any authors who contribute to the GEP in any way should be listed here using | ||
# their Github handle. | ||
authors: | ||
- robscott | ||
relationships: | ||
# obsoletes indicates that a GEP makes the linked GEP obsolete, and completely | ||
# replaces that GEP. The obsoleted GEP MUST have its obsoletedBy field | ||
# set back to this GEP, and MUST be moved to Declined. | ||
obsoletes: {} | ||
obsoletedBy: {} | ||
# extends indicates that a GEP extends the linkned GEP, adding more detail | ||
# or additional implementation. The extended GEP MUST have its extendedBy | ||
# field set back to this GEP. | ||
extends: {} | ||
extendedBy: {} | ||
# seeAlso indicates other GEPs that are relevant in some way without being | ||
# covered by an existing relationship. | ||
seeAlso: {} | ||
# references is a list of hyperlinks to relevant external references. | ||
# It's intended to be used for storing Github discussions, Google docs, etc. | ||
references: {} | ||
# featureNames is a list of the feature names introduced by the GEP, if there | ||
# are any. This will allow us to track which feature was introduced by which GEP. | ||
featureNames: | ||
- GatewayReturn421 | ||
# changelog is a list of hyperlinks to PRs that make changes to the GEP, in | ||
# ascending date order. | ||
changelog: {} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.