I have small server with few virtual machines at home, and more as an exercise, I decided to have local certificate authority, and to have few web servers in local network use HTTPS.

Since that certificates will be self signed, I’ll need to install CA certificate as trusted publisher on my laptop, but more on that later.

I had already tried with CFSSL, but it didn’t sit right with me, and I recently stumbled upon Hashicorp Vault. After playing with it and learning it, it looks like it will work for me. So, this post is just steps that I took to setup Vault. It will follow official tutorial, but adopted to my liking.

Just follow first part of Getting started tutorial from Hashicorp, and when vault is working on machine, come back here.

I have setup that vault binary is in /opt/vault/bin, there is vault user, without any special permissions, and group, and /var/vault is it’s home folder, and vault is run under vault user.

First configuration for vault is in /var/vault/config.hcl

api_addr = ""
ui = true

storage "file" {
  path = "/var/vault/data"

listener "tcp" {
 address     = ""
 tls_disable = 1

replace with IP of your vault installation

tls is disabled for now, because when vault is up and running, I’ll create certificate for vault from it self, and than enable ssl.

After this configuration is written, you can start vault with above config.

Vault is currently uninitialized, so now follow Deploying vault to initialize vault.

Now, when vault is up, running, initialized and unsealed, we can start with real work.

First thing, pki secrets engine needs to be enabled and mounted.

vault secrets enable -path=pki_root pki

After that, few settings to adjust

vault secrets tune -max-lease-ttl=87600h  pki_root/

And, finally, generate root CA

vault write pki_root/root/generate/internal common_name=vault ttl=87600h key_type=ec key_bits=384

Here, I’m setting TTL of 10 years, and using ECDSA key type with 384 bit pirvate key (secp384r1).

From output of this command, copy value of key certificate, and save it to some file.

Now, maybe it’s not good practice, but I’ll generate certificate for vault server directly from root CA.

First, setup URL for OCSP and CRL endpoints. I’ll define them as HTTPS, because after we create this certificate, it will be over HTTPS…

vault write pki_root/config/urls issuing_certificates="" crl_distribution_points=""

Create role for generating certificate (will delete it later, so rootCA cannot be used to issue another certificate…)

vault write pki_root/roles/lan \
    allowed_domains=lan \
    allow_subdomains=true max_ttl=87600h \
    allow_ip_sans=true allowed_uri_sans="*.lan" \
    key_type=ec key_bits=384 \
    client_flag=false server_flag=true \
    code_signing_flag=false email_protection_flag=false

And finally, issue certificate

vault write pki_root/issue/lan \
    common_name=vault.lan ttl=87500h \
    ip_sans="" uri_sans="vault.lan"

From output, save value of certificate key as certificate.pem in home folder of vault user (/var/vault), and value of private_key as key.pem in home folder of vault user. Now, modify config.hcl to enable TLS and include certificate and private key, and update api_addr to HTTPS

api_addr = ""
ui = true

storage "file" {
  path = "/var/vault/data"

listener "tcp" {
 address     = ""
 tls_disable = 0
 tls_cert_file = "/var/vault/certificate.pem"
 tls_key_file = "/var/vault/key.pem"

Now just restart vault service, and that should be it! But it isn’t… Since this certificate for vault server is signed by self-signed root CA, your system doesn’t trust it. So, either save it to systems CA chain, or export VAULT_CACERT variable, which points to saved rootCA certificate

export VAULT_CACERT=~/certs/vault_rootCA.pem

In next post, I’ll write how to create intermediate CA, and use it to create server and client certificates.

P.S. If you want to delete role on rootCA that enables creation of certificates, execute following command

vault delete pki_root/roles/lan