Add Self-Signed SSL To Google Chrome on Ubuntu 16.04

Self-Signed SSLThere are plenty of times when you are working on a website that uses SSL and you need to work on that site locally in your own development environment. Usually you just set things up not to run on SSL locally because it’s generally less trouble than getting SSL working on your local web server. Sometimes, however, you really need a local development environment that supports SSL. Here is how to do it for free with a self-signed SSL certificate.

UPDATED: April 22, 2017 – SubjectAltName

Chrome released an update recently that requires the SSL certificate to list the various domains you are using for your wildcard certificate under the Subject Alt Names section of your certificate. So, I’m updating this post to show you how to do that.

The Big Picture

I’m setting up a wildcard SSL certificate to use for local development with my wildcard virtual host configuration on nginx. This will let you spin up new sites using an SSL certificate without ever having to mess with /etc/hosts file or server configurations. I’m going to be using the local development domain lee.dev. After completing this, to create a new development site, Just create a new directory and your site will be available at https://<dir_name>.lee.dev.

openssl Configuration

The trick to this whole thing lies in the openssl.cnf file. Set up a temporary directory to work in at ~/tmp/ssl just too keep all these files together. Then, after generating the cert and key files, we’ll move them to where they need to be.

So… make a copy of your main openssl.cnf file to work with:

cp /etc/ssl/openssl.cnf ~/tmp/ssl/openssl.cnf

Now, open the copy of openssl.cnf and add (or uncomment) this line from the [v3_req] section of the file:

[v3_req]
...
x509_extensions = v3_ca

Then, add this section to the end of the [v3_req] section:

[v3_ca]
...
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.lee.dev
DNS.2 = lee.dev

Generate Self-Signed SSL Certificate

I am going to generate a key file and certificate for my local development domain lee.dev. You would replace lee.dev with whatever your domain is, or you could just use file names like server.key and server.crt – whatever fits your needs. The names of the files aren’t really very important other than for your own organizational needs.

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout lee.key -out lee.crt -config openssl.cnf

The end result of all of this is your lee.key file and your lee.crt file which you will use in your nginx (or Apache) virtual host configuration. If you are creating a self-signed SSL certificate for a wildcard subdomain (like I am doing) then you will want to be sure to enter *.lee.dev when asked for your fully qualified domain name (FQDN) when creating your SSL certificate.

Here is what my nginx server block looks like. The key things to note, with regard to the SSL certificate, are:

  • listen 443;
  • ssl on;
  • ssl_certificate /etc/ssl/lee.crt;
  • ssl_certificate_key /etc/ssl/lee.key;
server {
  listen 443;
  ssl on;
  ssl_certificate /etc/ssl/lee.crt;
  ssl_certificate_key /etc/ssl/lee.key;

  server_name ~^(?<vhost>.+)\.lee\.dev$;
  root /home/lee/sites/$vhost;
	index index.php index.html index.htm index.nginx-debian.html;

	location / {
		try_files $uri $uri/ /index.php?q=$uri&$args;
	}

	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass 127.0.0.1:9000;
	}
}

Be sure to restart nginx to load your new configuration.

Getting Google Chrome To Accept Your Self-Signed Certificate on Ubuntu 16.04

This is done differently on different platforms. I am working on Ubuntu 16.04. If you are using any linux based setup you will need to use the certutil command line tool for this. If you don’t have that command line tool, run this:

sudo apt-get install libnss3-tools

Now, navigate to your development website in your Google Chrome browser. You will see that the https: part of the URL is all red-X-ed out. Now we want to add our self-signed SSL certificate to Google Chrome so we can trust ourselves and not see the annoying security warnings for our local development.

Here’s what to do:

  • click the lock icon with an X,
  • choose Certificate Information
  • go to Details tab
  • Click on Export… (save as a file)

For me, the file saved as -.lee.dev because I created a wildcard SSL certificate for the domain lee.dev. It doesn’t matter what the file name is, just make note of what the file name is so you can use it in the next command.

The following command will add the certificate (where YOUR_FILE is your exported file):

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

To see if it actually worked, you can list all of your certificates with this command:

certutil -d sql:$HOME/.pki/nssdb -L

Now, when you go to your site you should see that Google Chrome trusts your self-signed SSL certificate.

Removing A Certificate

If you need to delete a certificate do the following:

certutil -D -d sql:$HOME/.pki/nssdb -n -.lee.dev

where -.lee.dev is the name of your certificate. To see a list of all your certificates and their names use this command:

certutil -d sql$HOME/.pki/nssdb -L

Resources

I learned this series of steps from the following sources:

14 thoughts on “Add Self-Signed SSL To Google Chrome on Ubuntu 16.04

  1. Very easy to follow instructions. Worked first time!

    On CentOS the configuration file is here: “/etc/pki/tls/openssl.cnf”.

  2. Mark Alexa says:

    Getting error line saying: “certutil: function failed: SEC_ERROR_BAD_DATABASE: security library: bad database.”

  3. Banish says:

    Came here for this. This solution makes Chrome happy and works great for Debian and Apache 2 as well. Thanks for posting! For Apache, the conf file will look like:

    SSLEngine on
    SSLCertificateFile /etc/ssl/…/dev.lee.crt
    SSLCertificateKeyFile /etc/ssl/…/dev.lee.key

  4. AZ420 says:

    Thank you for this. Awesome!

  5. Jamie Hutber says:

    The database has migrated over the years from flat files to Berkeley DB to now SQLite in 3.12. Prefix the directory name with sql and enclose in quotes to get around spaces:

    certutil -L -d sql:${HOME}/.pki/nssdb
    For reference, here’s the Mozilla NSS roadmap.

  6. David says:

    This is interseting, but there’s no need to go to the trouble any more now that SSL certificates are available free:

    Let’s Encrypt – Free SSL/TLS Certificates
    https://letsencrypt.org/

    AWS Certificate Manager
    https://aws.amazon.com/certificate-manager/pricing/

  7. James says:

    Setup is not longer working with:

    Google Chrome Version 65.0.3325.146 (Official Build) (64-bit)

    On the other hand Opera does not seem to mind.

    • Mohamed Jebali says:

      It works with Chrome 66, I just tried it.
      Open the Security console, you will get more details

  8. Ivan says:

    Thanks that worked nicely!

  9. James says:

    Thanks so much for a super clear write up. I spent a lot of hours trying to get this configured correctly and thanks to you it is. Really, really appreciated.

  10. Ben says:

    @Mark Alexa, that error, “certutil: function failed: SEC_ERROR_BAD_DATABASE: security library: bad database.” will arise if the database does not yet exist. You can create it first with the following commands:

    $ mkdir -p $HOME/.pki/nssdb
    $ certutil -N -d $HOME/.pki/nssdb –empty-password

  11. Raul says:

    Can I use this without adding an entry in /etc/hosts? I used apache and the procedure worked, but after adding an entry in /etc/hosts mapping my domain to 127.0.0.1

  12. Jarek says:

    Firefox?

  13. Hendrik says:

    Thank you.

    This took me quite some time to find. This is the only thing that works properly as it seems Chrome does not listen to the `update-ca-certificates` command.

Leave a Reply

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