Using Hashicorp Vault as CA
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 = "http://192.168.1.10:443"
ui = true
storage "file" {
path = "/var/vault/data"
}
listener "tcp" {
address = "192.168.1.10:443"
tls_disable = 1
}
replace 192.168.1.10 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="https://192.168.1.10/v1/pki_root/ca" crl_distribution_points="https://192.168.1.10/v1/pki_root/crl"
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="192.168.1.10" 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 = "https://192.168.1.10"
ui = true
storage "file" {
path = "/var/vault/data"
}
listener "tcp" {
address = "192.168.1.10:443"
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