The scripts included all need to store persistent data somewhere. For this example, a local directory is used:
$ VOL=/var/lib/minica
Create the database for certificate storage and revokation.
$ docker run -ti --rm -v $VOL:/certs dparrish/minica create_database.sh
...
goose: migrating db environment 'development', current version: 0, target: 1
OK 001_CreateCertificates.sql
First, edit the Root CA configuration. At the very least you should change the CN and OU values to something that makes sense to you.
$ sudo vi $VOL/install/ca-csr.json
Run the script that creates the Root CA certificate. This certificate is only used to generate an Intermediate certificate and should be protected.
$ docker run -ti --rm -v $VOL:/certs dparrish/minica create_root.sh
Creating Root Certificate.
2019/02/19 04:58:54 [INFO] generating a new CA key and certificate from CSR
2019/02/19 04:58:54 [INFO] generate received request
2019/02/19 04:58:54 [INFO] received CSR
2019/02/19 04:58:54 [INFO] generating key: ecdsa-256
2019/02/19 04:58:54 [INFO] encoded CSR
2019/02/19 04:58:54 [INFO] signed certificate with serial number 310123162380203327702166914002183066553285968238
To validate and revoke certificates, a URL must be available to clients that use the CA's generated certificates. This URL should be served by the minica job. These URLs are configured in the config.json
file, so you can edit that file directly or use the provided script to replace the placeholders automatically. For these instructions, ca.dparrish.com
will be used for the base URL.
$ docker run -ti --rm -v $VOL:/certs dparrish/minica set_base_url.sh ca.dparrish.com
Run the script that creates the Intermediate CA certificate. This certificate is used to sign all certificate requests from clients.
$ sudo vi $VOL/install/intermediate-csr.json
$ docker run -ti --rm -v $VOL:/certs dparrish/minica create_intermediate.sh
2019/02/19 05:00:17 [INFO] generate received request
2019/02/19 05:00:17 [INFO] received CSR
2019/02/19 05:00:17 [INFO] generating key: ecdsa-256
2019/02/19 05:00:17 [INFO] encoded CSR
2019/02/19 05:00:17 [INFO] signed certificate with serial number 694464029169303736780477313118487302242919220637
2019/02/19 05:00:17 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
2019/02/19 05:00:17 [INFO] generate received request
2019/02/19 05:00:17 [INFO] received CSR
2019/02/19 05:00:17 [INFO] generating key: ecdsa-256
2019/02/19 05:00:17 [INFO] encoded CSR
2019/02/19 05:00:17 [INFO] signed certificate with serial number 471292738264490260574895146908956428084454001108
2019/02/19 05:00:17 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
You should remove the Root Certificate keypair from the container's volume and keep it offline. It is only ever used to generate a new Intermediate certificate.
$ cp $VOL/root-key.pem $VOL/root.pem /some-backup-location
$ docker exec -ti minica shred_root.sh
Start the Mini-CA job serving:
$ docker run -d --restart=always -P --name minica -v $VOL:/certs dparrish/minica
The docker container exposes two ports, 80 and 8888. Port 80 runs a web server that provides /ocsp
, /crl
and /bundle.pem
. These URLs are suitable for public visibility.
Port 8888 is the cfssl remote API which should be protected, as this can be used to sign certificates without authentication.
The author's setup uses a traefik
proxy that exposes services to the outside world, so the following command makes port 80 available worldwide for CRL, and port 8888 only on localhost:
docker run -d --restart=always --name minica \
-p 127.0.0.1:8888:8888 \
-v $VOL:/certs \
--label "traefik.port=80" \
dparrish/minica
$ openssl ecparam -name prime256v1 -out prime256v1.pem
$ openssl req -new -newkey ec:prime256v1.pem -nodes -keyout server.key -out server.csr
$ cfssl sign -remote localhost -profile server server.csr | cfssljson -bare server -