Page History

mkcert and CA certificates

Mark George edited this page on 11 Oct 2021

Clone this wiki locally

mkcert

Anonymous self-signed x509 certs for testing are pretty much useless now. Browsers are getting more and more picky, and server software is starting to validate the full chain and refusing to work with anonymous self-signed certificates.

The solution is to create your own CA certs/keys, register them with the system, and use those to sign your certificates. This is a P.I.T.A, so mkcert simplifies things (a little bit).

https://github.com/FiloSottile/mkcert

Written in Go, so distributed as a single big-assed binary which is nice. Supported on all the major 3 platforms.

mkcert does the following:

  • Creates a CA certificate/key pair
  • Adds the CA certificate to the system CA stores so it will be recognised as a 'real' CA
  • Creates certificates that are signed by the CA key so should be seen as trusted certs

Linux

Simple usage

Run as normal user rather than sudo or root. It automatically calls sudo when necessary (which is entirely terrifying).

# generate and install CA cert/key pair in $CAROOT (which defaults to ~/.local/share/mkcert)
mkcert -install

# figure out where it generated the CA cert/key pair
mkcert -CAROOT

# change the CAROOT
CAROOT=/some/other/place mkcert -install

# create and sign a certificate in current dir
mkcert localhost

# create a PKCS12 bundle (password is 'changeit')
mkcert -pkcs12 localhost

# change the stores that it installs the CA certs in
TRUST_STORES=system,java,nss mkcert -install

# remove CA certs from trust stores
mkcert -uninstall

Nitty gritties

  • System CA certs are stored in:
    • Ubuntu: /usr/local/share/ca-certificates/mkcert* with symlinks in /etc/ssl/certs/mkcert*
    • Arch: /etc/ca-certificates/extracted/cadir/mkcert* with symlinks in /etc/ssl/certs/mkcert*
  • Java CA certs are stored in the /etc/ssl/certs/java/cacerts keystore. View/edit via keytool -cacerts. Default password is changeit.
  • Browser CA certs are stored in the user's NSSdatabase at ~/.pki/nssdb. View/edit via certutil:
     certutil -L -d ~/.pki/nssdb
  • Browser certificates can be viewed using chrome://settings/certificates (Linux only)

Gotcha's

As mentioned above, mkcert will automatically run sudo for system operations, so thinking you are safe to run it from a user account for playing around, or making user-only changes to NSS DBs is a bad idea. If you have recently run a sudo operation and run mkcert within the previous sudo's timeout window you will be making system-level changes. I have complained about this on the GitBucket for the project, but have so far been ignored. If you are worried about this, then run sudo -k to invalidate your sudo session which means you will at least be prompted for a password before mkcert makes system changes.

Windows

The following powershell one-liner sets the CAROOT to the current directory, set the TRUST_STORES to system only, and creates and installs the CA certs in the system store.

$env:CAROOT = pwd; $env:TRUST_STORES = 'system'; .\mkcert.exe -install

This does not seem to need to be run from an administrator terminal. There is a pop-up box that asks for permission, so the authorization seems to be via the usual 'get the user to click yes' approach. It doesn't even require UAC...

The CA cert can be viewed/deleted via certmgr. Run the following command to start it:

certmgr.msc

Create signed certificates using

$env:CAROOT = pwd; .\mkcert.exe -pkcs12 localhost

macOS

Pretty much the same as Linux, however using the nss trust store is not necessary as the browsers use the system store.

Browsers

Windows

Chrome and browsers based on Chrome use the system store. Firefox is not supported by mkcert on Windows.

macOS

Safari uses the system store. I am assuming that Chrome does too, but have not tested it.

Linux

Both Chrome (and derivatives) and Firefox use NSS, so you need to install the CA into the nss trust store.