From 111c3eaabec08cbb395334ba9669eee13abbf798 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Tue, 1 Feb 2022 12:00:01 -0500 Subject: [PATCH] Update TLS doc to use example signer for arbitrary https server --- .../tasks/tls/managing-tls-in-a-cluster.md | 157 +++++++++++++++--- .../examples/tls/server-signing-config.json | 15 ++ 2 files changed, 145 insertions(+), 27 deletions(-) create mode 100644 content/en/examples/tls/server-signing-config.json diff --git a/content/en/docs/tasks/tls/managing-tls-in-a-cluster.md b/content/en/docs/tasks/tls/managing-tls-in-a-cluster.md index de3b8fc09d..e715de5fd1 100644 --- a/content/en/docs/tasks/tls/managing-tls-in-a-cluster.md +++ b/content/en/docs/tasks/tls/managing-tls-in-a-cluster.md @@ -76,16 +76,11 @@ cat < Annotations: -CreationTimestamp: Tue, 21 Mar 2017 07:03:51 -0700 +CreationTimestamp: Tue, 01 Feb 2022 11:49:15 -0500 Requesting User: yourname@example.com +Signer: example.com/serving Status: Pending Subject: - Common Name: my-svc.my-namespace.svc.cluster.local + Common Name: my-pod.my-namespace.pod.cluster.local Serial Number: Subject Alternative Names: - DNS Names: my-svc.my-namespace.svc.cluster.local + DNS Names: my-pod.my-namespace.pod.cluster.local + my-svc.my-namespace.svc.cluster.local IP Addresses: 192.0.2.24 10.0.34.2 Events: @@ -175,30 +172,136 @@ kubectl certificate approve my-svc.my-namespace certificatesigningrequest.certificates.k8s.io/my-svc.my-namespace approved ``` - -## Download the Certificate and Use It - -Once the CSR is signed and approved you should see the following: +You should now see the following: ```shell kubectl get csr ``` ```none -NAME AGE REQUESTOR CONDITION -my-svc.my-namespace 10m yourname@example.com Approved,Issued +NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION +my-svc.my-namespace 10m example.com/serving yourname@example.com Approved ``` -You can download the issued certificate and save it to a `server.crt` file -by running the following: +This means the certificate request has been approved and is waiting for the +requested signer to sign it. + +## Sign the Certificate Signing Request + +Next, you'll play the part of a certificate signer, issue the certificate, and upload it to the API. + +A signer would typically watch the Certificate Signing Request API for objects with its `signerName`, +check that they have been approved, sign certificates for those requests, +and update the API object status with the issued certificate. + +### Create a Certificate Authority + +First, create a signing certificate by running the following: + +```shell +cat <}} + +Use a `server-signing-config.json` signing configuration and the certificate authority key file +and certificate to sign the certificate request: + +```shell +kubectl get csr my-svc.my-namespace -o jsonpath='{.spec.request}' | \ + base64 --decode | \ + cfssl sign -ca ca.pem -ca-key ca-key.pem -config server-signing-config.json - | \ + cfssljson -bare ca-signed-server +``` + +You should see the output similar to: + +``` +2022/02/01 11:52:26 [INFO] signed certificate with serial number 576048928624926584381415936700914530534472870337 +``` + +This produces a signed serving certificate file, `ca-signed-server.pem`. + +### Upload the Signed Certificate + +Finally, populate the signed certificate in the API object's status: + +```shell +kubectl get csr my-svc.my-namespace -o json | \ + jq '.status.certificate = "'$(base64 ca-signed-server.pem | tr -d '\n')'"' | \ + kubectl replace --raw /apis/certificates.k8s.io/v1/certificatesigningrequests/my-svc.my-namespace/status -f - +``` + +{{< note >}} +This uses the command line tool [jq](https://stedolan.github.io/jq/) to populate the base64-encoded content in the `.status.certificate` field. +If you do not have `jq`, you can also save the JSON output to a file, populate this field manually, and upload the resulting file. +{{< /note >}} + +Once the CSR is approved and the signed certificate is uploaded you should see the following: + +```shell +kubectl get csr +``` + +```none +NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION +my-svc.my-namespace 20m example.com/serving yourname@example.com Approved,Issued +``` + +## Download the Certificate and Use It + +Now, as the requesting user, you can download the issued certificate +and save it to a `server.crt` file by running the following: ```shell kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \ | base64 --decode > server.crt ``` -Now you can use `server.crt` and `server-key.pem` as the keypair to start -your HTTPS server. +Now you can populate `server.crt` and `server-key.pem` in a secret and mount +it into a pod to use as the keypair to start your HTTPS server: + +```shell +kubectl create secret tls server --cert server.crt --key server-key.pem +``` + +```none +secret/server created +``` + +Finally, you can populate `ca.pem` in a configmap and use it as the trust root +to verify the serving certificate: + +```shell +kubectl create configmap example-serving-ca --from-file ca.crt=ca.pem +``` + +```none +configmap/example-serving-ca created +``` ## Approving Certificate Signing Requests diff --git a/content/en/examples/tls/server-signing-config.json b/content/en/examples/tls/server-signing-config.json new file mode 100644 index 0000000000..86860d7369 --- /dev/null +++ b/content/en/examples/tls/server-signing-config.json @@ -0,0 +1,15 @@ +{ + "signing": { + "default": { + "usages": [ + "digital signature", + "key encipherment", + "server auth" + ], + "expiry": "876000h", + "ca_constraint": { + "is_ca": false + } + } + } +} \ No newline at end of file