Graham Eddy

Micro Certificate Authority

Generate and sign certificates locally for private use. These can be easily deployed on internal networks but externally exposed certificates need to be signed off by a recognised Certificate Authority such as LetsEncrypt.

The μCA must be on a secure server. The whole trust chain depends upon it.

2023-05-02 Ubuntu 22.10, Debian bulleye


There must be a mechanism for securely transferring certificates between the μCA and any client hosts. The examples here use ssh access from μCA to client host, which is not particularly secure in this context because it leaves readable keys etc exposed for periods of time, but is adequate for illustrative purposes.

The hosts in the example are:

uca
μCA server
dbox
client host running a Debian OS

Installation

On μCA host:

@uca:~ sudo apt update @uca:~ sudo apt install easy-rsa @uca:~ mkdir easy-rsa # container for microCA @uca:~ chmod 700 easy-rsa # must be highly secured! @uca:~ cd easy-rsa @uca:~/easy-rsa ln -s /usr/share/easy-rsa/* . # (note trailing dot) @uca:~/easy-rsa ./easyrsa init-pki # create public key infrastructure @uca:~/easy-rsa vi vars
@uca ~/easy-rsa/vars new file
set_var EASYRSA_REQ_COUNTRY     "AU"
set_var EASYRSA_REQ_PROVINCE    "Victoria"
set_var EASYRSA_REQ_CITY        "Buxton"
set_var EASYRSA_REQ_ORG         "Graham Eddy"
set_var EASYRSA_REQ_EMAIL       "my email"
set_var EASYRSA_REQ_OU          "CA"
set_var EASYRSA_ALGO            "ec"
set_var EASYRSA_DIGEST          "sha512"
@uca:~/easy-rsa ./easyrsa build-ca nopass # create a certificate authority

Enable client host to use μCA-signed certificate

For each client host, only required once per μCA.

@uca:~/easy-rsa scp pki/ca.crt dbox:/tmp/ # place cert on dbox somehow

On client host:

@dbox:~ sudo cp /tmp/ca.crt /usr/local/share/ca-certificates/ @dbox:~ sudo update-ca-certificates @dbox:~ sudo rm /tmp/ca.crt # clean up transfer

Client host create key and have it signed by μCA

In this example, dbox will be providing service plop.

Client host generate key to be signed:

@dbox:~ openssl genpkey -algorithm RSA -out plop.key @dbox:~ chmod 400 plop.key # keep key here for now @dbox:~ openssl req -new -key plop.key -out plop.req @dbox:~ cp plop.req /tmp/ # make avail to uca somehow

μCA sign request and return certificate:

@uca:~ scp dbox:/tmp/plop.req /tmp/ # retrieve from dbox somehow @uca:~ cd ~/easy-rsa @uca:~ ./easyrsa import-req /tmp/plop.req plop @uca:~ ./easyrsa sign-req server plop @uca:~ scp pki/issued/plop.crt dbox:/tmp/plop.crt # make avail on dbox somehow @uca:~ rm /tmp/plop.req # clean up transfer

Client host retrieve certificate:

@dbox:~ cp /tmp/plop.crt . # retrieve cert somehow @dbox:~ sudo rm /tmp/plop.{crt,req} # clean up transfers @dbox:~ chmod 444 plop.crt # keep cert here for now @dbox:~ rm plop.req

Appendix: Viewing certificate contents

~ openssl rsa -noout -text -in file.key ~ openssl req -noout -text -in file.req ~ openssl x509 -noout -text -in file.crt