HTTP/2 backend and :scheme header

I am using HAproxy (2.2.6-1~bpo10+1 2020/12/01) as a reverse proxy for HTTP2 backend
HAproxy is doing TLS termination, connection between HAProxy and backend is cleartext, so BE looks like this

backend bk_howitzer_http_reverse_proxy
  mode http
  server sv_localhost ipv6@[::1]:5000 check proto h2

Problem:
HAproxy sets the HTTP2 pseudoheader :scheme to https, and ASP.NET Core backend drops the request because it expects :http.

dbug: Microsoft.AspNetCore.Server.Kestrel[35]
      Trace id "0HM5AGGHLO7JT:00000003": HTTP/2 stream error "PROTOCOL_ERROR". A Reset is being sent to the stream.
      Microsoft.AspNetCore.Connections.ConnectionAbortedException: The request :scheme header 'https' does not match the transport scheme 'http'.

I already saw in https://github.com/haproxy/haproxy/issues/77 that :scheme now forwarded from incoming TLS request. But since HAProxy is doing TLS termination shouldn’t it send :scheme as http, and use X-Forwarded-Proto instead?

There is a similar problems for linkerd:

Also it seems that Kestrel validation won’t get dropped anyway

So is there any way to force HAproxy to send the :scheme as http?

Possible workaround

1 Like