Tangible Bytes

A Web Developer’s Blog

Local https for dev

As more and more of the web moves to https, we developers find more problems getting things to run properly.

It used to be easier to run development sites on http and maybe have a config option pretending it was secure, or use a fake certificate (often labelled “snakeoil”)

As the internet has matured this has become more problematic.

Some things just don’t work without https, browsers are less likely to let you ignore the warning, and if you develop a PWA it just won’t work without a valid, trusted certificate.

SSL Warning

Easy solution - use Let’s Encrypt

It may not be obvious but you can create a free valid cert using Let’s Encrypt

This requires you control a domain - but you can then use it to add a public DNS record for a private internal IP address.

The advantage of this method is that the certificate will be valid on (nearly) all devices

Create Your own Root Certificate Authority

If you don’t have a domain or for reasons of company politics the above isn’t possible..

You can create the keys for your own Certificate Authority - and then sign as many https certificates as you like.

Normal Certificate Authorities have been going for many years and have their public keys embedded in all browsers - these are then used by the browser to recognise and validate regular certs.

Your keys don’t have this advantage and the hard part is that you need to install them on any device you need to use.

Create Root Key

Attention: this is the key used to sign the certificate requests, anyone holding this can sign certificates on your behalf. So keep it in a safe place!

openssl genrsa -des3 -out rootCA.key 4096

If you want a non password protected key just remove the -des3 option

Create and self sign the Root Certificate

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

Here we used our root key to create the root certificate that needs to be distributed in all the computers that have to trust us.

Import this into your browser

This only works for browsers you control

I tried importing to my OS certificates but that didn’t work for me

Importing my rootCA.crt to the browsers did work (eventually)

You only have to do this once - then you can create as many https certs as you want (say one for each project) and they will be recognised.

Create a certificate

This procedure needs to be followed for each server/appliance that needs a trusted certificate from our CA

My example is for a local dev server where I have a matching entry in my /etc/hosts file for the IP

Create the certificate key

openssl genrsa -out dot.burlington.me.uk.key 2048

Create the signing (csr)

The certificate signing request is where you specify the details for the certificate you want to generate. This request will be processed by the owner of the Root key (you in this case since you create it earlier) to generate the certificate.

Important: Please mind that while creating the signign request is important to specify the Common Name providing the IP address or domain name for the service, otherwise the certificate cannot be verified.

You also need to specify a SAN / subjectAltName or chrome wont accept it

openssl req -new -sha256 \
    -key dot.burlington.me.uk.key \
    -subj "/C=UK/ST=Dorset/O=Tangible Bytes Ltd/OU=Development/CN=dot.burlington.me.uk" \
    -reqexts SAN \
    -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:dot.burlington.me.uk")) \
    -out dot.burlington.me.uk.csr

Verify the csr’s content

openssl req -in dot.burlington.me.uk.csr -noout -text

Generate the certificate using the custom csr and key along with the CA Root key

openssl x509 -req -extfile <(printf "subjectAltName=DNS:dot.burlington.me.uk") \
-days 120 \
-in dot.burlington.me.uk.csr \
-CA rootCA.crt \
-CAkey rootCA.key \
-CAcreateserial \
-out dot.burlington.me.uk.crt \
-sha256

Verify the certificate’s content

openssl x509 -in dot.burlington.me.uk.crt -text -noout