Chrome needs ALPN to use HTTP/2, ALPN needs OpenSSL 1.0.2, RedHat will only ship OpenSSL 1.0.1 on RHEL 7, and nginx uses the OpenSSL provided by the system. Here’s the solution to this mess!
UPDATE 2: The module ngx_brotli from eustas was added to the build to provide Brotli compression support. It is a fork from the original ngx_brotli from Google, with changes to build with recent nginx versions. Take a look into the Brotli announcement to understand how it may help your pages load faster.
UPDATE: EL7 was updated to OpenSSL 1.0.2 with the release of EL7.4, which provides proper ALPN support, and therefore there’s ALPN support out-of-the-box now on EL7. However, I will continue to be providing packages for EL7 if someone wants to keep using a built-in OpenSSL from the most recent stable branch. The situation with EL6 remains unchanged and it still needs custom packages to provide ALPN support.
TL;DR: Paste this (if you trust me) in your EL7 or EL6 system:
- Current nginx version: 1.15.4
- Current OpenSSL version: 1.1.1
Now, let me explain the situation a little bit. Google defined that after Chrome 51, released on May 31st of 2016, HTTP/2 connections would only be negotiated trough Application-Layer Protocol Negotiation (ALPN) instead of the Next Protocol Negotiation (NPN) used so far in TLS-enabled HTTP streams. The new protocol is great because it avoids some additional trips over the wire to negotiate the security parameters, reducing latency, but it needs to be supported on the server side.
Because of the Heartbleed vulnerability, RedHat is no longer doing backports of OpenSSL and other crucial packages, since on the original version of OpenSSL that was shipped with RHEL6 there was no presence of this vulnerability, but it was later introduced because of a stable backport. This creates the whole problem.
RHEL7 shipped with OpenSSL 1.0.1, and RedHat has no plans to update it - as per this RFE ticket - until RHEL8, which is only scheduled to be launched on 2018. That’s two more years without ALPN support.
Therefore, neither Apache httpd nor nginx packages shipped on either the official RedHat repos, the Fedora EL repos nor even the packages available in the Apache and nginx own Yum repos are able to support ALPN, since they all use the OpenSSL dynamic library available on the target system.
Replacing only the OpenSSL package for a more recent version is not an option, since that would introduce an ABI incoherence between the library available on the system and the one that the applications expect. The application also needs to be rebuilt.
The good news is that since we need to rebuild the application anyway, we can easily instruct it to use a different OpenSSL library, but this comes with a whole new bag of problems: you need to keep track of both the OpenSSL and the application (nginx or Apache httpd) security bulletins, besides having to either create a new Yum repository yourself or building the packages in every system you manage.
As such, I decided to build those packages and make it available to the community, and the packagecloud team was happy to host them.
The packages available at packagecloud are distributed either trough direct download, or trough a GPG-signed Yum repository. Also, I always sign the packages themselves with my own GPG key. Therefore, if you trust me, you can be certain that the package is safe.
Basically the script on the top of this post will do the following:
- Ensure curl, sed and pygpgme are installed
- Create a repository config for this repo on
/etc/yum.repos.d
- Install the packagecloud and my own GPG keys on the RPM keyring
Note that this nginx package has a built-in OpenSSL library, and will in no way touch your OpenSSL library already present on the system. Also, the script will not install nginx by itself, since nginx is modular, and you may or may not want to also install its modules.
In order to build those packages, I’ve written some Docker recipes for EL7 and EL6, which are fit for either RHEL or CentOS, and those recipes are also open to scrutiny at GitHub.
I’ve also modified the default packagecloud Yum repo install script to also include the installation of my public GPG key, to ensure extra protection against unauthorized modifications on the package.
I vow to keep this repository updated until the EOL of RHEL7 and RHEL6.
If you liked this, drop me a line in the comments and star the repo on Github!