What
Envoy Gateway currently does not return HTTP 421 (Misdirected Request) when a TLS connection's SNI does not match the HTTP Host/:authority header. This is required by RFC 9110 Section 7.4 and tested by the upstream Gateway API conformance feature GatewayHTTPSListenerDetectMisdirectedRequests.
This feature is currently skipped in both default and gateway-namespace-mode conformance runs, and listed under unsupportedFeatures in the published conformance reports (default, gateway-namespace-mode).
Current behavior
When multiple HTTPS listeners share the same port with different hostnames, a request where the SNI and Host header don't match returns 404 instead of 421.
Expected behavior
Return 421 Misdirected Request when the SNI used in the TLS handshake does not match the Host/:authority header of the HTTP request.
Implementation considerations
Envoy does not have a built-in filter for misdirected request detection. The most practical approach is to have EG automatically inject a Lua HTTP filter into the generated xDS configuration for HTTPS listeners. The required API (streamInfo():requestedServerName()) is already available in Envoy's Lua runtime, added via envoyproxy/envoy#15215.
Rough sketch:
function envoy_on_request(request_handle)
local sni = request_handle:streamInfo():requestedServerName()
local authority = request_handle:headers():get(":authority")
if sni ~= "" and authority ~= sni then
request_handle:respond({[":status"] = "421"}, "")
end
end
Challenges
Wildcard hostname matching: The conformance test includes patterns like *.wildcard.org. Simple string comparison is insufficient — wildcard matching logic needs to be implemented within the Lua script.
Performance: The Lua filter runs on every HTTPS request. In high-traffic environments the overhead may be a concern.
Alternative — native Envoy filter: A longer-term option would be to propose a native misdirected request detection filter upstream to Envoy, which would be more performant and maintainable.
Related
I'd like to work on this if the approach sounds reasonable.
What
Envoy Gateway currently does not return HTTP 421 (Misdirected Request) when a TLS connection's SNI does not match the HTTP Host/
:authorityheader. This is required by RFC 9110 Section 7.4 and tested by the upstream Gateway API conformance featureGatewayHTTPSListenerDetectMisdirectedRequests.This feature is currently skipped in both default and gateway-namespace-mode conformance runs, and listed under
unsupportedFeaturesin the published conformance reports (default, gateway-namespace-mode).Current behavior
When multiple HTTPS listeners share the same port with different hostnames, a request where the SNI and Host header don't match returns
404instead of421.Expected behavior
Return
421 Misdirected Requestwhen the SNI used in the TLS handshake does not match the Host/:authorityheader of the HTTP request.Implementation considerations
Envoy does not have a built-in filter for misdirected request detection. The most practical approach is to have EG automatically inject a
Lua HTTP filterinto the generated xDS configuration for HTTPS listeners. The required API (streamInfo():requestedServerName()) is already available in Envoy's Lua runtime, added via envoyproxy/envoy#15215.Rough sketch:
Challenges
Wildcard hostname matching: The conformance test includes patterns like*.wildcard.org. Simple string comparison is insufficient — wildcard matching logic needs to be implemented within the Lua script.Performance: The Lua filter runs on every HTTPS request. In high-traffic environments the overhead may be a concern.Alternative — native Envoy filter: A longer-term option would be to propose a native misdirected request detection filter upstream to Envoy, which would be more performant and maintainable.Related
requestedServerName()in LuaI'd like to work on this if the approach sounds reasonable.