facebook youtube pinterest twitter reddit whatsapp instagram

Securing Nginx Server Using a (Self Signed Certificate) [Ubuntu]

In this guide, you'll learn how to use SSL to secure your Nginx, this way, you can ensure your websites are encrypted and available over HTTPS.

By default, Nginx configuration listens for traffic on port 80 in Ubuntu, and not port 443 (HTTPS).

There are two ways you can go about installing SSL, you can either go with a self-signed certificate that most browsers won't trust by default and the other way is to install certificates signed by a certificate authority, which is the recommended method.

We would be using a self-signed certificate as an illustration in this guide, they are not recommended for a production environment, so, if you are planning to secure Nginx on a production server, you can go with this article: Securing Nginx Server Using (Let's Encrypt) [Ubuntu]

Create a directory that would house the certificates. Create a certs directory under /etc/nginx/

Change your working directory into /etc/nginx/ and run the following command

sudo mkdir certs

To avoid an error when issuing a self-signed certificate in Ubuntu, you might need to create a .rnd in your user directory, make sure this is owned by the user of the home directory, it is used by OpenSSL to store some amount (256 bytes) of seed data.

Create the .rnd file:

touch ~/.rnd

Now, request for the certificate and key pair with the following command:

Note: You can also change the name of the key and cert file to match the name of your website. In my case, I am using website.com

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/certs/website.key -out /etc/nginx/certs/website.crt

You would be asked a series of questions, this is would be incorporated in your certificate request, here is the questions, and answer of mine:

Note: Your common name should be your server IP address

Country Name (2 letter code) [AU]:NG
State or Province Name (full name) [Some-State]:Lagos
Locality Name (eg, city) []:Ikeja
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Devsrealm
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:faruq@devsrealm.com

The next step is configuring Ngnix to use SSL, to do this, we would create two new configuration files, this is to make the process easy.

Create a self-signed.conf:

sudo nano /etc/nginx/certs/self-signed.conf

In that new file, add the location that the pair certificates is installed:

ssl_certificate /etc/nginx/certs/website.crt;
ssl_certificate_key /etc/nginx/certs/website.key;

Save and Close using Ctrl + X and Enter.

The next step is to create another configuration snippet, these provide Strong SSL Security for all modern browsers, plus you get an A+ on the SSL Labs Test. In short, they set a strong Forward Secrecy enabled ciphersuite, they disable SSLv2 and SSLv3, add HTTP Strict Transport Security and X-Frame-Deny headers and enable OCSP Stapling.

If you need more ciphers, visit cipherlist.eu

Create a new file:

sudo nano /etc/nginx/snippets/ssl-params.conf

In that new file, add the following:

ssl_protocols TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
# ssl_stapling on; # Requires nginx >= 1.3.7
# ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

I have commented out stapling, this is a method for quickly and safely determining whether or not an SSL certificate is valid, this is not needed in a self-signed certificate, uncomment it if you are not using self-signed.

The next step is to configure Nginx to use SSL. I'll assume you already have a config for website.com

Open it:

sudo nano /etc/nginx/sites-available/website.com

First, we change the first two lines to listen on port 443 with SSL instead of standard port

listen 443 ssl;
listen [::]:443 ssl;

Next, update the server block to reflect the following:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    include certs/self-signed.conf;
    include snippets/ssl-params.conf;
    ssl_session_timeout 5m;

    server_name website.com www.website.com;

    root /var/www/website.com/html;
    index index.html index.htm index.nginx-debian.html;

The last step is to redirect all HTTP version of our site to HTTPS version automatically. To do that add a new server block (to perform an HTTPS redirect) like so:

server {
listen 80;
listen [::]:80;

server_name website.com www.website.com;

return 302 https://$server_name$request_uri;

Finally, we need to link from sites-available to sites-enabled with the command:

ln -s /etc/nginx/sites-available/www.website.com /etc/nginx/sites-enabled/

Using ufw, we can check our new SSL-enabled profiles with the command:

sudo ufw app list

Restart NGINX with with the command:

sudo systemctl restart nginx

Now try visiting your server IP address with https, e.g

You would see a warning "certificate is not trusted because it is self-signed" bypass it by clicking allow.

You can configure chrome to trust the certificate by issuing:

certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n "localhost" -i localhost.crt

Related Post(s)

  • Setting Up Send-Only Mail Server From Scratch (With Haraka)

    In this guide, I would walk you through the steps of setting up an email server that can be used as a send-only mail server, we would not be dealing with receiving mails, we only care about sending em

  • Send Mail with Attachment Using Mutt in GNU/Linux

    Mutt is a powerful text-based mail client for Unix/Linux operating systems. It features color support, message threading, MIME support...

  • Using Pageant To Automatically Authenticate SSH key in Putty

    I can't count how many times I have typed my ssh key passphrase whenever my ssh connection times out, it is so annoying and repetitive. Well, thanks to the putty pageant, you can do that seamlessly.

  • Installing WP-CLI In a GNU/Linux Server

    WP-CLI is a command-line interface for WordPress. It can also be used with ClassicPress, as they are no differences in their usage, maybe just minimal if you are updating or downloading new ClassicPr

  • How To Send Mail To Multiple Addresses Using (mailx)

    In this guide, you'll learn a couple of ways you can send mail to multiple addresses using mailx. mailx is a utility program for sending and receiving mail. I assume you already have mailx command, i

  • Monitoring Multiple Log Files In RealTime With MultiTail (Ubuntu)

    Oh my... I really find scanning through the logs file time consuming, and painful. Luckily for me, I founded Multitail, which is an awesome, and powerful tool for not only browsing through several f