HTTP/2 h2 with no ALPN support in server
Asked Answered
C

2

6

After reading both HTTP/2 RFC (#7540) and TLS-ALPN RFC (#7301), I'm still unable to figure out the expected behavior when ALPN is lacking in one end.

Assuming I have a client that uses HTTP/2 "h2" (over TLS) that talks to a server that support HTTP/2 but does not send the ALPN extension in the "server hello". What is the expected behavior from the client?

Most clients I've seen so far consider that HTTP/2 is not supported by the server and downgrade the connection to http/1.1, but few ignore (go-gRPC) continue with HTTP/2.

This scenario can be more practical if using AWS classic LB that does SSL termination between a client ("h2") to the server ("h2c"). In this example, the client sends the ALPN extension with value of "h2", the LB performs SSL handshake without ALPN (as expected from his part), and eventually the JAVA gRPC fails due to HTTP/1.1 downgrade.

Clute answered 11/12, 2017 at 18:0 Comment(0)
M
3

To answer the question, without alpn, but using npn, still can support grpc.

Two clarification,

  1. http2 negotiation for grpc can happen either thru alpn or npn. If alpn is supported in client, it sends alpn extension as well as npn extension in Client Hello. If alpn is supported in server, server only responds with alpn with h2. If alpn not supported and npn is configuration in 'server LB config' it will send npn and h2. What i noticed in haproxy and nginx if you dont configure alpn, it does not default to npn unless configured.
  2. grpc client insists on h2. If neither alpn, nor npn with h2 happed, client will disconnect as it assumes h2 is not suppored, and h2 is mandatory for grpc
Molloy answered 29/11, 2018 at 10:57 Comment(0)
S
1

It depends entirely on the client and server. Many still support the older NPN TLS extension for SPDY and HTTP/2 Support, though officially the spec says to use ALPN only.

On the browser side, for example, Chrome, Firefox and Opera now only support HTTP/2 over ALPN though they all used to support it over NPN. At the time of writing Safari, IE and Edge still allow either NPN or ALPN to be used.

On the server side some (e.g. Nginx) Support both, while some (e.g. Apache) only Support ALPN.

I would also question the terminology of “downgrade”. The ALPN extension is a request to use h2 and happens as part of the TLS negotiation before a single HTTP message has been sent. So it’s not really a downgrade anymore than an unsuccessful upgrade request.

Submission answered 11/12, 2017 at 19:22 Comment(8)
IMHO ALPN extension is optional in the TLS negotiation. What I’ve seen so far is that when the server response with “server hello” that doesn’t contain ALPN, the handshake finish successfully, and (usually) the client sends encrypted http/1.1 data.Clute
My question is actually regarding the spec, I would like to know if this is the accepted behavior or whether it is written in the RFC (I didn't find) that when the server is missing the ALPN extension, the client default is to select http/1.1Clute
Correct. It is optional. Just like TLSv1.2 Support is optional. A client that doesn’t support TLSv1.2 doesn’t get “downgraded” to TLSv1.0 - it never started on TLSv1.2 in the first place! And if a server only supports TLSv1.2 then the client doesn’t get to connect.Submission
In my opinion the spec is quite clear. To use HTTP/2 over HTTPS (h2) ALPN must be used: tools.ietf.org/html/rfc7540#section-3.3. Without ALPN support you cannot use HTTP/2 over HTTPS (though as I say currently some clients and servers still allow ALPN’s predecessor NPN to be used). Therefore you are left with HTTP/1.1, 1.0 or even 0.9 (shudder). The other methods to negotiate HTTP/2 (“upgrade” or “prior knowledge”) are explicitly marked in the HTTP/2 spec as for non-secure HTTP connections only.Submission
I accept your comment. Any thoughts on the exampled scenario of AWS CLB as SSL termination?Clute
I don’t fully get the scenario. So the LB doesn’t support ALPN but you still want to support HTTP/2 over HTTPS? Well that’s basically not possible - at least for some clients. And even if it did support ALPN and HTTP/2 for incoming connections, it may not support HTTP/2 for outgoing backend connections (many load balancer don’t). The only option I can see is to remove SSL/TLS offloading from the load balance and to change your load balancer to be a level 4 TCP load balancer. That way the end machine’s can do the SSL/TLS negotiating.Submission
Exactly. If I configure the LB to be Transparent TCP and the SSL is terminated in my server, the result is satisfying. However, It make more sense for me in microservice environment to hold the certificate and terminate the SSL at the entrance, I.e., LB. I would expect that AWS will give a flag to set this ALPN option. Until then, there will be no complete support for HTTP/2Clute
Agreed. Moan at AWS to support HTTP/2 properly :-) But as I said ALPN is only one part of it. The other part (needed for gRPC) is to allow HTTP/2 from load balancer to your server (either h2 or h2c) which I don’t think they do yet either.Submission

© 2022 - 2024 — McMap. All rights reserved.