email@encode8.com
Dev-ops

Self-signed SSL Certificates for Local Development

SSL (Secure Sockets Layer) is a standard security protocol for establishing encrypted links between a web server and a browser in an online communication.  Almost all major browsers show a warning message to users if they input login credentials on non-SSL sites. More and more people are opting for SSL everyday. Using LetsEncrypt, issuing SSL certificates has become a painless affair.

But SSL certificates, issued by LetsEncrypt or other CA authorities, work on real domain names. If you are developing a website locally, you are out of luck. You may feel that SSL is not required on local development machines. But several APIs require you to access their endpoints only via HTTPS. Also, it is a good practice to use SSL when data is moving — the general rule is: you should use SSL when your data is on the move, and PGP when your data is static.

So in order to issue local ssl certificates, you have two options.

1. Using openssl

You can issue self-signed certificates using openssl. To issue a certificate, you can just run the following command:

openssl genrsa -out localhost.key 2048

This will generate an RSA private key for localhost which is 2048 bits in length. The generated private key is saved in local.key file. Next, we need to generate a certificate. To do so, run this command:

openssl req -new -x509 -key localhost.key -out localhost.cert -days 3650 -subj /CN=localhost

Our certificate is saved in localhost.cert and is valid for 3650 days.

Now that we have the certificate, we can use it with Apache or Nginx. But you would get ‘Certificate not trusted’ error when you visit localhost. This is because it is a self-signed certificate and there is no CA authority that can be trusted. You need to add an exception for this certificate in order to bypass this error message.

2. Using mkcert

mkcert is a very useful tool for issuing local SSL certificates. Issuing a certificate with mkcert is a cleaner way than the one described above. Once you have installed mkcert, just run:

mkcert -install

Under the hood, mkcert creates a new certificate and adds it to system trust store so that you don’t see that pesky ‘Certificate not trusted’ error.

Whether you are using openssl or mkcert, you should configure your webserver to actually use those certificates. For nginx, add the following in the server block:

server {
        ...

        listen 443 ssl;

        ssl_certificate /path/to/certificate.crt;
        ssl_certificate_key /path/to/certificate.key;
        
        ...
}

For Apache, you can follow this guide (only Configuration for Apache section).

Conclusion

I personally prefer using mkcert over openssl for the simple reason that mkcert does not require me to remember long commands. However, one of the main drawbacks of mkcert is its unavailability to Windows users. If you are using a Windows machine, you won’t be able to issue certificates using mkcert. Openssl is your best bet, probably over cygwin.