How to Enable HTTP2 Protocol with Nginx on Debian 8 Jessie Server
This tutorial will be showing you how to enable HTTP/2 protocol with Nginx on a Debian 8 server to speed up web page loading. There are 2 requirements.
- Nginx version 1.9.5 or above, built with OpenSSL 1.0.2
- HTTPS enabled
Let’s tackle these one by one.
Installing Nginx from Jessie Backports Repo
ALPN (Application Layer Protocol Negotiation) is a TLS extension that allows servers to negotiate HTTP/2 protocol with web browsers. Without ALPN, HTTP/2 connection can not be established, even if both web server and web browser support HTTP/2. The OpenSSL library supports ALPN stating with version 1.0.2.
Debian 8 has OpenSSL 1.0.1. To check your OpenSSL version, run
openssl version
Please note that there’s no need to install OpenSSL 1.0.2 on the system. We only need Nginx 1.9.5 or above that’s built with OpenSSL 1.0.2. Nginx added support for HTTP/2 in version 1.9.5. The default Debian 8 repo has Nginx 1.6.2. Fortunately, Jessie backports repo provides Nginx 1.10.3 built with OpenSSL 1.0.2l.
To add this repository, create a source list file.
sudo nano /etc/apt/sources.list.d/jessie-backports.list
Add the following line to this file.
deb http://ftp.debian.org/debian jessie-backports main
Save and close the file. Then update package index and install Nginx from Jessie backports repository.
sudo apt update sudo apt -t jessie-backports install nginx
Check Nginx version and configure parameters.
sudo nginx -V
Output:
nginx version: nginx/1.10.3 built with OpenSSL 1.0.2l 25 May 2017 TLS SNI support enabled
Nginx.org repo contains the latest version of Nginx for Debian 8. But that package is built against OpenSSL 1.0.1, so it doesn’t support ALPN.
Installing SSL Certificate on Debian 8
We can install a free SSL certificated issued by Let’s Encrypt. First, install Let’s Encrypt client (Certbot) on Debian 8 from Jessie Backports repo. Python-certbot-nginx
is the Nginx plugin for Certbot.
sudo apt install -t jessie-backports certbot python-certbot-nginx
Now if you have configured a Nginx virtual host, then use Nginx plugin to obtain and install SSL certificate like below
sudo certbot --nginx --agree-tos -d example.com --redirect --staple-ocsp --must-staple --email your-email-address
Explanation:
--nginx
: Use Nginx plugin--agree-tos
: Agree to Let’s Encrypt terms of service--redirect
: Automatically redirect all HTTP traffic to HTTPS for the newly authenticated vhost.--staple-ocsp
: Enables OCSP Stapling--must-staple
: Adds the OCSP Must Staple extension to the certificate--email
: Email used for registration and recovery contact
Enabling HTTP2 Protocol
By default, Certbot doesn’t configure HTTP/2 for Nginx. To enable HTTP/2, edit your Nginx virtual host file. Find the following directive.
listen 443 ssl;
Then add http2 like below.
listen 443 ssl http2;
Save and close the file. Reload Nginx.
sudo systemctl reload nginx
Test
How do you know your site is actually using HTTP2 protocol?
- In Firefox or Google Chrome, load a page of your site, then press
Ctrl+Shift+I
to open Developer Tools, click the Network tab. You can see the protocol being used for your domain. - You can also install the HTTP/2 and SPDY Indicator extension in Google Chrome.
- Install the HTTP/2 Indicator extension in Firefox.
- The online HTTP/2 test tool by KeyCDN can tell you if HTTP/2 and ALPN is supported on your site.
Note that you may need to clear your browser’s cache because cached objects may be mistakenly marked with HTTP/1.1 protocol.
How to Enable Server Push
HTTP/2 comes with a feature called server push, which allows web server to send resources that the web browser didn’t ask for, but is needed for loading web pages. For example, if web browser requests an HTML document, then the web server knows that the client will need the associated CSS file and send it along with HTML document, thus eliminating the need for web browser to send the request for CSS, so one round trip is reduced.
Here, I use WordPress as an example. The following resources are commonly needed for WordPress site.
- style.css: the main stylesheet, located in the root of theme directory.
- jquery.js: JQuery libary
- jquery-migrate.min.js: the old JQuery
- wp-embed.min.js: for embedding videos
To push these resources to clients, add the following directives in server
block. Replace twentyseventeen with your own WordPress theme name.
http2_push /wp-content/themes/twentyseventeen/style.css;
http2_push /wp-includes/js/jquery/jquery.js;
http2_push /wp-includes/js/jquery/jquery-migrate.min.js;
http2_push /wp-includes/js/wp-embed.min.js;
Save and close the file. Then restart Nginx for the changes to take effect.
sudo systemctl restart nginx
Note that you need to add the following code in functions.php
file to remove the version number from WordPress CSS and JavaScript files. When WordPress updates, server push won’t work if version number is added to these files.
// Remove WP Version From Styles add_filter( 'style_loader_src', 'sdt_remove_ver_css_js', 9999 ); // Remove WP Version From Scripts add_filter( 'script_loader_src', 'sdt_remove_ver_css_js', 9999 ); // Function to remove version numbers function sdt_remove_ver_css_js( $src ) { if ( strpos( $src, 'ver=' ) ) $src = remove_query_arg( 'ver', $src ); return $src; }
Testing Server Push
In Google Chrome browser, load your page, then press Ctrl+Shift+I
to open developer tools and click Network tab. Press F5 to reload. As you can see from the screen shot below, server push is working on one of my websites. If you see “from memory cache”, then right-click on it, clear browser cache and reload.
Improvements
The Certbot Nginx plugin is still not mature. I got B on SSL Labs test after using Nginx plugin because of the use of weak key exchange parameters. The Mozilla SSL configuration generator is a good tool to help you create modern SSL configurations.
That’s it! I hope this tutorial helped you enable HTTP/2 with Nginx on Debian 8 server. As always, if you found this post useful, then subscribe to our free newsletter.