An SSL certificate is required to have secure communication between the server and the client applications. The SSL certificate with appropriate configurations ensures that the communication takes place over TLS or SSL(predecessor of TLS) protocols. We can either obtain the SSL certificate from the well-known certificate authorities including Let's Encrypt, Comodo, VeriSign, etc OR install a self-signed SSL certificate. The self-signed certificate shows a security warning for the first time since the client applications including the browsers do not recognize it. This is not the issue with the SSL certificate obtained from the certificate providers. We might still need the self-signed SSL certificate for testing and other purposes.
This tutorial provides the steps required to install the self-signed SSL certificate on Ubuntu 20.04 LTS using OpenSSL. It also provided the steps to configure the virtual hosts of Apache and server blocks of Nginx to enforce communication over TLS/SSL protocols.
Prerequisites
Ubuntu 20.04 LTS - This tutorial assumes that you have already installed Ubuntu 20.04 LTS desktop or server version either for local or production usage. You can follow Install Ubuntu 20.04 LTS Desktop, Install Ubuntu 20.04 LTS On Windows Using VMware, and Spin Up Ubuntu 20.04 LTS Server On Amazon EC2 to install Ubuntu 20.04 LTS. It also assumes that you have either root privileges or a regular user with sudo privileges.
Apache Web Server (Optional) - It assumes that the Apache is already installed on the system and it's configured properly to access the Virtual Host using the domain name. You can also follow How To Install Apache 2 On Ubuntu 20.04 LTS to install the Apache Web Server.
Nginx Web Server (Optional) - It assumes that the Nginx is already installed on the system and it's configured properly to access it using the domain. You can also follow How To Install And Configure Nginx on Ubuntu 20.04 LTS to install the Nginx Web Server.
Install Self-Signed SSL Certificate
This section provides the steps to install the self-signed SSL certificate on Ubuntu 20.04 LTS. Create the self-signed SSL certificate by executing the commands as shown below. Make sure to replace the word example or example.com with your domain.
# Create the Directory to store certificates sudo mkdir /etc/secure/
# Generate SSL Certificate
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/secure/example.com.key -out /etc/secure/example.com.crt
# Output Generating a RSA private key ..................+++++ ................+++++ writing new private key to '/etc/secure/example.com.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:<Country Code> State or Province Name (full name) [Some-State]:<State/Province> Locality Name (eg, city) []:<City/Location> Organization Name (eg, company) [Internet Widgits Pty Ltd]:<Org Name> Organizational Unit Name (eg, section) []:<Org Unit Name> Common Name (e.g. server FQDN or YOUR name) []:www.example.com Email Address []:admin@example.com
After providing all the details correctly, OpenSSL generates the private key and certificate at /etc/secure/example.com.key and /etc/secure/example.com.crt. Also, below listed are the parameters used by us to generate the self-signed SSL certificate.
- openssl - The openssl command is required to generate the self-signed SSL certificate.
- req - It specifies that we are using X.509 CSR (Certificate Signing Request).
- -x509 - It specifies that we want a self-signed certificate instead of certificate signing request.
- -nodes - Skip the option to secure the self-signed certificate using the passphrase.
- -days - The number of days for which certificate remains valid. We have provided the number of days as 365 to generate the certificate with 1-year validity.
- -newkey - Generate a new key and new certificate using rsa:2048.
- -keyout - The path to save the key file.
- -out - The path to save the certificate file.
Configure Apache Virtual Host
This section provides the steps to configure the virtual host to secure the domain hosted using Apache Web Server. A normal virtual host without SSL should be similar to the virtual host as shown below.
# Read Virtual Host sudo nano /etc/apache2/sites-available/example.com.conf
# Content <VirtualHost *:80> ServerName example.com ServerAlias www.example.com ServerAdmin admin@example.com
DocumentRoot /var/www/example.com/html <Directory /var/www/example.com/html> Options -Indexes +FollowSymLinks DirectoryIndex index.html AllowOverride All Require all granted </Directory>
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined </VirtualHost>
The domain without using the SSL Certificate should show the no-ssl sign as highlighted in Fig 1.
Now add another virtual host using the port 443 as shown below.
# Add Virtual Host sudo nano /etc/apache2/sites-available/example.com-ssl.conf
# Content <IfModule mod_ssl.c> <VirtualHost *:443> ServerName example.com ServerAlias www.example.com ServerAdmin admin@example.com
DocumentRoot /var/www/example.com/html
<Directory /var/www/example.com/html>
Options -Indexes +FollowSymLinks
DirectoryIndex index.php
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined SSLCertificateFile /etc/secure/example.com.crt SSLCertificateKeyFile /etc/secure/example.com.key </VirtualHost> </IfModule>
# Save and exit the editor
Also, update the existing virtual host by redirecting the HTTP requests to HTTPS as shown below.
# Update Virtual Host sudo nano /etc/apache2/sites-available/example.com.conf
# Content
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin admin@example.com
DocumentRoot /var/www/example.com/html
<Directory /var/www/example.com/html>
Options -Indexes +FollowSymLinks
DirectoryIndex index.html
AllowOverride All
Require all granted
</Directory> ErrorLog /var/www/example.com/logs/error.log CustomLog /var/www/example.com/logs/access.log combined
RewriteEngine on RewriteCond %{SERVER_NAME} =example.com [OR] RewriteCond %{SERVER_NAME} =www.example.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>
Now enable the new virtual host added by us and reload Apache Web Server as shown below.
# Enable Virtual Host sudo a2ensite example.com-ssl
# Enable rewrite module sudo a2enmod rewrite
# Enable SSL module sudo a2enmod ssl
# Restart Apache sudo systemctl restart apache2
Now if you will try to access the site using http://www.example.com, it will redirect to the URL https://www.example.com. It will also show security warnings for the first time as shown in Fig 2.
Now accept the risk and continue as shown in Fig 3.
After accepting the risk, it will open the URL using HTTPS as shown in Fig 4.
It will show an orange symbol instead of green due to the self-signed SSL certificate.
Configure Nginx Server Block
This section provides the steps to configure the server block to secure the domain hosted using Nginx Web Server. A normal server block without SSL should be similar to the server block as shown below.
# Content server { listen 80; server_name example.com www.example.com; root /var/www/example.com/html;
index index.html index.htm;
location / { try_files $uri $uri/ =404; } location ~ /\.ht { deny all; } }
Now update the server block and disabled the HTTP protocol. Also, enable HTTPS protocol and configure the SSL certificate and key as shown below.
Update server block sudo nano /etc/nginx/sites-available/example.com
# Content server { listen 80; server_name example.com www.example.com;
# Redirect to https return 301 https://$host$request_uri; }
server {
#listen 80; server_name example.com www.example.com; root /var/www/example.com/html;
index index.html index.htm;
location / { try_files $uri $uri/ =404; }
location ~ /\.ht { deny all; }
listen 443 ssl;
ssl_certificate /etc/secure/example.com.crt;
ssl_certificate_key /etc/secure/example.com.key; } # Save and exit the editor
Now reload Nginx to apply the changes as shown below.
# Reload Nginx sudo systemctl reload nginx
This will enable the HTTPS protocol to use the self-signed certificate generated by us.
Summary
This tutorial provided the steps to install a self-signed SSL certificate on Ubuntu 20.04 LTS. It also showed how to configure the virtual host of Apache to protect the host by redirecting all the HTTP traffic to HTTPS and create and configure the virtual host to use the self-signed certificate installed by us. The last section showed how to configure the server block of Nginx to redirect all the HTTP traffic to HTTPS and configure it to use the self-signed certificate installed by us.