From 397ca243436dea6501cea852caeae48a4a1de15b Mon Sep 17 00:00:00 2001 From: Carl Tashian Date: Mon, 31 Jan 2022 14:09:51 -0800 Subject: [PATCH] CA install WIP --- docs/02-client-tools.md | 58 ++--- docs/04-certificate-authority.md | 354 +++++++++++++++++++++++-------- 2 files changed, 282 insertions(+), 130 deletions(-) diff --git a/docs/02-client-tools.md b/docs/02-client-tools.md index 94d93be..1590210 100644 --- a/docs/02-client-tools.md +++ b/docs/02-client-tools.md @@ -1,72 +1,56 @@ # Installing the Client Tools -In this lab you will install the command line utilities required to complete this tutorial: [cfssl](https://github.com/cloudflare/cfssl), [cfssljson](https://github.com/cloudflare/cfssl), and [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl). +In this lab you will install the command line utilities required to complete this tutorial: [step](https://github.com/smallstep/cli), and [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl). ## Install CFSSL -The `cfssl` and `cfssljson` command line utilities will be used to provision a [PKI Infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) and generate TLS certificates. +The `step` command line utility will be used to provision a [PKI Infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) and generate TLS certificates. -Download and install `cfssl` and `cfssljson`: +Download and install `step`: ### OS X -``` -curl -o cfssl https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/darwin/cfssl -curl -o cfssljson https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/darwin/cfssljson -``` +For Intel chips: ``` -chmod +x cfssl cfssljson +curl -L https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_darwin_0.18.0_amd64.tar.gz | tar xz +sudo mv step_0.18.0/bin/step /usr/local/bin/ ``` -``` -sudo mv cfssl cfssljson /usr/local/bin/ -``` - -Some OS X users may experience problems using the pre-built binaries in which case [Homebrew](https://brew.sh) might be a better option: +For Apple Silicon: ``` -brew install cfssl +curl -L https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_darwin_0.18.0_arm64.tar.gz | tar xz +sudo mv step_0.18.0/bin/step /usr/local/bin/ +``` + +Or, if you'd like to use [Homebrew](https://brew.sh): + +``` +brew install step ``` ### Linux ``` -wget -q --show-progress --https-only --timestamping \ - https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssl \ - https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssljson -``` - -``` -chmod +x cfssl cfssljson -``` - -``` -sudo mv cfssl cfssljson /usr/local/bin/ +curl -L https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_linux_0.18.0_amd64.tar.gz +sudo mv step_0.18.0/bin/step /usr/local/bin/ ``` ### Verification -Verify `cfssl` and `cfssljson` version 1.4.1 or higher is installed: +Verify `step` version 0.18.0 or higher is installed: ``` -cfssl version +step version ``` > output ``` -Version: 1.4.1 -Runtime: go1.12.12 -``` - -``` -cfssljson --version -``` -``` -Version: 1.4.1 -Runtime: go1.12.12 +Smallstep CLI/0.18.0 (linux/amd64) +Release Date: 2021-11-17 21:15 UTC ``` ## Install kubectl diff --git a/docs/04-certificate-authority.md b/docs/04-certificate-authority.md index 1510993..da38fe2 100644 --- a/docs/04-certificate-authority.md +++ b/docs/04-certificate-authority.md @@ -1,100 +1,280 @@ -# Provisioning a CA and Generating TLS Certificates +# Provisioning a CA -In this lab you will provision a [PKI Infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) using CloudFlare's PKI toolkit, [cfssl](https://github.com/cloudflare/cfssl), then use it to bootstrap a Certificate Authority, and generate TLS certificates for the following components: etcd, kube-apiserver, kube-controller-manager, kube-scheduler, kubelet, and kube-proxy. +In this lab you will provision a [PKI Infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) using Smallstep's CA server, [`step-ca`](https://github.com/smallstep/certificates), and generate TLS certificates for the following components: etcd, kube-apiserver, kube-controller-manager, kube-scheduler, kubelet, and kube-proxy. ## Certificate Authority -In this section you will provision a Certificate Authority that can be used to generate additional TLS certificates. +In this section you will provision a `step-ca` Certificate Authority that can be used to generate additional TLS certificates. The CA will only run on `controller-0`. While it's possible to run a high-availability CA across multiple nodes, it's not necessary in a small-to-medium sized Kubernetes cluster. The CA service would have to be down for several days before having any negative impact on the cluster. -Generate the CA configuration file, certificate, and private key: +Connect to `controller-0`: + +``` +gcloud compute ssh controller-0 +``` + +Download the `step` client and `step-ca` server binaries, and the `jq` command: ``` { - -cat > ca-config.json < /dev/null +< /dev/urandom tr -dc A-Za-z0-9 | head -c40 > provisioner-password +umask 002 +} +``` + +Initialize your PKI: + +``` +{ +INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \ +http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip) +EXTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip) +INTERNAL_HOSTNAME=$(hostname -f) +sudo -E step ca init --name="admin" \ + --dns="$INTERNAL_IP,$INTERNAL_HOSTNAME,$EXTERNAL_IP" \ + --address=":4443" --provisioner="kubernetes" \ + --password-file="$(step path)/password" \ + --provisioner-password-file="provisioner-password" +sudo -E step ca provisioner add acme --type ACME +} +``` + +Configure the CA provisioner to issue 90-day certificates: + +``` +{ +sudo jq '(.authority.provisioners[]) += { + "claims": { + "maxTLSCertDuration": "2160h", + "defaultTLSCertDuration": "2160h" + } +}' /etc/step-ca/config/ca.json > ca-new.json +sudo mv ca-new.json /etc/step-ca/config/ca.json +} +``` + +Put the CA configuration into place, and add the CA to systemd: + +``` +{ +sudo chown -R step:step /etc/step-ca +cat < ca-csr.json < /dev/null +``` + +Finally, start the CA service: + +``` { - "CN": "Kubernetes", - "key": { - "algo": "rsa", - "size": 2048 - }, - "names": [ - { - "C": "US", - "L": "Portland", - "O": "Kubernetes", - "OU": "CA", - "ST": "Oregon" - } - ] -} -EOF - -cfssl gencert -initca ca-csr.json | cfssljson -bare ca - +sudo systemctl daemon-reload +sudo systemctl enable --now step-ca } ``` -Results: +## Verification + +Check the CA health, then request and save the CA root certificate: + +``` +sudo -u step -E step ca health +``` + +Output: + +``` +ok +``` + +You can now sign out of `controller-0`. + +# Generating certificates + +## Bootstrapping with the CA + +### Bootstrapping your local machine + +Run the following on your local machine. + +Download your CA's root certificate: + +``` +gcloud compute scp controller-0:ca.pem controller-0:provisioner-password . +``` + +Result: ``` -ca-key.pem ca.pem +provisioner-password ``` +Now bootstrap with your CA: + +``` +{ +CA_IP=$(gcloud compute instances describe controller-0 \ + --format='get(networkInterfaces[0].accessConfigs[0].natIP)') +step ca bootstrap --ca-url "https://$CA_IP:4443/" --fingerprint $(step certificate fingerprint ca.pem) +} +``` + +Output: + +``` +The root certificate has been saved in /home/carl/.step/authorities/XX.XXX.XXX.XXX/certs/root_ca.crt. +The authority configuration has been saved in /home/carl/.step/authorities/XX.XXX.XXX.XXX/config/defaults.json. +The profile configuration has been saved in /home/carl/.step/profiles/XX.XXX.XXX.XXX/config/defaults.json. +``` + +Add your CA URL and fingerprint to the project metadata on GCP, so instances can bootstrap: + +``` +gcloud compute project-info add-metadata --metadata="STEP_CA_URL=https://10.240.0.10:4443,STEP_CA_FINGERPRINT=$(step certificate fingerprint ca.pem)" +``` + +Output: + +``` +Updated [https://www.googleapis.com/compute/v1/projects/project-id-xxxxxx]. +``` + +### Bootstrapping remote instances + + +Run each command on every node: + +``` +{ +for i in 0 1 2; do + gcloud compute ssh worker-${i} -- \ + step ca bootstrap \ + --ca-url "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_URL)" \ + --fingerprint "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_FINGERPRINT)" + gcloud compute ssh worker-${i} -- \ + step ca bootstrap \ + --ca-url "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_URL)" \ + --fingerprint "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_FINGERPRINT)" +done +} +``` + +Output: + +``` +The root certificate has been saved in /home/carl/.step/certs/root_ca.crt. +The authority configuration has been saved in /home/carl/.step/config/defaults.json. +``` + + ## Client and Server Certificates In this section you will generate client and server certificates for each Kubernetes component and a client certificate for the Kubernetes `admin` user. ### The Admin Client Certificate -Generate the `admin` client certificate and private key: +On your local machine, generate the `admin` client certificate and private key: ``` { - -cat > admin-csr.json < ${instance}-csr.json <