Browser won't upgrade to h2 (HTTP/2) although "Upgrade" headers are sent
Asked Answered
P

3

6

I'm trying to get h2 (HTTP/2) to work on my webserver. Installed Apache 2.4.20 via the "ondrej" repository. I tested on a Debian 8 and Ubuntu 14.04 server, but I keep running into the same problems. I have OpenSSL 1.0.2 and SSL vhosts running.

The strange thing is that the upgrade headers (Connection: upgrade and Upgrade: h2) are sent. When I do some external server testing I get the responses that h2 is running properly with ALPN support. But the problem is the browsers I tested on (Chrome and FireFox on Win7) won't upgrade to h2.

One thing which I noticed which is missing is the HTTP/2-Settings header, but I can't find anything in any Apache documentation to implement this or force Apache to send this header.

Sadly I couldn't test with cUrl, since the servers I have access to don't support any version which has HTTP/2 support.

My SSL vhost settings:

Protocols h2 http/1.1
SSLEngine On
SSLCACertificateFile xxxxxxxx
SSLProtocol all -SSLv2 -SSLv3
SSLCompression Off
SSLHonorCipherOrder On
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RSA+AES RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !AES128"
Header always set Strict-Transport-Security "max-age=15552000;includeSubDomains"
SSLCertificateFile xxxxxxxx
SSLCertificateKeyFile xxxxxxxx

I'm running Apache with the prefork module instead of with workers.

Who can tell me what's wrong?

Pazpaza answered 19/5, 2016 at 11:53 Comment(1)
I had the same symptom after installing mod_http2. In my case, also switching to using php-fpm (as described here: techwombat.com/enable-http2-apache-ubuntu-16-04) solved it for me in the end. Just throwing it out there in case others come this way!Creditable
P
8

In the end I got it to work. It was a matter of changing the "SSLChiperSuite" to this string:

SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-A$

The old one had - so to speak - an option which blocked http2. My SSL test rating is still A+ btw.

Pazpaza answered 24/5, 2016 at 18:57 Comment(0)
D
6

You cannot upgrade to the h2 protocol.

The HTTP/1.1 upgrade mechanism is something that is initiated by clients.

If I understood you correctly, and you're trying to send the Upgrade and the HTTP2-Settings headers from server to client, then that does not make sense. Clients send those headers, not the server.

Furthermore, while the HTTP/2 protocol itself allows for clear-text communication via a HTTP/1.1 upgrade to h2c (note the c at the end of the protocol name), browser vendors have not implemented this mechanism and only use the HTTP/2 protocol after ALPN negotiation.

In summary:

  • You can upgrade from HTTP/1.1 to HTTP/2 clear text (h2c), but only with non-browser clients such as nghttp. This is explained here.
  • The upgrade mechanism is initiated only by clients, and they will send the Upgrade and HTTP2-Settings headers, not the server.
  • Browsers only support negotiation of HTTP/2 via ALPN (h2). This means that you cannot have clear-text HTTP/2 between a browser and a server.
Durable answered 19/5, 2016 at 13:22 Comment(2)
Thx, but I never mentioned h2c and I'm not trying to get that to work. Besides that, you misunderstood the part about the headers, nevermind.Pazpaza
What you did mention and emphasize, in question title and body, was having upgrade headers. sbordet is right to indicate that upgrade is for cleartext only, but he probably isn't aware that some clients may send those headers for h2. Only inasmuch that the headers indicate the browser is attempting h2, is it informative. Servers are specified to ignore "Upgrade: h2", precisely because HTTP/2 is to be negotiated via ALPN on secure connections. So this explains your "strange thing". The upgrade headers show the browser's intent, but they don't really do anything for secured HTTP/2.Moffett
K
3

prefork

You mentioned, that you use prefork mpm. The Apache webserver will not use HTTP/2 if configured with the prefork mpm, it will default back to HTTP 1.1.

*"Disable and give warning when mpm_prefork is encountered. The server will 
continue to work, but HTTP/2 will no longer be negotiated."* ([Apache Revision 
: SECURITY: CVE-2017-9789: Read after free in mod_http2.][1])

While this may have worked at the time the question is asked, this will not work currently. Use a different mpm or switch to php-pm and worker or event.


HTTPS

As already mentioned in one of the answers, encryption can be an issue. The server should be configured correctly for HTTPS and requests should be served over HTTPS.


More information

Kella answered 8/1, 2019 at 16:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.