I use cookies in order to optimize my website and continually improve it. By continuing to use this site, you are agreeing to the use of cookies.
You can find an Opt-Out option and more details on the Privacy Page!

Use Vault-CRD with NGINX Ingress Controller Part II

In this Blog post I’ll show you how to use the Vault-CRD to share Certificates stored in Vault with Kubernetes

The Blog post is splitted into two parts.

  • Part I: The first part will show you how to use a PKI Secret Engine to generate NGINX Ingress Controller certificates.
  • Part II: The second part of this tutorial will show you how to setup and use Key-Value type for certificates that NGINX Ingress Controller can use

To get started please first read Part I of this tutorial.

Setup a simple Certificate

To make it easier I’ll reuse the PKI I’ve generated in the first Part of this blog post:

$ vault write -format=json testpki/issue/testrole  common_name=test-url.koudingspawn.de > data.json
$ vault write secret/test-url.koudingspawn.de @data.json

The interresting part here is, that the data has a special format, because the response is wrapped in a “data” Object everything that will be written has now a second “data” Object when you read it:

$ vault read -format=json secret/test-url.koudingspawn.de
{
  "request_id": "b2259df1-d1de-5218-4840-ea11e564a402",
  "lease_id": "",
  "lease_duration": 2764800,
  "renewable": false,
  "data": {
    "data": {
      "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
      "issuing_ca": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
      "private_key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
      "private_key_type": "rsa",
      "serial_number": "62:98:DE:39:66:7C:A4:72:DF:FC:80:3A:71:27:3F:AD:E7:87:4A:98"
    },
    "lease_duration": 0,
    "lease_id": "",
    "renewable": false,
    "request_id": "478ae6d3-2913-39ce-3a14-8f2de523637e",
    "warnings": null
  },
  "warnings": null
}

After you applied the new secret you can generate the new Vault-CRD type:

apiVersion: "koudingspawn.de/v1"
kind: Vault
metadata:
  name: ingress-ssl-certificate
  namespace: vault-crd
spec:
  path: "secret/test-url.koudingspawn.de"
  type: "CERT"

What will happen now

As you can now see inside the Vault-CRD logs, that it detects the updated Vault-Resource in namespace vault-crd with name ingress-ssl-certificate. Now Vault-CRD tries to access your Vault and requests the secret secret/test-url.koudingspawn.de. After this it updates the secret we already generated in the first Part of the Blog Post.

Refresh the certificate

From time to time a certificate expires and must be renewed. To do this you can now change the certificate in Vault for example with the same command that we used to generate the first certificate:

$ vault write -format=json testpki/issue/testrole  common_name=test-url.koudingspawn.de > data.json
$ vault write secret/test-url.koudingspawn.de @data.json

Now Vault-CRD will detect in his specified refresh interval a change in Vault and will now update the secret in Kubernetes. This secret update will be detected by NGINX Ingress Controller and the Controller will now reload the Secret from Kubernetes:

I0505 18:35:02.732775       5 store.go:375] secret vault-crd/ingress-ssl-certificate was updated and it is used in ingress annotations. Parsing...
I0505 18:35:02.736128       5 backend_ssl.go:59] updating secret vault-crd/ingress-ssl-certificate in the local store
I0505 18:35:02.736653       5 controller.go:168] backend reload required
I0505 18:35:02.914816       5 controller.go:177] ingress backend successfully reloaded...
I0505 18:35:28.340035       5 backend_ssl.go:173] updating local copy of ssl certificate vault-crd/ingress-ssl-certificate with missing intermediate CA certs
I0505 18:35:28.340265       5 controller.go:168] backend reload required
I0505 18:35:28.479019       5 controller.go:177] ingress backend successfully reloaded...

You can also see with an openssl command that the certificate has changed from:

$ openssl s_client -servername test-url.koudingspawn.de -connect test-url.koudingspawn.de:30443 < /dev/null 2>/dev/null  | openssl x509 -fingerprint -noout -in /dev/stdin
SHA1 Fingerprint=62:98:DE:39:66:7C:A4:72:DF:FC:80:3A:71:27:3F:AD:E7:87:4A:98

to this:

$ openssl s_client -servername test-url.koudingspawn.de -connect test-url.koudingspawn.de:30443 < /dev/null 2>/dev/null  | openssl x509 -fingerprint -noout -in /dev/stdin
SHA1 Fingerprint=28:43:64:87:C5:48:B8:B9:ED:5D:D6:B8:B3:17:0A:64:ED:1D:05:81

For more information please also see: Vault-CRD.

Björn Wenzel

Björn Wenzel

My name is Björn Wenzel. I’m a Platform Engineer working for Schenker with interests in Kubernetes, CI/CD, Spring and NodeJS.