Sunday October 17 2021

Automatically stuffing a Certificate Authority into pass

Why? Because pass is a convenient interface I can use that’s backed by hardware security.

Download EasyRSA, I’m using a git checkout.

From there let’s go into the easyrsa3 folder and configure the vars:

if [ -z "$EASYRSA_CALLER" ]; then
	echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2
	echo "This is no longer necessary and is disallowed. See the section called" >&2
	echo "'How to use this file' near the top comments for more details." >&2
	return 1
fi
set_var EASYRSA_REQ_COUNTRY		"US"
set_var EASYRSA_REQ_PROVINCE	"New Hampshire"
set_var EASYRSA_REQ_CITY		"Concord"
set_var EASYRSA_REQ_ORG			"riedstra.dev"
set_var EASYRSA_REQ_EMAIL		"mitch@riedstra.dev"
set_var EASYRSA_REQ_OU			"Primary CA"
set_var EASYRSA_ALGO			ec # Optionally, 'rsa'
set_var EASYRSA_CA_EXPIRE		3650
set_var EASYRSA_CERT_EXPIRE		825
set_var EASYRSA_CRL_DAYS		1800
set_var EASYRSA_BATCH			1

I’ve set the expire dates quite a ways into the future here, I’ve also changed the EASYRSA_ALGO to ec from RSA. You can shorten up the expire dates if you want to force yourself to rotate the CA sooner.

Now for a script to chuck the information we need into pass: Note the use of the nopass option, you can specify passwords for each if you wish, I’m just doing this in memory ( tmpfs ) and wiping the directory when I’m done. Destroying the CA key. Risk of compromise is minimal given this. Adding new certs or revoking old ones is done by rebuilding the entire CA and re-keying the entire infrastructure. At small scales this works wonderfully. Large scales should probably look at other solutions like cfssl using intermediate certificates and shortening the expire window.

#!/bin/sh
set -ex
# Adjust hosts and workstations to your heart's content for the actual hosts
# and workstations involved
hosts="ns0.example.com
ns1.example.com"
ca_prefix="ca/prometheus"

workstations="laptop"

./easyrsa init-pki
./easyrsa build-ca nopass

pass insert -m "${ca_prefix}/ca.crt" < pki/ca.crt

for _h in $hosts $workstations ; do
        ./easyrsa build-serverClient-full "$_h" nopass
        pass insert -m "${ca_prefix}/${_h}.key" < "pki/private/${_h}.key"
        pass insert -m "${ca_prefix}/${_h}.crt" < "pki/issued/${_h}.crt"
done

for _w in $workstations ; do
        ./easyrsa export-p12 "$_w"
        pass insert -m "${ca_prefix}/${_w}.p12" < "pki/private/${_w}.p12"
done

Note the workstations var, this is used to export a PKCS#12 archive which we can import into our browser’s certificate store. This allows us to pull up HTTPS severs that require client certificates. ( As I have configured for Prometheus and Node Exporters on my servers )

This allows me to somewhat comfortably leave them open to the world with confidence that only trusted clients will be connecting. For instance: https://ns1.riedstra.dev:9090 ( And port 9100 ) will not load for you, even if you bypass HSTS and the untrusted CA.