How To Configure Nginx to use Self-Signed SSL/TLS Certificate on Ubuntu 18.04 VPS or Dedicated Server


SSL (Secure Sockets Layer) and TLS (Transport Layer Security), are web protocols that are used to protect normal traffic by wrapping it in an encrypted form.

This technology features a certificate system that allows private communication between servers and clients. It creates a secure path for servers to send traffic to customers without the information being manipulated by other parties.

In this tutorial, we will take you through the process of creating a self-signed SSL/TLS certificate and use it on Nginx. In this case, we will use Ubuntu 18.04 server.


Before you start, you need the following:

  • A non-root user with sudo privileges
  • An installed Nginx server

Now, let’s dive into the process.

Step 1: Creating Self-Signed Certificate

When it comes to implementation of SSL/TLS certificates, they work through a set of public certificate and a private key. The SSL certificate is a public document that is shared with clients that request for the content. On the other hand, the SSL key is used in encrypting messages sent to clients and it should be kept as a secret on your server.

To create a certificate and self-signed key with SSL, run the command below:

$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/ -out /etc/ssl/certs/

Openssl: This command line tool for generating and managing the OpenSSL certificate, keys, plus other files.

Req: This a subcommand that indicates we want to utilize X.509 CSR (certificate signing request) management. X.509 is the public key infrastructure standard that TLS and SSL comply with for its certificate and key management. In our case, we are generating a new X.509 certificate, and for this reason we use req.

-x509: This modifies the req subcommand. It informs the utility that we are creating a selfsigned certificate instead of generating a CSR.

 -nodes: This commands OpenSSL not to secure the certificate using a passphrase. A passphrase prevents Nginx to read our file whenever the server is started.

-days 365: This stipulate the duration of the certificate validity.

-newkey rsa:2048: This a command stating that we’ll be generating a new key and certificate simultaneously. Rsa:2048 instructs the service to create a 2048 bits RSA key.

-keyout: This a line instructing OpenSSL to to store the created private key.

-out: The line instructs OpenSSL where to store the created certificate.

After the above command, you’ll be prompted to answer a few questions about the certificate you want to generate.

How To Configure Nginx to use Self-Signed SSL/TLS Certificate on Ubuntu 18.04 VPS or Dedicated Server

Read them carefully and provide the right answers to complete the process. The important line to note on this section is one that requires the Common Name such as YOUR name or server Fully Qualified Domain Name (FQDN). In this case, enter your domain name, or public IP address associated with the server.  .

You should have the output below:

CountryName (2 lettercode) [AU]:US
StateorProvinceName (fullname) [Some-State]:New York
LocalityName (eg, city) [ ]:New YorkCity
OrganizationName (eg, company) [Internet Widgits Pty Ltd]::Example Company
OrganizationalUnitName (eg, section) [ ]:SSL Unit
CommonName (e.g. serverFQDNorYOURname) [ ]:server_IP_address
EmailAddress [ ]

Once you’re done, the two files will be stored in the right subdirectories in the /etc/ssl directory.

You will need these files as the reference in Nginx configuration settings. It is also important to create a strong DH (Diffie-Hellman) group which is essential in negotiations of the forward secrecy with clients.

To do so, run the command below:

$ sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096

This process may take a while, but once it’s done, your DH (Diffie-Hellman) group will be stored at /etc/nginx/dhparam.pem that can be used in Nginx configuration.

How To Configure Nginx to use Self-Signed SSL/TLS Certificate on Ubuntu 18.04 VPS or Dedicated Server

Step 2: Configuring Nginx HTTP Web Server to use SSL

Since we have already created the certificate and key and files, we can move to configure Nginx with these settings.

But before that, here are few adjustments we need to make to our configuration to put common sections into reusable units.

Creating a Configuration Snippet for SSL Key and Certificate

Start by creating a snippet for Nginx configuration in the /etc/nginx/snippets directory. We will name this file self-signed.conf.

$ sudo nano /etc/nginx/snippets/self-signed.conf

Now, set the ssl_certificate to the associated file and ssl_certificate_key to its accompanying key. This will give you the following output:

ssl_certificate /et##c/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

Then, save and exit the file.

Generating a Configuration Snippet To Define SSL Settings

The next step is to create an extra snippet with strong SSL encryption settings. This will enable other additional features to keep your server secure.

In this case, we are going to choose a generic name as shown below:

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

To ensure Nginx SSL is set securely, we will use the format on the site which provides easy-to-use encryption guidelines for popular software.

For this tutorial, we will copy the settings provided from this site, but we will change a few lines.

In this case, we will include our DNS resolver for different upstream requests. Also, we will uncomment the line that is responsible for the transport security header.

Copy the details below into your snippet file named ssl-params.conf.

ssl_protocols TLSv1.2;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_ticketsoff; # Requires nginx >= 1.5.9
ssl_staplingon; # Requires nginx >= 1.3.7
ssl_stapling_verifyon; # Requires nginx => 1.3.7
resolver8. valid=300s;
# Disable strict transport security for now. You can uncomment the following
# line if you understand the implications.
# 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";

Since we are only utilizing a self signed certificate, there is no need to include SSL stapling. Nginx will automatically disable stapling and proceed to run properly.

Now, save and exit the file.

Modifying Nginx Configuration to Point to SSL

Once you’re done with snippets, now adjust Nginx configuration to allow SSL.

For this example, we will use /etc/nginx/sites-available/ Replace the filename in your configuration with the one you want to use.

But before that, begin by backing up the current configuration file:

$ sudo cp /etc/nginx/sites-available/ /etc/nginx/sites-available/

Open your file and adjust the appropriate line as shown below:

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

You will see an output like this:

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


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

    . . .

You may discover different configuration statements where sections such as root and index may appear as location, proxy_pass, or other configurations. It is important to mention that it’s okay to have these directives, you just need to update the listen statements and include the SSL snippets.

In your current configuration file, go ahead and update the listen statements to server SSL traffic on port 443 and ssl. Also, include the snippet files created in the previous two steps:

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


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

    . . .

After the closing bracket (}) of the block above, paste another server block into your configuration file:

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


    return302 https://$server_name$request_uri;

The above configuration listens on port 80 , besides performing redirects to HTTPs.

Save and exit the file once you’re done.

Step 3: Adjusting Ufw Firewall Settings

If the ufw firewall is enabled, you need to adjust the system settings to allow traffic through SSL.

Once the installation is complete, Nginx will register several profiles with ufw.

You can see these profiles by running the command below:

$ sudo ufw app list

You will see an output like this:

Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS

To see what setup is enabled, run the command below:

$ sudo ufw status

You should have an output like this to show that your web server will only allow HTTP traffic:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

To ensure the HTTPS traffic is flowing smoothly, allow “Nginx Full” profile and delete the Nginx HTTP redundant profile:

$ sudo ufw allow 'Nginx Full'
$ sudo ufw delete allow 'Nginx HTTP'

Your output should look like this:

$ sudo ufw status


Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)

Step 4: Restarting Nginx to Apply the Changes

Once the adjustments to the firewall are made, now restart the Nginx service to apply the changes.

Also, check to ensure that there no errors in your files. To do so, run the command below:

$ sudo nginx -t

If everything is working properly, you should get the following output:

nginx: [warn] "ssl_stapling" ignored, issuer certificate not found
nginx: the configuration file /etc/nginx/nginx.confsyntax is ok
nginx: configuration file /etc/nginx/nginx.conftest is successful

Now, restart nginx to apply the changes:

$ sudo systemctl restart nginx

Step 5: Testing the SSL Server

Next, test whether the SSL encryption is working.

On your browser, type the prefix http:// then your domain name:


Since the certificate is not already signed by a trusted certificate authority, you will most likely get a warning like the one below:

You will see a warning that may pop-up because the SSL certificate created earlier isn’t signed by a trusted certificate authority:

How To Configure Nginx to use Self-Signed SSL/TLS Certificate on Ubuntu 18.04 VPS or Dedicated Server

Don’t worry when you see this message, it’s normal. The important thing is the encryption feature of the certificate. Select the Advanced option and the link that will follow to proceed to the host.

How To Configure Nginx to use Self-Signed SSL/TLS Certificate on Ubuntu 18.04 VPS or Dedicated Server

You will be directed to your website. In your browser bar, you may see something that looks like a lock with a symbol “x” over it. It signifies that the certificate is not yet validated and the encryption is still in progress.

To check whether then HTTP content redirect is working properly, type the following:


If the results of the lock icon are the same, it means that the redirect is functioning properly.

Step 6: Pointing To Permanent Redirects

If you are sure you want to permit only encrypted traffic, then its important to change the Nginx configuration to create permanent redirect.

Use the command below to open the server block configuration file:

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

Find return 302 and replace it with return 301:

return301 https://$server_name$request_uri;

Save changes and close the file

Next, scrutinize the configuration for potential syntax errors using the command below:

$ sudo nginx -t

Restart Nginx to complete the modifications:

$ sudo systemctl restart nginx


There you have it! You have successfully configured Nginx to use SSL/TLS certificate. It’s a secure way to allow requests from clients and prevent other parties from accessing your traffic.


Check out the top 3 Linux hosting services

Was this article helpful?