Questions about backend h2 in haproxy 1.9

When using haproxy 1.8 and before in order to use h2, i simply checked the ssl_fc_alpn and then sent traffic to the correct server depending on if the client(browser) supported h2. Now with h2 available on the backend in 1.9 and 2.0, i thought i may be able to remove this check and clean up the configuration, but am clearly missing something.

– haproxy 1.8 –

frontend https
  mode tcp
  bind 0.0.0.0:443 ssl crt /etc/haproxy/certs alpn h2,http/1.1 ecdhe secp384r1
  timeout http-request 10s
  #send all HTTP/2 traffic to a specific backend
  use_backend http2-nodes if { ssl_fc_alpn -i h2 }
  #send HTTP/1.1 and HTTP/1.0 to default, which don't speak HTTP/2
  default_backend http1-nodes

backend http1-nodes
  mode http
  balance roundrobin
  default-server inter 1s fall 2 on-marked-down shutdown-sessions on-marked-up shutdown-backup-sessions

  server web01 10.X.X.12:80 check send-proxy
  server web02 10.X.X.14:80 check send-proxy

backend http2-nodes
  mode tcp
  balance roundrobin
  default-server inter 1s fall 2 on-marked-down shutdown-sessions on-marked-up shutdown-backup-sessions

  server web01 10.X.X.12:81 check send-proxy
  server web02 10.X.X.14:81 check send-proxy

Nginx is behind these servers and has http2 on port 81 and regular 1.1 on 80

In haproxy 1.9 and 2.0 i was thinking i could use one backend for haproxy and drop the 2nd port for Nginx. Something like the following:

frontend https
  mode http
  bind 0.0.0.0:443 ssl crt /etc/haproxy/certs alpn h2,http/1.1 ecdhe secp384r1
  option http-use-htx
  timeout http-request 10s
  default_backend http-nodes

backend http-nodes
  mode http
  option http-use-htx
  balance roundrobin
  default-server inter 1s fall 2 on-marked-down shutdown-sessions on-marked-up shutdown-backup-sessions

  server web01 10.X.X.12:80 send-proxy check alpn h2 #check-alpn http/1.1 send-proxy alpn h2,http1.1
  server web02 10.X.X.14:80 send-proxy check alpn h2 #check-alpn http/1.1 send-proxy alpn h2,http1.1

Then the nginx listen directive is simply
listen 80 http2 proxy_protocol

I’ve tried a number of things with the haproxy backends(alpn h2/http1.1 and proto h2) and am mainly running into 502’s from HAProxy and an error message in nginx stating:
recv() failed (104: Connection reset by peer) while processing HTTP/2 connection, client: 10.X.X.11, server: 0.0.0.0:80

Ultimately i think my question is simple: Can i use one backend for both h2 and http1.1, or should i still use the port routing based on ssl_fc_alpn. I’m trying to gain a better understanding of the new h2 backends and how option http-use-htx works.

One last bit. If i change to send-proxy check alpn h2 to send-proxy check proto h2, it seems to work well with h2 browsers and even when i curl --http1.1 -nvL -o /dev/null https://www.site.com it states that they request was in 1.1, but the nginx logs show its 2.0.

Hopefully this is clear, for older browsers, like IE10, it seems that i’m going to have to use the port redirect, but would love any further clarification.

Thank You,
Jeff

1 Like

I am dealing with this issue as well. And cannot find anything else on the internet about how this should work, and this is the only similar issue I ran into. I am hoping somebody can help us in the right direction!

Possibly it is a bug in nginX. I used the latest nginX 1.17.1. If I configure it as follows:

server {
  listen 8002 default_server proxy_protocol;
  listen 8003 default_server http2 proxy_protocol;
}

And I try to use curl to make a proxy request:

curl --output output.log --http2 --haproxy-protocol http://localhost:8003

I receive the following binary output:

roel@proxy-test:~$ xxd -p output.log2
000012040000000000000300000080000400010000000500ffffff000004
0800000000007fff00000000080700000000000000000000000001

However the 8002 port using HTTP1.1 does work:

curl --haproxy-protocol http://localhost:8002

But this could be due to the curl flag using V1 of proxy protocol. Or maybe the response is correct. I simply do not know what the binary output is meant to say!

Hopefully somebody can help!

My first intent is not to offend, but this has nothing to do with my question. As i’m trying to trim down my configuration to not route to different backends.

That said, i’m thinking you have an issue with something else in your nginx configuration or its curl causing this question as you’re not going through haproxy. Does it work if you do go though haproxy? Are you routing traffic based on alpn as per my original example.

I am sorry that my post wasn’t helpful!

I do think I am having the same troubles you have. Namely that we are both not sure how we can get HaProxy and nginX correctly set-up such that HaProxy will use http mode for http2 traffic as well. So I will watch closely for any answer to pop up.