Skip to content

Support GatewayHTTPSListenerDetectMisdirectedRequests conformance feature #9577

Description

@mmmommm

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions