-
Notifications
You must be signed in to change notification settings - Fork 688
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
Wildcard certificate with HTTP/2 causes 421 Misdirected Request on cross-host connection reuse #5240
Comments
Hey @sybereal! Thanks for opening your first issue. We appreciate your contribution and welcome you to our community! We are glad to have you here and to have your input on Contour. You can also join us on our mailing list and in our channel in the Kubernetes Slack Workspace |
This behavior is by design (and will not differ between Ingress, HTTPProxy, or Gateway API) because requests can be routed to the wrong backend/be processed incorrectly (generally be run through the wrong filter chain) if we do not check that the SNI and request authority match. See original issue: #1493 |
My bad, I guess I should've phrased it as a question instead of a bug report. So, am I correct in assuming that connection coalescing and thus HTTP/2 with wildcard certificates is inherently unsupported by Contour?
That's another question I had: I noticed that when TLS is disabled, there is only one filter chain and hosts are disambiguated through virtual hosts on the route config. But once TLS is enabled, each host gets its own filter chain. |
I wouldn't say inherently unsupported, but the aggressive coalescing that certain clients/browsers use will cause issues. The RFC says clients "MAY" retry when they get a 421 response so not all do. According to this comment newer versions of Safari should retry but not sure the source of that. |
Yes, without TLS, there is no way to match traffic (i.e. at the L4/TLS level) to different filter chains but you can match on SNI when TLS is enabled. Having separate filter chains per vhost allows us to do things like enable a particular filter (external auth, etc.) for that vhost only. Not all filters in Envoy have a per-Route filter available to configure/enable/disable the filter so we do have to do things at the HTTP filter chain level. |
The Contour project currently lacks enough contributors to adequately respond to all Issues. This bot triages Issues according to the following rules:
You can:
Please send feedback to the #contour channel in the Kubernetes Slack |
The Contour project currently lacks enough contributors to adequately respond to all Issues. This bot triages Issues according to the following rules:
You can:
Please send feedback to the #contour channel in the Kubernetes Slack |
What steps did you take and what happened:
I deployed a Gateway with a wildcard hostname
*.cluster.example.com
and matching certificate, as well as two HTTPRoutes with specific hostnames matching that wildcard name. When navigating from one to another in a browser that implements HTTP/2 connection reuse, e.g. Firefox, there will be a 421 Misdirected Request error. Since the spec does not require retrying, some clients (our reports came from macOS Safari users) will then be stuck on the error page.I was able to forcibly trigger the 421 by passing one URL (for SNI) and then overriding the
Host
header to try and direct the request to another backend.What did you expect to happen:
If there is one gateway with one certificate matching all possible hostnames, I would expect HTTP/2 connection reuse to work.
Anything else you would like to add:
I originally experienced the issue with separate Ingress resources using the same wildcard certificate and switched to Gateway API, hoping the split between the Gateway and HTTPRoute resources would avoid this issue.
In both cases, as soon as TLS is enabled, one filter chain is generated for each hostname, preventing connection reuse across hostnames.
Currently, the workaround I deployed disables HTTP/2, thus avoiding cross-host connection reuse entirely.
Environment:
kubectl version
): Kubernetes API server 1.25.5 (AKS) or 1.25.3 (KinD)/etc/os-release
): KinD running on openSUSE Tumbleweed in WSL, AKS running on UbuntuThe text was updated successfully, but these errors were encountered: