Official Power Up Hosting Blog

Everything about Linux, Windows, and hosting ;)

Selvakumar
Author

I am an Online Marketer and technology lover. I like to learn new things and share that with people.

Share


Our Newsletter


Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Tags


Twitter


Official Power Up Hosting Blog

(10 Steps) Setup Nginx with HTTP/2 support on Ubuntu 16.04

SelvakumarSelvakumar

Nginx is a reliable and fast web server. The usage of the Nginx has been rapidly growing in the last 5 years due to the support and ability to handle the high load without slowing down the system.

They have a lot of advantages and below are few of them.

  • Easy to configure
  • Ability to scale at heavy load
  • consumes less memory to function
  • Support for multiple protocols

The HTTP/1.0 has released a long ago and widely used by all. It is still working well, but we have one main problem with that.

We will discuss the issue shortly.

The HTTP/2.0 is the latest version of protocol which has been released on 2015.

It has a big advantage which resolves the issue with the HTTP/1.0.

The Problem with HTTP/1.0

The all web page requests are made as queue and processed according to the order.

So, if a client request for a web page, the server will send the files one by one.

The second file will be sent only after the first is downloaded by the client.

It takes a lot of time to complete the downloading process.

It is ok with the normal small web pages.

But:

The bigger web pages will require sending a lot of requests.

This will make the client wait for all the requests to be delivered.

The Solution by HTTP/2.0

The HTTP/2.0 requests are made simultaneously and there is no queue while serving the request.

This saves a lot of time and all the available files will be downloaded without waiting for the each other to be downloaded in an order.

Also, the server won't wait for the client to send the requests for next file.

Rather it sends the data to the client, so that client can receive it without any delay.

This is very helpful while sending the data to a client which often faces the latency issue.

Also, the data are transferred as the binary data instead of being sent as files.

This enables the simultaneous data transfer.

The HTTP headers also compressed before sending.

Prerequisites

In this tutorial, we will go through the following steps.

  • Installing Latest version of Nginx.
  • Make the Nginx to Listen on HTTP port 80.
  • Adding the SSL certificate.
  • Enhancing the Security.
  • Redirecting HTTP to HTTPS.
  • Optimizing the Nginx.

Install the Latest version of Nginx from Ubuntu Repository

First, you have to install the latest version of Nginx. The HTTP/2 has introduced on Nginx 1.9.5.

But:

We have a recent version of Nginx in the Ubuntu repository. All you have to do is just update the repository and install the Nginx.

$ sudo apt-get update

Now, install the Nginx

$ sudo apt-get install nginx

After that, check the version of Nginx

$ sudo nginx -v

You will get an output like the below.

Ouput:

nginx version: nginx/1.10.0 (Ubuntu)

After this, we will change the Nginx configuration to make it support the HTTP/2.

We will change the listening port in ufw.

Changing the port

First, you have to change the listening port from port 80 to port 443.

$ sudo nano /etc/nginx/sites-available/default

The configuration file will open. In that, you have to change the default port from 80 to port 443.

     /etc/nginx/sites-available/default
listen 80 default_server;
listen [::]:80 default_server;

You can notice that there are two listening variables.

One is for ipv4 and another is for ipv6.

We will change the both of the port to port 443 for HTTPS connections.

Replace the above lines with the below lines.

       /etc/nginx/sites-available/default
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;

Here, we have added more one more thing. That is http2. So, the Nginx will use the http2 for the supported browsers.

Changing the Server Name

You have to change the server name to a specific domain name in the configuration file.

It is because the configuration file is responsible for handling all the incoming requests.

So, in order to serve the requests, you will need to set the domain name.

First, Look for the server name in the configuration file.

         /etc/nginx/sites-available/default
server_name mydomain.com;

Replace the mydomain.com with your domain name.

After that, save and close the file. Then check for the syntax error.

$ sudo nginx -t

If there is no syntax error, you will get the following output.

Output of sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

SSL certificate integration with Nginx

Once you generated the SSL certificate, your next task is to place the SSL certificate in the Nginx server.

Then only the web server will use the SSL to encrypt the traffic.

For openssl alpn support, install OpenSSL version of 1.0.2 or later.

You don't need to worry about the nginx http2 proxy when using SSL. It won't affect the performance anyway.

First, you have to create a directory to store the SSL certificate in the Nginx directory.

$ sudo mkdir /etc/nginx/ssl

After that, you have to move the SSL certificate and key to the newly created folder.

Then, you have to change the name of the certificate and key value file name to your domain name.

This will be helpful when you have more than one domain on your web server.

$sudo cp /path/to/your/certificate.crt /etc/nginx/ssl/mydomain.com.crt
$sudo cp /path/to/your/private.key /etc/nginx/ssl/mydomain.com.key

The next task is to add the SSL certificate location in the server block.

First, open the Nginx configuration file.

$ sudo nano /etc/nginx/sites-available/default

Now:

Add the below lines in the configuration file to indicate the SSL certificate location.

        /etc/nginx/sites-available/default
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

Save and exit from the file.

Skipping the old Cyphers

HTTP/2 has a huge list of old ciphers which are blocked.

The reason is that a lot of them are outdated and people found the way to decrypt them.

So, here we will use a strong cipher set which is approved by the cloud flare.

The cipher does not allow the MD5 encryption technique as they are being insecure for a long time.

But:

It is still used by many. However, we won't use it.

Open the Nginx configuration file using the following command.

$ sudo nano /etc/nginx/nginx.conf

Add the line after ssl_prefer_server_ciphers on;

/etc/nginx/nginx.conf
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

Save and close the file.

After that, check for the syntax errors.

$ sudo nginx -t

Increase the Security before the key exchange

To decrypt the traffic between the client and server, you have to exchange the private key between them.

When we transact the key, the traffic will be still visible.

This is not safe. To transact the key we will use a secure algorithm which is called Diffie-Hellman Merkel algorithm.

Explaining this article here will distract the focus. So, if you want to know, how the algorithm is working, you can just refer it here.

Nginx also using the DHE. Since it is 1028 bit, still it can be easily decrypted.

So, we will generate the strong key on our own.

Execute the below command to generate 2048 bit encryption key.

$ sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

The above command will store the generated key in the SSL directory.

It is because the Nginx server will look for user-generated key in the SSL directory.

If you have generated any key, it will use it.

This gives enough security. But, if you want more security than that, you can generate the strong values by changing the key, length from 2048 to 4096.

It is almost impossible to break.

It will take more than 5 minutes to generate the key.

After the key generation, you have to add a line in the Nginx server configuration file to indicate the key location.

$ sudo nano /etc/nginx/sites-available/default

Add the following line in the configuration file.

          /etc/nginx/sites-available/default
ssl_dhparam  /etc/nginx/ssl/dhparam.pem;

Redirecting the HTTP request to HTTPS

Your server will get the request for unencrypted connection, but you should not connect using the HTTP.

To upgrade the connection to the server, we will use nginx http2 alpn for enabling the HTTP/2 connection.

Here is the referance guide for nginx alpn support

To improve the security, you have to redirect the request from HTTP to HTTPS.

For that, we will add the instruction code at the end of the server configuration file.

   /etc/nginx/sites-available/default
server {
   listen         80;
   listen    [::]:80;
   server_name    example.com;
   return         301 
https://$server_name$request_uri;
}

Just, save the file and close it. Check for the syntaxusing the below command.

$ sudo nginx -t

If no error, just proceed.

Reaload the Nginx

Once you have made all changes, now its time to reload the Nginx server.

If you make all changes as mentioned above, the now the server configuration blocks will look like the following.

/etc/nginx/sites-available/default
server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name example.com;

    location / {
            try_files $uri $uri/ =404;
    }

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
}


server {
   listen         80;
   listen    [::]:80;
   server_name    example.com;
   return         301 https://$server_name$request_uri;
}

Now restart the Nginx server.

$ sudo systemctl restart nginx

Check the HTTP/2 in your browser.

Once you configured the Nginx server to use HTTP/2, its time to check whether it works perfectly.

First, open the website in your browser and go to the following settings.

View -> Developer -> Developer Tools

Then reload the page by going through

View -> Reload This Page

After that, go to Network Tab. There right click on the file name and then select the protocol.

Now, the protocol type will be displayed as 'h2'.

We can confirm that our web server is using the HTTP/2 protocol.

But:

We have to do some more changes in order to speed up the server and client communication.

Optimizing the Nginx

We will enable the session caching in the Nginx server configuration file.

Use the below command to open the Nginx server configuration file.

$ sudo nano /etc/nginx/nginx.conf

Enabling the caching in Nginx

The HTTPS protocol takes more time than HTTP to establish the connection with the client.

This is because the client has to request the connection credentials each time.

To avoid this, we will enable the credentials caching.

Instead of requesting the credentials each time, the existing cached credentials will be used to authenticate the connection.

Add the following lines in the Nginx server configuration.

              /etc/nginx/nginx.conf
ssl_session_cache shared:SSL:5m;
ssl_session_timeout 1h;

The ssl_session_cache indicates the size of the cache that will be used in to store the session information.

The default cache memory is 5 MB. Even 1 MB of session management can store 4000 session information. So, the default cache memory size is high enough.

Enabling the HSTS

We have already enabled the HTTPS for the connections. But, we also need to enable the HTTP strict transport policy.

Once the browser reads the HSTS header, it will only establish the connection with the server using HTTPS.

The browser won't use the HTTP in such cases. It will avoid all the redirections.

Add the following line in the Nginx server configuration file.

$ /etc/nginx/nginx.conf
add_header Strict-Transport-Security "max-age=15768000" always;

The max age is in seconds. It represents six months.

This is only for domains and not applicable for subdomains.

If you want to set this for the subdomain, just add the 'includeSubDomains' at the end of the line as follows.

/etc/nginx/nginx.conf
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

Save and close the file and then exit the editor.

Now, check the configuration for the syntax errors.

$ sudo nginx -t

If there is no error, then restart the Nginx server.

$ sudo systemctl restart nginx

Conclusion

Now, you have learned how to setup the Nginx server to use HTTP/2.

Also, you have implemented the SSL certificate for the Nginx server to use.

Follow the guide accordingly, then you won't get nginx http 2 not working issue.

Your server security and site loading speed also will be improved.

If you have any doubt in the execution, let us know that in the comment section, we will help you.

Also, signup for the upcoming tutorials.

Selvakumar
Author

Selvakumar

I am an Online Marketer and technology lover. I like to learn new things and share that with people.

Comments