How to setup SSL termination with Nginx

– How do I enable SSL on my website which was setup using Nginx?

As part of my series of tutorials on Nginx, its time to learn “how to install SSL using Nginx“. It is assumed that you already have your SSL certificate, if not, you can generate a free SSL certificate by following this tutorial which makes use of LetsEncrypt.

Installing SSL using Nginx

  1. Edit the SSL configuration file
    Here is a sample config file that you can make use of.
server {
   listen 80;
        return 301 https://$host$request_uri;

# SSL configuration
server {
   listen 443 ssl default deferred;
        ssl_certificate      /etc/letsencrypt/live/;
        ssl_certificate_key  /etc/letsencrypt/live/;

        # Improve HTTPS performance with session resumption
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 5m;
        # Disable SSLv3
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        # Enable HSTS (
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";

        # Enable OCSP stapling (
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/letsencrypt/live/;
        resolver valid=300s;
        resolver_timeout 5s;

        # Log location definition
        access_log  /var/log/nginx/https-nginx-access.log;
        error_log  /var/log/nginx/https-nginx-error.log;

     location / {

        proxy_set_header        Host $host:$server_port;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;

Once you have saved the configuration file, you can run the following commands to validate there are no errors in the config and then apply them using “reload, restart”.

sudo nginx -t
sudo service nginx reload
sudo service nginx restart

If you notice, we now have 2 separate server blocks in the configuration file and here is the explanation.

  • First server block listens to incoming request on port 80 which is the default HTTP port
  • Secod server block listens to port 443 which is the default HTTPS (SSL Enabled) port.
  • We’re using “ssl_certificate” and “ssl_certificate_key” arguments to define the path where our SSL files are stored. This path is arbitrary and you can change it to your liking as long as the SSL key and cert is available there.

Enforcing HTTPS on all URLs

That should enable the SSL on your website. However, the users would have to manually enter “https” in the URL in order to reach the encrypted entry point. The HTTPS is not yet enforced. There are several ways to accomplish this. The easiest way is to add an “.htaccess” entry in the root directory of your website to force all the visitors to HTTPS enabled URL. You can add the following code.

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 

Feel free to comment below if you need any help troubleshooting the errors you come across.

Published by Nishant

With over 9 years in the industry, initially started as a Linux administrator and transitioned into DevOps Engineer. I work with deployment and infrastructure automation as well as application release management processes.

Leave a comment

Your email address will not be published. Required fields are marked *

Hooman? *