NGINX Full Version

为网站访客支持 HTTP/2

[Editor – This post has been updated to reflect changes to browser support for NPN and to OS support for ALPN since the original publication in June 2016 as “Supporting HTTP/2 for Google Chrome Users”. The information is current as of September 2017.]

Users of several major web browsers are finding that sites that they previously accessed over HTTP/2 have fallen back to HTTP/1. The main reason is that browser vendors have stopped supporting one of the two common methods for upgrading a connection to HTTP/2 – Next Protocol Negotiation, or NPN – in recent versions of their browsers. As of mid‑2017, among the most popular browsers only Safari 10 still supported NPN (see What Has Happened?).

To enable visitors to access your website over HTTP/2, you need to upgrade your OpenSSL installation to version 1.0.2 or later, which supports the other method for upgrading connections to HTTP/2, Application‑Layer Protocol Negotiation (ALPN). Unfortunately, this requires that you either upgrade the operating system on your NGINX and NGINX Plus servers, or use a private build of NGINX. See What Can You Do?

Why HTTP/2?

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, early in this decade Google developed a new transport layer named SPDY. SPDY required that connections be protected by SSL/TLS, and Google developed Next Protocol Negotiation (NPN) as an extension to SSL/TLS that enables clients to upgrade their SSL/TLS connections from HTTP/1 to HTTP/2. Major web servers (such as NGINX and NGINX Plus) 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 added HTTP/2 support, and in January 2015 OpenSSL added support for ALPN in version 1.0.2. NPN and ALPN can coexist, and clients and servers that support both prefer ALPN over NPN.

While HTTP/2 is not a silver bullet, users are likely to experience faster response times than over TLS‑encrypted HTTP/1 – especially for 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).

As of mid‑2017, more than 15% of the world’s websites were accessible over HTTP/2 (nearly double the percentage when this post was originally published in May 2016).

What Has Happened?

In May 2016, Google released Chrome build 51, eliminating support for SPDY and NPN in favor of HTTP/2 and ALPN. Although concern was expressed publicly and privately about the negative consequences before the change was made, Google went ahead, providing a brief explanation of its reasons for dropping NPN.

At that time Chrome was the only major browser that didn’t support NPN, so users could regain HTTP/2 access by switching to another browser. However, by mid‑2017 all of the most popular browser vendors except Safari (version 10) had dropped support for NPN, starting with the following versions (see the Protocol Details section on the page for each browser at Qualys SSL Labs):

Now the onus has fallen completely on website administrators to enable their visitors to access a website over HTTP/2. Fortunately, it is relatively easy to upgrade web server software to a version that supports HTTP/2; a web server is a standalone application with very few tight dependencies. NGINX and NGINX Plus have supported HTTP/2 since September 2015 (starting in NGINX 1.9.5 and NGINX Plus R7).

The more significant challenge is that the operating system underlying the web server must provide a version of OpenSSL that supports ALPN. As previously mentioned, that is OpenSSL 1.0.2 or later.

Unlike a standalone web server like NGINX and NGINX Plus, 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 of OpenSSL to protect their users against OpenSSL vulnerabilities. They do not backport new features, particularly those which change the ABI of essential shared libraries.

The table summarizes Linux operating system support for ALPN and NPN as of September 2017.

Operating System OpenSSL Version ALPN/NPN Support
CentOS/Oracle Linux/RHEL 6.5+, 7.0–7.3 1.0.1e NPN
CentOS/Oracle Linux/RHEL 7.4+ 1.0.2k ALPN and NPN
Debian 7.0 1.0.1e NPN
Debian 8.0 1.0.1k NPN
Debian 9.0 1.1.0f ALPN and 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

What Can You Do?

You can verify what version of OpenSSL is in use by running nginx -V:

# nginx -V
nginx version: nginx/1.11.10 (nginx-plus-r12-p3)
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
built with OpenSSL 1.0.2g  1 Mar 2016
TLS SNI support enabled

You have three options if you want to enable your website visitors to access the site over HTTP/2:

  1. Upgrade your operating system

    As shown in the table, some operating system distros ship with OpenSSL versions that support ALPN. Other vendors are likely to support ALPN in their future long‑term‑support releases.

  2. Recompile NGINX from source and use a private build with OpenSSL 1.0.2 or later

    The NGINX sources support OpenSSL 1.0.2 and later, so another option is to recompile NGINX from source and link against a private OpenSSL build by including the --with-openssl argument. (This is not an option for NGINX Plus.)

    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 precompiled binary distribution, then recompiling NGINX from source on every update is an additional workload.

  3. Run NGINX or NGINX Plus in a container

    For some deployments you can put your NGINX or NGINX Plus web server inside a container that is based on an OS that provides OpenSSL 1.0.2 or later. This does not require a full operating system upgrade, but is a sensible option only if you’re already running Docker or another container for your production servers – it’s probably too disruptive if you’re not familiar with containers.

Conclusion

If your site supports HTTP/2 and you are using an older version of OpenSSL with NGINX, most visitors will fall back to encrypted (TLS) HTTP/1 when they update their browser to a recent version (or it’s auto‑updated for them). Your options for restoring HTTP/2 support for these users are limited to those described above.