Occasional blog posts from a random systems engineer

Automating SSL CA and certificates for CI/CD using easyrsa

· Read in about 2 min · (419 Words)

Whilst implementing basic end-to-end tests for, an open source Terraform-cloud alternative, Terrarun (https://github.com/matthewJohn/terrarun), I need to deploy the Hashicorp Terraform cloud agent. The agent (as well as the Terraform-cloud Terraform provider) require a trusted SSL certificate to correctly interact with the server.

I’ve deployed various solutions in the past, such as automated distribution of Letsencrypt certificates and Hashicorp Vault for generating complex PKI setups, but not had to deal with generating CA certs and server certificates in a fully automated method.

I read some articles, particularly the article from Digital Ocean (https://www.digitalocean.com/community/tutorials/how-to-set-up-and-configure-a-certificate-authority-ca-on-ubuntu-20-04). Though it had some methods for performing some parts without automation, it didn’t quite allow for full automation.

Though no complex, I wanted to document the resulting script, so that it could be re-used by others.

Automating CA certificate and server certificate creation

This script automates the following:

  • Installs necessary depdencies
  • Setup a directory for configuring the CA
  • Create the CA certificates and adds to trusted system CA certificates
  • Create server certificates
# Install easyrsa and ca-certificates
apt update
apt install --assume-yes easyrsa ca-certificates

# Create a directory to setup easyrsa and copy
# configs provided by upstream package
mkdir easy-rsa
cp -r /usr/share/easy-rsa/* ./easy-rsa/

# Capture PWD, or set to required destination
TARGET_DIRECTORY=`pwd`

pushd ./easy-rsa
    # Export environment variable to instruct
    # easyrsa to use values from 'vars' without
    # confirming the values
    export EASYRSA_BATCH=1

    # Initialise PKI
    ./easyrsa init-pki

    # Create vars file with desired attributes
    cat > ./pki/vars <<'EOF'
set_var EASYRSA_REQ_COUNTRY    "GB"
set_var EASYRSA_REQ_PROVINCE   "Hampshire"
set_var EASYRSA_REQ_CITY       "Southampton"
set_var EASYRSA_REQ_ORG        "Terrarun"
set_var EASYRSA_REQ_EMAIL      "admin@example.com"
set_var EASYRSA_REQ_OU         "Community"
set_var EASYRSA_REQ_CN         "mylocalsite"
set_var EASYRSA_ALGO           "ec"
set_var EASYRSA_DIGEST         "sha512"
EOF

    # Build the CA certificate
    ./easyrsa build-ca nopass

    # Copy the CA public key to ca-certificates directory and run update-ca-certificates
    # to allow it to be trusted by applications
    cp ./pki/ca.crt /usr/local/share/ca-certificates/
    update-ca-certificates

    # Generate private key for target server/application
    openssl genrsa -out $TARGET_DIRECTORY/private.pem

    # Generate certificate request - the important value to change is the CN
    # to the desired hostname ("mylocalsite" in this example)
    openssl req -new -key $TARGET_DIRECTORY/ssl/private.pem -out server.req -subj \
        /C=GB/ST=Hampshire/L=Southampton/O=Terrarun/OU=Community/CN=mylocalsite

    # Import the request into easyrsa and sign the certificate to generate
    # a signed public key
    ./easyrsa import-req ./server.req mylocalsite
    ./easyrsa sign-req server mylocalsite

    # Obtain the public key and remove any lines before the cert
    # that start with whitespace or 'Certificate'
    cat ./pki/issued/mylocalsite.crt | grep -Ev '^\s+' | grep -Ev '^Certificate' > $TARGET_DIRECTORY/public.pem
popd

Within the TARGET_DIRECTORY, the public and private keys can then be used… Done :)

Comments