WARNING: This guide is intended for educational purposes. It is recommended to thoroughly review and adjust the content before applying it to production environments.
Introduction
Cert-manager is a Kubernetes third-party plugin that aids in the generation and administration of TLS certificates. Cert-manager can automate the creation and renewal of certificates for a wide range of use cases. As an issuer, Cert-manager also supports HashiCorp Vault. This document will focus on the use of HashiCorp Vault as an Issuer.
Scope
This article explains how to generate the Intermediate CA certificate in Kubernetes using the vault in Cert-Manager
Pre-requisite
- Enable pki secret engine for root CA as detailed here.
- Enable pki_int secret engine for intermediate CA as detailed here.
Implementation
Enable and setup the approle authentication mechanism as follows
vault auth enable approle vault write -f auth/approle/role/cert-role secret_id_ttl=768h token_ttl=768h token_max_ttl=768h token_policies=pki
The policy text is as follows
#I stored this policy under the name pki.
path "pki_int/root/sign-intermediate"
{ capabilities = ["create", "update"] } path "pki/*" { capabilities = ["read", "list"] }
Install Cert Manager
Follow the HashiCorp documentation for installing cert-manager here.
Create Issuer
- First, we build a role_id from approle, which we will supply later in the manifest file. We can also pass environment variables in the manifest.
vault read auth/approle/role/cert-role/role-id
- Then, using approle, generate a secret-id and save it in Kubernetes secret. Because the secret-id should not be provided directly into the file, referencing it from the Kubernetes secret is the best option.
vault write -f auth/approle/role/cert-role/secret-id
- Create Kubernetes secret to save.
kubectl create secret generic cert-manager-vault-approle --from-literal=secretId=f34da025-47f2-21e2-b28b-464c85b0981f
Content of Issuer manifest:
apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: vault-issuer-approle namespace: default spec: vault: path: pki_int/root/sign-intermediate server: http://vault.default:8200 auth: appRole: path: approle roleId: <approle-role-id> secretRef: name: cert-manager-vault-approle key: secretId
Validate Issuer
root@:~/vault-cert-manager/with-approle# kubectl get issuer
NAME READY AGE
vault-issuer-approle True 6d12h
Generate Intermediate Certificate
Content for the intermediate certificate generation manifest :
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: vault-cm-intermediate-cert namespace: default spec: secretName: vault-cm-intermediate-cert-tls issuerRef: name: vault-issuer-approle commonName: www.example.com dnsNames: - www.example.com usages: - digital signature - key encipherment - cert sign - client auth - server auth
Expected Output:
root@:~/vault-cert-manager/with-approle# kubectl get certificate
NAME READY SECRET AGE
vault-cm-intermediate-cert True vault-cm-intermediate-cert-tls 6d12h
Verify Secret
#This will display three blocks: ca.crt, tls.crt, and tls.key, where ca.crt is the intermediate CA from vault that signed the freshly created CA from Kubernetes using Vault as the cert manager.
kubectl get secret vault-cm-intermediate-cert-tls -o yaml
Run the openssl command to read the intermediate root certificate (tls.crt block), you will find "CA: True" in the output as below :
Additional Information
- HashiCorp Tutorial: Deploy Vault as a Cert Manager in Kubernetes