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. There are additional issuers, however we will solely examine HashiCorp Vault in this knowledge piece.
Scope
This article explains how to generate the Intermediate CA certificate in Kubernetes using the vault as the cert manager, in response to a handful of customer requests.
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
Configure the policy and assign it to the role you generated in the approle auth procedure.
The policy text is as follows
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 as mentioned 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
- Below is how it can be validated:
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
Run the below command to read secret for verification:
#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 :
