Dec 09, 2019 8:30 AM Feb 10, 2020 1:30 PM

Adding a trusted self-signed SSL certificate to Apache on Debian/Ubuntu

In this article I will explain how to add a trusted self-signed SSL certificate to the Apache server on the Debian/Ubuntu operating system. I always use the HTTPS protocol for the local development environment. But I was always annoyed that the browser does not trust the self-signed SSL certificate and displays a notification about it. Several times I tried to figure this out. I tried different instructions, but none of them solved my problem. And then one day I decided to deal with this problem in detail and finally solve it. I hope this instruction helps you too.

At some point, I again had errors in browsers: NET::ERR_CERT_AUTHORITY_INVALID (Google Chrome), MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT (Firefox). And again I had to figure out how to solve this problem. I wrote a new article on how to add a trusted SSL certificate for the local environment in Apache on Debian/Ubuntu. This time we will use the root certification authority (CA).

This instruction was executed on operating systems: Debian 10, Debian 9, Ubuntu 20.10, Ubuntu 20.04, Ubuntu 19.10.

Creating an OpenSSL configuration

Let's start with this important section. We need to create a configuration file for OpenSSL by running the command in the terminal:

nano /tmp/openssl.cnf

Copy and paste the following prepared configuration into a new file, where DNS.1 is the name of your server (specify DNS.2 if you need support for subdomains):

[req]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
x509_extensions = v3_ca # The extensions to add to the self-signed cert

[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = New York
localityName = Locality Name (eg, city)
localityName_default = Rochester
organizationName = Organization Name (eg, company)
organizationName_default = Localhost CA
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Development
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = localhost
commonName_max = 64

[v3_ca]
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
# Support subdomains
#DNS.2 = *.domain.local

Save the changes and close the file.

Creating a trusted self-signed SSL certificate

Now let's create a self-signed SSL certificate with a private key using our configuration file:

sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/private/localhost.key -out /etc/ssl/certs/localhost.crt -config /tmp/openssl.cnf

where

In the process of generating the certificate, several questions will be asked. You can skip them:

Creating a trusted self-signed SSL certificate

Configuring Apache to use SSL

Let's enable SSL in the Apache server configuration. We will specify listening on port 443 (HTTPS) and the path to the certificate and private key files. Edit the server configuration file /etc/apache2/sites-available/default-ssl.conf:

sudo nano /etc/apache2/sites-available/default-ssl.conf
<IfModule mod_ssl.c>
	<VirtualHost _default_:443>
		ServerAdmin webmaster@localhost

		DocumentRoot /var/www/html

		ErrorLog ${APACHE_LOG_DIR}/error.log
		CustomLog ${APACHE_LOG_DIR}/access.log combined

		SSLEngine on
		SSLCertificateFile	/etc/ssl/certs/localhost.crt
		SSLCertificateKeyFile /etc/ssl/private/localhost.key

		<FilesMatch "\.(cgi|shtml|phtml|php)$">
			SSLOptions +StdEnvVars
		</FilesMatch>
		<Directory /usr/lib/cgi-bin>
			SSLOptions +StdEnvVars
		</Directory>
	</VirtualHost>
</IfModule>

Save the changes and close the file.

You must activate the mod_ssl module by running the command in the terminal:

sudo a2enmod ssl

Do not forget to activate the configuration file by running the command in the terminal:

sudo a2ensite default-ssl

Check the configuration for validity by running the command in the terminal:

sudo apache2 -t

Now apply the configuration changes by running the command in the terminal:

sudo service apache2 reload

Installing certutil utility

Now we need to add the generated SSL certificate to the database that the browser uses. The certutil utility, which is part of the libnss3-tools package, is used to manage this database. If you do not have this package in the system, then install it.

Before any software installation, it is recommended to update the list of repository packages by running the command in the terminal:

sudo apt-get update

Install the libnss3-tools package by running the command in the terminal:

sudo apt-get install libnss3-tools

Adding a certificate to the database

Let's add the generated SSL certificate to the database using the certutil utility by running the command in the terminal:

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

This instruction has been tested on browsers: Google Chrome and Opera.

The Firefox browser does not want to trust the certificate, it uses the cert8.db database, which I edited as follows:
certutil -d sql:$HOME/.mozilla/firefox/xqck5xx8.default -A -t "P,," -n localhost.crt -i /etc/ssl/certs/localhost.crt

Encryption testing

In order for the browser to read the updated certificate database, you need to restart your browser (close and reopen).

Let's check that our Apache server is accessible via the HTTPS protocol by entering the following address in the browser:

https://localhost

If you did everything correctly, you will see that the browser has begun to trust your self-signed certificate. Your connection will now be encrypted using the HTTPS protocol without displaying a warning about an insecure connection:

Apache welcome page with trusted SSL

Other articles