Table of Contents
Was this article helpful?

0  out of  1 found this helpful

Try Vultr Today with

$50 Free on Us!

Want to contribute?

You could earn up to $600 by adding new articles.

Enable HTTP/2 in Nginx on Ubuntu 16.04

Last Updated: Thu, Jun 9, 2016
Linux Guides System Admin Ubuntu Web Servers
Archived content

This article is outdated and may not work correctly for current operating systems or software.

HTTP/2 is the new version of now obsolete HTTP/1.1 protocol which was standardized way back in 1999. A lot has changed on the web since then. Our applications are more complex than they were back than, so to cope with that, change in the underlying transport protocol was necessary. The most important thing about HTTP/2 is that it will make your web page faster for the end users.

In brief HTTP/2 adds 5 key features:

  • Single, persistent connection

  • Multiplexing

  • Header compression

  • Resource prioritization

  • Secures transport layer (only valid for browsers)

Explaining all these features is out of the scope of this tutorial but if you want to dig deeper into this topic I can recommend excerpt from High Performance Browser Networking book - HTTP/2 excerpt.

In this guide we are going to install latest stable version of Nginx on Ubuntu 16.04 (Xenial), generate self-signed SSL Certificate, enable HTTP/2 protocol in Nginx and install text based browser elinks to act as HTTP client.

Install Nginx

To install latest stable version of Nginx we need to issue quite a few commands:

  1. We need to download Nginx public PGP key used for signing packages and repositories and add it into the keyring used by the package manager to verify the authenticity of packages downloaded from the repository.

    wget && apt-key add nginx_signing.key
  2. Delete the PGP key from the file system:

    rm nginx_signing.key
  3. Add new repository

    printf "deb xenial nginx \ndeb-src xenial nginx \n" >> /etc/apt/sources.list.d/nginx.list
  4. Update your package list and install Nginx:

    apt update && apt install nginx -y
  5. To verify Nginx version we can use the following:

    nginx -v 
    # nginx version: nginx/1.10.1

    If all goes well you should see pattern like 1.10.x in the output when running nginx -v command.

Self-signed certificate and HTTP/2

Although HTTP/2 spec doesn’t force browsers to implement HTTP/2 over TLS, all major browsers decided to only implement HTTP/2 over TLS, but not any TLS version, only TLS 1.2 or higher.

We are going to create self-signed certs for fictional domain, for production you need valid domain and use trusted CA.

  1. Generate private key:

    openssl genrsa -aes128 -out 2048

    After running this command you will need to enter passphrase 2 times. Because passphrases are annoying we are going to remove it.

  2. Remove passphrase from private key:

    openssl rsa -in -out
  3. Generate Certificate Signing Request (CSR):

    openssl req -new -sha256 -key -out cert-request.csr 

    We are creating single-domain certificate so we need to set common-name field equal to domain

  4. Create certificate:

    openssl x509 -req -days 365 -in cert-request.csr -signkey -out
  5. Sort out certificate and private key:

    mkdir -p /etc/ssl/testing/private && mkdir /etc/ssl/testing/certs
    mv /etc/ssl/testing/private && mv /etc/ssl/testing/certs
  6. Make nginx virtual host directories

    mkdir /etc/nginx/sites-available && mkdir /etc/nginx/sites-enabled
  7. Then run nano /etc/nginx/nginx.conf and find a directive include /etc/nginx/conf.d/*.conf;. Below this directive add include /etc/nginx/sites-enabled/*; Save (CTRL+O) and then quit (CTRL+X).

    # Virtual Hosts
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
  8. Create a file called inside /etc/nginx/sites-available directory with this command nano /etc/nginx/sites-available/ and copy/paste the following code:

    server {
        listen 80;
        listen [::]:80;
        return 301 https://$host$request_uri;
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        root /var/www/html;
        index index.nginx-debian.html;
        ssl_certificate /etc/ssl/testing/certs/;
        ssl_certificate_key /etc/ssl/testing/private/;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

    Congratulations, you now have HTTP/2 enabled web server. Adding http2 parameter to the listen directive inside HTTPS virtual host will give you HTTP/2 support.

  9. Create a symbolic link for /etc/nginx/sites-available/ with this command:

    ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled
  10. Test configuration syntax

    nginx -t
  11. Restart Nginx to apply your changes:

    systemctl restart nginx
  12. Add domain to /etc/hosts file

    echo '' >> /etc/hosts

To test your virtual host we need text-based browser - elinks.

  1. To install elinks use the following command:

    apt install elinks
  2. To test your virtual host run:

  3. To exit out of the elinks browser press q on your keyboard and then Enter.

Test HTTP/2

To see what protocols server advertises the easiest way is to use openssl toolkit.

    openssl s_client -connect -nextprotoneg ''

In the output of this command you should see something like this:


    Protocols advertised by server: h2, http/1.1      

To see HTTP/2 in action you can use browser developer tools. HTTP/2 protocol is indicated either with h2 or HTTP/2.0 identifiers. Open network panel in dev-tools and refresh your page.


Now you should be aware of how "easy" is to enable HTTP/2 in Nginx configuration, but that is not the whole part of the overall picture. First you should think about enabling TLS/SSL on your server with strong cipher suites and make sure you are not using blacklisted ciphers. Only after enabling strong TLS/SSL on your server, you can start thinking about enabling HTTP/2.

Want to contribute?

You could earn up to $600 by adding new articles.