CA install WIP
parent
79a3f79b27
commit
397ca24343
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
```
|
||||
{
|
||||
wget -q --show-progress --https-only --timestamping \
|
||||
"https://dl.step.sm/gh-release/certificates/gh-release-header/v0.18.0/step-ca_linux_0.18.0_amd64.tar.gz"
|
||||
wget -q --show-progress --https-only --timestamping \
|
||||
"https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_linux_0.18.0_amd64.tar.gz"
|
||||
sudo apt update
|
||||
sudo apt install -y jq
|
||||
}
|
||||
```
|
||||
|
||||
cat > ca-config.json <<EOF
|
||||
Install the binaries:
|
||||
|
||||
```
|
||||
{
|
||||
"signing": {
|
||||
"default": {
|
||||
"expiry": "8760h"
|
||||
},
|
||||
"profiles": {
|
||||
"kubernetes": {
|
||||
"usages": ["signing", "key encipherment", "server auth", "client auth"],
|
||||
"expiry": "8760h"
|
||||
tar -xvf step-ca_linux_0.18.0_amd64.tar.gz
|
||||
sudo mv step-ca_0.18.0/bin/* /usr/local/bin/
|
||||
tar -xvf step_linux_0.18.0_amd64.tar.gz
|
||||
sudo mv step_0.18.0/bin/* /usr/local/bin/
|
||||
}
|
||||
```
|
||||
|
||||
Now create a `step` user and the paths for `step-ca`:
|
||||
|
||||
```
|
||||
{
|
||||
sudo useradd --system --home /etc/step-ca --shell /bin/false step
|
||||
}
|
||||
```
|
||||
|
||||
Create a CA configuration folder and generate passwords for the CA root key and the CA provisioner:
|
||||
|
||||
```
|
||||
{
|
||||
export STEPPATH=/etc/step-ca
|
||||
umask 077
|
||||
sudo mkdir -p $(step path)/db
|
||||
< /dev/urandom tr -dc A-Za-z0-9 | head -c40 | sudo tee $(step path)/password > /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 <<EOF | sudo tee /etc/systemd/system/step-ca.service
|
||||
[Unit]
|
||||
Description=step-ca service
|
||||
Documentation=https://smallstep.com/docs/step-ca
|
||||
Documentation=https://smallstep.com/docs/step-ca/certificate-authority-server-production
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
StartLimitIntervalSec=30
|
||||
StartLimitBurst=3
|
||||
ConditionFileNotEmpty=/etc/step-ca/config/ca.json
|
||||
ConditionFileNotEmpty=/etc/step-ca/password
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=step
|
||||
Group=step
|
||||
Environment=STEPPATH=/etc/step-ca
|
||||
WorkingDirectory=/etc/step-ca
|
||||
ExecStart=/usr/local/bin/step-ca config/ca.json --password-file password
|
||||
ExecReload=/bin/kill --signal HUP $MAINPID
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
TimeoutStopSec=30
|
||||
StartLimitInterval=30
|
||||
StartLimitBurst=3
|
||||
|
||||
; Process capabilities & privileges
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
SecureBits=keep-caps
|
||||
NoNewPrivileges=yes
|
||||
|
||||
; Sandboxing
|
||||
ProtectSystem=full
|
||||
ProtectHome=true
|
||||
RestrictNamespaces=true
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
PrivateTmp=true
|
||||
ProtectClock=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelLogs=true
|
||||
ProtectKernelModules=true
|
||||
LockPersonality=true
|
||||
RestrictSUIDSGID=true
|
||||
RemoveIPC=true
|
||||
RestrictRealtime=true
|
||||
PrivateDevices=true
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallArchitectures=native
|
||||
MemoryDenyWriteExecute=true
|
||||
ReadWriteDirectories=/etc/step-ca/db
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat > ca-csr.json <<EOF
|
||||
{
|
||||
"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
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Results:
|
||||
Save the root CA certificate:
|
||||
|
||||
```
|
||||
sudo cat /etc/step-ca/certs/root_ca.crt | tee ca.pem > /dev/null
|
||||
```
|
||||
|
||||
Finally, start the CA service:
|
||||
|
||||
```
|
||||
{
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now step-ca
|
||||
}
|
||||
```
|
||||
|
||||
## 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 <<EOF
|
||||
{
|
||||
"CN": "admin",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [
|
||||
{
|
||||
"C": "US",
|
||||
"L": "Portland",
|
||||
"O": "system:masters",
|
||||
"OU": "Kubernetes The Hard Way",
|
||||
"ST": "Oregon"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
cfssl gencert \
|
||||
-ca=ca.pem \
|
||||
-ca-key=ca-key.pem \
|
||||
-config=ca-config.json \
|
||||
-profile=kubernetes \
|
||||
admin-csr.json | cfssljson -bare admin
|
||||
|
||||
step ca certificate admin admin.pem admin-key.pem \
|
||||
--provisioner="kubernetes" \
|
||||
--provisioner-password-file="provisioner-password"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -113,24 +293,6 @@ Generate a certificate and private key for each Kubernetes worker node:
|
|||
|
||||
```
|
||||
for instance in worker-0 worker-1 worker-2; do
|
||||
cat > ${instance}-csr.json <<EOF
|
||||
{
|
||||
"CN": "system:node:${instance}",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [
|
||||
{
|
||||
"C": "US",
|
||||
"L": "Portland",
|
||||
"O": "system:nodes",
|
||||
"OU": "Kubernetes The Hard Way",
|
||||
"ST": "Oregon"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
|
||||
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
|
||||
|
@ -138,13 +300,7 @@ EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
|
|||
INTERNAL_IP=$(gcloud compute instances describe ${instance} \
|
||||
--format 'value(networkInterfaces[0].networkIP)')
|
||||
|
||||
cfssl gencert \
|
||||
-ca=ca.pem \
|
||||
-ca-key=ca-key.pem \
|
||||
-config=ca-config.json \
|
||||
-hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \
|
||||
-profile=kubernetes \
|
||||
${instance}-csr.json | cfssljson -bare ${instance}
|
||||
step ca certificate "system:node:${instance}" ${instance}.pem ${instance}-key.pem --san "${instance}" --san "${EXTERNAL_IP}" --san "${INTERNAL_IP}" --provisioner "kubernetes" --provisioner-password-file "provisioner-password"
|
||||
done
|
||||
```
|
||||
|
||||
|
@ -159,6 +315,18 @@ worker-2-key.pem
|
|||
worker-2.pem
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### The Controller Manager Client Certificate
|
||||
|
||||
Generate the `kube-controller-manager` client certificate and private key:
|
||||
|
|
Loading…
Reference in New Issue