Nginx is a robust, fast, reliable and dynamic open-source web server popular for serving high traffic sites. In addition, it is well renowned for its ease of configuration, high scalability, and support for a myriad of protocols.
Among the protocols supported by Nginx is the new HTTP/2 protocol whose main advantage over its predecessor HTTP 1.1 is the high transfer speed required for content-rich websites.
In this guide, we will delve in the installation and setup of a secure Nginx server with HTTP/2 Support:
Prerequisites
To start let’s go through the flight check and see whether we have the following
- A server instance of Ubuntu 18.04 LTS
- Nginx version 1.9.5 or higher (To verify the version of Nginx, run
nginx -v
), read Install Nginx on Ubuntu 18.04. - OpenSSL version 1.0.2 or higher (Check the version using openssl version)
- A regular, non-root user with sudo privileges
- A Fully Qualified Domain Name (FQDN) In this case, we are going to use
crazytechgeek.info
purchased from GoDaddy.The domain name’s A record should point to the IP address of the server. crazytechgeek.info has been pointed to 216.200.116.207.
- An SSL certificate (Either a self-signed certificate or a one from Let’s encrypt SSL. Similarly, you can purchase one form a different provider.
Step 1 – Enabling HTTP /2.0 Support
To start off, it is assumed that you have configured Nginx server block at
/etc/nginx/sites-available/your_domain
In our case, the server block is /etc/nginx/sites-available/crazytechgeek.info
.
Using your favorite text editor, open the server block file and locate the listen
directive as shown
The first directive indicates IPv6 connections while the second one is for IPv4 connections
Now, we are going to modify each directive to include a http2
flag as shown
This is going to instruct Nginx to use HTTP/2 on supported browsers
Save the configuration file and exit your editor.
Next, open /etc/nginx/sites-available/default
file and make the same changes
Save and exit the text editor.
Just to make sure that there are no syntax errors in any of the Nginx files, run the command below
$ sudo nginx -t
Output
Step 2 – Purging Old and insecure Ciphers
For HTTP/2 to work as expected, we must avoid using old and insecure ciphers which have been on the HTTP/2 blacklist. Cipher suites are cryptographic algorithms which dictate how traffic is to be encrypted.
If certbot was used to obtain the certificates, then the ciphers in the path /etc/letsencrypt/options-ssl-nginx.conf
are not secure enough for HTTP/2. However, modification of this file will only cause errors and prevent certbot from applying updates. This means we must specify our list of ciphers and instruct Nginx to ignore the file
Open the configuration file for your Nginx’s domain server block
$ vim /etc/nginx/sites-available/crazytechgeek.info
Comment this line
# include /etc/letsencrypt/options-ssl-nginx.conf;
Below that line, append the line below to define the allowed ciphers
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
Save the file and exit the text editor
If a self-assigned certificate was used, or a third party certificate, then open the file
/etc/nginx/snippets/ssl-params.conf
$ sudo vim /etc/nginx/snippets/ssl-params.conf
Locate the line as shown below
...
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
...
Modify the file accordingly as shown below
...
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
The finally save and exit the configuration file
Once again check for any Nginx configuration errors
$ sudo nginx -t
If all went well, you should see the output below as shown earlier
Restart Nginx
$ sudo systemctl reload nginx
In the next step, we are going to test whether our server can server HTTP/2 pages
Step 3 – Testing If HTTP/2 is enabled
Now let’s test whether HTTP is running and enabled on our Nginx web server
In your terminal, execute the command below
curl -I -L https://your_domain
In our case, it shall be
curl -I -L https://crazytechgeek.info
Output
Alternatively, you can verify HTTP/2 by opening Google developer tools by hitting
Ctrl + Shift + I
Next, click on Network
Tab.
In the Protocol
column, be sure to find the label h2
Step 4 – Deploying HTTP Strict Transport Security
Lastly, even though we know very clearly that our server can redirect HTTP requests to HTTPS, we want to enable HSTS HTTP Strict Transport Security to eliminate such redirects. Should a browser chance upon an HSTS header, it will not try connecting to the server again for a certain duration of time. IT will only exchange data via secure and encrypted HTTPS protocol.
To achieve this, Open the Nginx config file
$ vim /etc/nginx/nginx.conf
Append the line below
add_header Strict-Transport-Security "max-age=15768000" always;
max-age
is set in seconds
If your site has subdomains, and you desire to apply HSTS to all of them, append the includeSubDomains
flag at the end of the line
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
Save and exit from the config file.
As always, check whether there are any errors
$ sudo nginx -t
Finally, restart Nginx
$ sudo systemctl restart nginx
Conclusion
At this point, your Nginx server is now serving HTTP/2 pages.
You can also visit https://tools.keycdn.com/http2-test
to test your site’s HTTP/2 status as shown
Alternatively, you can also visit this site
https://http2.pro/
For more detailed results use
https://www.ssllabs.com/ssltest/