Users of Google Chrome are seeing some sites that they previously accessed over HTTP/2 falling back to HTTP/1. This is because of a policy change in the most recent update to Chrome, released in late May, which removes support for NPN, one method for upgrading a connection to HTTP/2.
The only way Chrome users can continue using HTTP/2 to access these websites is by switching to a different browser. Website administrators can restore HTTP/2 support for Chrome users by upgrading their OpenSSL installation to the recently released 1.0.2 version. Unfortunately, this requires either a major operating system upgrade or using a private build of NGINX.
What Has Happened?
In the beginning was HTTP/1. HTTP/1 has served us well, but as websites got more and more complex, it began to get a bad rap for being too slow.
To address this, Google developed a new transport layer named SPDY. SPDY was accessed over SSL/TLS, and Google developed an SSL/TLS modification called Next Protocol Negotiation (NPN) that allowed clients to upgrade their SSL/TLS connections from HTTP/1 to HTTP/2. Major web servers (such as NGINX) implemented SPDY; OpenSSL and other SSL/TLS stacks implemented NPN.
SPDY was submitted to the IETF, revised, and released as a new standard called HTTP/2. NPN was similarly revised and released as a new standard called Application-Layer Protocol Negotiation (ALPN). Web servers such as NGINX added HTTP/2 support, and OpenSSL added support for ALPN in version 1.0.2. NPN and ALPN can coexist, and clients and servers that support both will prefer ALPN over NPN.
Google has removed support for SPDY from the latest release of the Chrome web browser (build 51). Fortunately, upgrading a web server to a later version that supports HTTP/2 is relatively easy; a web server is a standalone application with very few tight dependencies.
The more significant issue is that Google has also removed support for NPN from Chrome build 51. If the web server that a user is connecting to supports only NPN (not ALPN), the new Chrome browser drops back to HTTP/1.
This can cause problems for users and site developers. Users are likely to experience slower response times than under HTTP/2—especially at sites with lots of different assets (which benefit from HTTP/2’s multiplexing over a single connection) and when they are accessing the site over a high-latency connection (which worsens the penalties for less efficient connection usage). Site developers have less incentive to upgrade to HTTP/2 and are stuck either leaving their sites optimized for HTTP/1 or optimizing for HTTP/2.
Google has briefly described its reasons for dropping NPN here. Concern was expressed publicly and privately about the change before it was implemented, but Google has now implemented its plans and Chrome no longer supports NPN as of build 51.
Why Has HTTP/2 Stopped Working for Users of the New Version of Google Chrome?
As of May 2016, approximately 8% of the world’s websites were accessible over HTTP/2. These websites all use SSL/TLS, because browsers that support HTTP/2 only upgrade the connection to the new standard if SSL/TLS is also in use. The vast majority of sites—those running NGINX and LiteSpeed—depend on OpenSSL’s implementation of NPN or ALPN to upgrade to HTTP/2.
OpenSSL added ALPN support on January 2015, in version 1.0.2. Versions 1.0.1 and earlier do not support ALPN.
Unlike a standalone web server like NGINX, OpenSSL is a core operating system library that is used by many of the packages shipped as part of a modern Linux operating system. To ensure the operating system is stable and reliable, OS distributors do not make major updates to packages such as OpenSSL during the lifetime of each release. They do backport critical OpenSSL patches to their supported versions to protect their users against vulnerabilities. They do not backport new features, particularly those which change the ABI of essential shared libraries.
The table summarizes operating system support for ALPN and NPN.
|Operating System||OpenSSL Version||ALPN and NPN Support|
|CentOS/Oracle Linux/RHEL 5.10+||0.9.8e||Neither|
|CentOS/Oracle Linux/RHEL 6.5+, 7.0+||1.0.1e||NPN|
|Ubuntu 12.04 LTS||1.0.1||NPN|
|Ubuntu 14.04 LTS||1.0.1f||NPN|
|Ubuntu 16.04 LTS||1.0.2g||ALPN and NPN|
As you can see, only Ubuntu 16.04 LTS supports ALPN. This means that if you’re running your website on any other major operating system, the OpenSSL version shipped with the operating system does not support ALPN and Chrome users will be downgraded to HTTP/1.
What Can You Do?
With recent versions of NGINX, you can verify what version of OpenSSL is in use by running
# nginx -V nginx version: nginx/1.9.13 (nginx-plus-r9) built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.1) built with OpenSSL 1.0.1f 6 Jan 2014
You have three options if providing HTTP/2 to Chrome users is important to you.
- Upgrade your operating system. At the time of this writing, the only major operating system that ships with OpenSSL 1.0.2 is Ubuntu 16.04 LTS. Other vendors are likely to support 1.0.2 (or the forthcoming 1.1.0 release) in their future long-term support releases.
- Recompile NGINX from source and use a private build with OpenSSL 1.0.2. The NGINX sources support OpenSSL 1.0.2 (and the forthcoming 1.1.0 release), so another option is to recompile NGINX from source and link against a private OpenSSL 1.0.2 build by including the
--with-opensslargument. We recommend this only as a temporary solution, however. You are taking on the burden of monitoring OpenSSL for updates and recompiling it every time an important security update is issued. If you obtain NGINX from your OS vendor’s repo or from the official NGINX repo, rather than from a pre-compiled binary distribution, then recompiling NGINX from source on every update is an additional workload.
- Run NGINX in a container. For some deployments, you can put your NGINX web server inside a container that is based on an OS that provides OpenSSL 1.0.2 (at this time, that means Ubuntu 16.04 LTS). This does not require a full operating system upgrade, and but is a sensible option only if you’re already running Docker for your production servers—it’s probably too disruptive if you’re not familiar with Docker.
If your site supports HTTP/2, Chrome users will fall back to HTTP/1 when they update their browser to build 51 (or it’s auto-updated for them). Your options for restoring HTTP/2 support for these users are limited to those described above. If you can’t update your site in the near future, you may need to explain to users what has happened, what their options are (waiting or using another browser), and what your plans for HTTP/2 support are going forward.