completed upto lab 38

This commit is contained in:
Mosiur Rahman
2026-08-27 14:03:17 +06:00
parent d74b79cfc6
commit ac6292db20
19 changed files with 220 additions and 204 deletions

3
CKS-DASHBOARD.html Normal file
View File

@@ -0,0 +1,3 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>CKS mastery dashboard</title><link rel="stylesheet" href="assets/course.css"><style>
body{background:linear-gradient(135deg,#e8effd,#f7f9fc 50%,#e8f8f1);font-family:Arial,sans-serif}main{max-width:1050px!important;padding:0!important;overflow:hidden;border-radius:20px}.hero{padding:45px 52px;color:#fff;background:radial-gradient(circle at 90% 15%,#315da9,#0b1736 65%)}.hero h1{color:#fff;font-size:2.5rem}.hero .lede{color:#dce7ff}.hero .eyebrow{color:#75e0bd}.content{padding:34px 52px}.grid{display:grid;grid-template-columns:220px 1fr;gap:32px;align-items:center}.ring{width:190px;height:190px;position:relative;display:grid;place-items:center}.ring svg{width:190px;transform:rotate(-90deg)}circle{fill:none;stroke-width:14}.track{stroke:#edf0f5}.progress{stroke:#75e0bd;stroke-linecap:round;stroke-dasharray:503;stroke-dashoffset:75}.ring div{position:absolute;text-align:center}.ring b{display:block;font-size:2.2rem}.ring span,.muted{color:#667085;font-size:.8rem}.stats,.checks,.domains{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}.card,.check{padding:15px;border:1px solid #e6ebf2;border-radius:12px;background:#f8fafc}.card b{font-size:1.65rem;color:#0b1736}.card span{display:block;color:#667085;font-size:.7rem;text-transform:uppercase;margin-top:5px}h2{border:0!important;padding:0!important;margin:0;color:#0b1736}.title{display:flex;justify-content:space-between;align-items:baseline;border-bottom:1px solid #e6ebf2;margin:38px 0 14px;padding-bottom:9px}.domains{grid-template-columns:1fr 1fr}.domain{display:grid;grid-template-columns:135px 1fr 32px;gap:8px;align-items:center;font-size:.8rem;font-weight:bold}.bar{height:9px;background:#e8edf4;border-radius:9px;overflow:hidden}.bar i{display:block;height:100%;background:linear-gradient(90deg,#4c8df0,#75e0bd)}.check{padding-left:42px;position:relative;font-size:.84rem}.check:before{position:absolute;left:14px;top:14px;width:18px;height:18px;border-radius:50%;display:grid;place-items:center}.done:before{content:"✓";background:#75e0bd}.todo:before{content:"";border:2px solid #aeb8c9}.check small{display:block;color:#667085;margin-top:5px}.next{margin-top:38px;padding:25px 28px;border-radius:16px;background:linear-gradient(105deg,#f1f7ff,#f1fcf7);display:grid;grid-template-columns:1fr auto;gap:20px;align-items:center}.next a{padding:12px 16px;border-radius:8px;background:#0b1736;color:#fff;text-decoration:none;font-weight:bold;font-size:.85rem}@media(max-width:700px){main{margin:0!important;border-radius:0!important}.hero,.content{padding-left:24px;padding-right:24px}.grid,.stats,.checks,.domains,.next{grid-template-columns:1fr}.next a{text-align:center}}
</style></head><body><main><header class="hero"><p class="eyebrow">CKS mastery dashboard · updated 27 August 2026</p><h1>Build confidence into evidence.</h1><p class="lede">Lab ready · Kubernetes v1.34 · Linux tools installed · 2 CIS labs passed today</p></header><section class="content"><div class="grid"><div class="ring"><svg viewBox="0 0 190 190"><circle class="track" cx="95" cy="95" r="80"/><circle class="progress" cx="95" cy="95" r="80"/></svg><div><b>85%</b><span>topic coverage</span></div></div><div><h2>22 of 26 topics have practical training evidence.</h2><p class="muted">Hero is deliberately strict: tool drill, capstone, evidence, scope review, and cold retest.</p><div class="stats"><div class="card"><b>22</b><span>training</span></div><div class="card"><b>4</b><span>not started</span></div><div class="card"><b>0</b><span>heroes—yet</span></div></div></div></div><div class="title"><h2>Coverage by domain</h2><span class="muted">training / total</span></div><div class="domains"><div class="domain">Cluster Setup <div class="bar"><i style="width:100%"></i></div>5/5</div><div class="domain">Cluster Hardening <div class="bar"><i style="width:75%"></i></div>3/4</div><div class="domain">System Hardening <div class="bar"><i style="width:50%"></i></div>2/4</div><div class="domain">Microservices <div class="bar"><i style="width:100%"></i></div>4/4</div><div class="domain">Supply Chain <div class="bar"><i style="width:75%"></i></div>3/4</div><div class="domain">Monitoring & Runtime <div class="bar"><i style="width:100%"></i></div>5/5</div></div><div class="title"><h2>CS-02 Hero checklist</h2><span class="muted">CIS components</span></div><div class="checks"><div class="check done"><b>Tool drills</b><small>kube-bench, etcd, and kubelet practised</small></div><div class="check todo"><b>Timed capstone</b><small>multi-component remediation</small></div><div class="check todo"><b>Evidence & cold retest</b><small>saved PASS groups, then repeat later</small></div></div><section class="next"><div><p class="eyebrow">Next win</p><h2>CS-02.Q4 — secure CoreDNS component review</h2><p class="muted">Deployment, ServiceAccount, RBAC, ConfigMap, image, and security context.</p></div><a href="CKS-MASTERY-CHECKLIST.md">Open checklist</a></section><footer>Latest pass: Lesson 38 — five kubelet controls verified. · <a href="CKS-MASTERY-CHECKLIST.md">Canonical checklist</a></footer></section></main></body></html>

View File

@@ -58,18 +58,18 @@ Minor syntax corrections during training are expected. A cold retest fails when
## Next Task ## Next Task
Finish the one-time local lab installation after Windows restarts, then run `CS-02.Q1` as revised Lesson 0036 on `kind-cks-lab`. Do not use the learner's Kubernetes v1.36 production cluster: kube-bench v0.16.0 has automatic version mappings only through v1.34. Run `CS-02.Q4`: review CoreDNS deployment, ServiceAccount, RBAC, ConfigMap, image, and security context; distinguish CIS-relevant component configuration from workload hardening. Do not use the learner's Kubernetes v1.36 production cluster.
## Local Lab Environment ## Local Lab Environment
Status: `WINDOWS RESTART REQUIRED` Status: `READY`
- Platform: Ubuntu 24.04 on WSL2, Docker Engine, two-node Kind cluster, and Calico. - Platform: Ubuntu 24.04 on WSL2, Docker Engine, two-node Kind cluster, and Calico.
- Kubernetes: pinned to v1.34.0; kube-bench: pinned to v0.16.0. - Kubernetes: pinned to v1.34.0; kube-bench: pinned to v0.16.0.
- Cluster and context: `cks-lab` / `kind-cks-lab`. - Cluster and context: `cks-lab` / `kind-cks-lab`.
- Kubeconfig: `/opt/cks-lab/kubeconfig`; it is never merged with a production config. - Kubeconfig: `/opt/cks-lab/kubeconfig`; it is never merged with a production config.
- Setup and recovery files: `lab-environment/`. - Setup and recovery files: `lab-environment/`.
- Resume after restart: run `lab-environment\\02-install-and-build.ps1`, then `lab-environment\\verify-lab.ps1`. - Enter the ready lab with `lab-environment\\enter-lab.ps1`; verify or rebuild it with `lab-environment\\verify-lab.ps1` and `lab-environment\\02-install-and-build.ps1`.
- Lesson scope: use Kind nodes for Kubernetes tasks and the disposable Ubuntu WSL2 VM for host/kernel hardening tasks. - Lesson scope: use Kind nodes for Kubernetes tasks and the disposable Ubuntu WSL2 VM for host/kernel hardening tasks.
--- ---
@@ -603,6 +603,9 @@ Append one row after every graded attempt.
| Date | Task | Topic | Time | Result | Critical errors | Evidence | Next action | | Date | Task | Topic | Time | Result | Critical errors | Evidence | Next action |
|---|---|---|---:|---|---:|---|---| |---|---|---|---:|---|---:|---|---|
| 2026-08-27 | Lesson 0038 | CS-02 | Not recorded | Training pass | 0 after verifier correction | `lab/lesson-38-verify.sh /tmp/lesson-38-kubelet.yaml`: all PASS | Continue CS-02.Q4 |
| 2026-08-27 | Lesson 0037 | CS-02 | Not recorded | Training pass | 0 after one correction | `lab/lesson-37-verify.sh /tmp/lesson-37-etcd.yaml`: all PASS | Continue CS-02.Q3 |
| 2026-08-27 | Lesson 0036 | CS-02 | 90 minutes | Partial training evidence | etcd and worker checks not captured | `lab/lesson-36-controlplane-after.txt` shows 1.2.1 and 1.2.7 PASS | Run focused CS-02.Q2, then require PASS evidence |
| 2026-08-26 | Lesson 0035 | CH-03 / MR-05 | Not recorded | Training pass | 0 after review | `lab/lesson-35-kube-apiserver-answer.yaml`, `lab/lesson-35-audit-policy.yaml` | Cold retest later | | 2026-08-26 | Lesson 0035 | CH-03 / MR-05 | Not recorded | Training pass | 0 after review | `lab/lesson-35-kube-apiserver-answer.yaml`, `lab/lesson-35-audit-policy.yaml` | Cold retest later |
| 2026-08-26 | Lesson 0034 | CS-01 / MM-01 | Not recorded | Training pass | 0 after review | `lab/lesson-34-answer.yaml` | Cold retest later | | 2026-08-26 | Lesson 0034 | CS-01 / MM-01 | Not recorded | Training pass | 0 after review | `lab/lesson-34-answer.yaml` | Cold retest later |
| 2026-08-25 | Lesson 0032 | MR-03 | Not recorded | Training; evidence incomplete | 0 substantive; command omitted | `lab/lesson-32-answer.md` | Require structured query next time | | 2026-08-25 | Lesson 0032 | MR-03 | Not recorded | Training; evidence incomplete | 0 substantive; command omitted | `lab/lesson-32-answer.md` | Require structured query next time |

View File

@@ -0,0 +1,3 @@
# CKS training workspace
Start with the [CKS Mastery Dashboard](CKS-DASHBOARD.html). The [Mastery Checklist](CKS-MASTERY-CHECKLIST.md) is the canonical record of evidence, Hero gates, and the next task.

View File

@@ -20,7 +20,15 @@ EOF
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
apt-get update apt-get update
apt-get install -y ca-certificates curl gnupg jq vim git iproute2 iptables conntrack socat apt-get install -y \
bash-completion ca-certificates conntrack curl dnsutils git gnupg iproute2 \
iptables iputils-ping jq less lsof man-db nano netcat-openbsd procps psmisc \
socat strace tcpdump tree vim wget yq
cat >/etc/profile.d/cks-lab.sh <<'EOF'
alias k=kubectl
complete -o default -F __start_kubectl k 2>/dev/null || true
EOF
install -m 0755 -d /etc/apt/keyrings install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
@@ -45,20 +53,20 @@ curl -fsSLo "$tmp_dir/kubectl.sha256" "https://dl.k8s.io/release/${KUBECTL_VERSI
printf '%s %s\n' "$(cat "$tmp_dir/kubectl.sha256")" "$tmp_dir/kubectl" | sha256sum --check --status printf '%s %s\n' "$(cat "$tmp_dir/kubectl.sha256")" "$tmp_dir/kubectl" | sha256sum --check --status
install -m 0755 "$tmp_dir/kubectl" /usr/local/bin/kubectl install -m 0755 "$tmp_dir/kubectl" /usr/local/bin/kubectl
curl -fsSLo "$tmp_dir/kind" "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64" curl -fsSLo "$tmp_dir/kind-linux-amd64" "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64"
curl -fsSLo "$tmp_dir/kind.sha256sum" "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64.sha256sum" curl -fsSLo "$tmp_dir/kind.sha256sum" "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64.sha256sum"
(cd "$tmp_dir" && sha256sum --check --status kind.sha256sum) (cd "$tmp_dir" && sha256sum --check --status kind.sha256sum)
install -m 0755 "$tmp_dir/kind" /usr/local/bin/kind install -m 0755 "$tmp_dir/kind-linux-amd64" /usr/local/bin/kind
curl -fsSLo "$tmp_dir/kube-bench.tar.gz" \ curl -fsSLo "$tmp_dir/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz" \
"https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz" "https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz"
curl -fsSLo "$tmp_dir/checksums.txt" \ curl -fsSLo "$tmp_dir/checksums.txt" \
"https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_checksums.txt" "https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_checksums.txt"
(cd "$tmp_dir" && grep " kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz$" checksums.txt | sha256sum --check --status) (cd "$tmp_dir" && grep " kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz$" checksums.txt | sha256sum --check --status)
rm -rf /opt/cks-lab/tools/kube-bench rm -rf /opt/cks-lab/tools/kube-bench
install -d /opt/cks-lab/tools/kube-bench install -d /opt/cks-lab/tools/kube-bench
tar -xzf "$tmp_dir/kube-bench.tar.gz" -C /opt/cks-lab/tools/kube-bench tar -xzf "$tmp_dir/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz" -C /opt/cks-lab/tools/kube-bench
ln -sfn /opt/cks-lab/tools/kube-bench/kube-bench /usr/local/bin/kube-bench ln -sfn /opt/cks-lab/tools/kube-bench/kube-bench /usr/local/bin/kube-bench
printf 'Installed kubectl %s, Kind %s, and kube-bench %s.\n' \ printf 'Installed CKS command-line tools plus kubectl %s, Kind %s, and kube-bench %s.\n' \
"$KUBECTL_VERSION" "$KIND_VERSION" "$KUBE_BENCH_VERSION" "$KUBECTL_VERSION" "$KIND_VERSION" "$KUBE_BENCH_VERSION"

View File

@@ -31,9 +31,9 @@ if [[ "$context" != "kind-${CLUSTER_NAME}" ]]; then
exit 1 exit 1
fi fi
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/operator-crds.yaml" kubectl apply --server-side --validate=false -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/operator-crds.yaml"
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/tigera-operator.yaml" kubectl apply --server-side --validate=false -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/tigera-operator.yaml"
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/custom-resources.yaml" kubectl apply --server-side --validate=false -f "https://raw.githubusercontent.com/projectcalico/calico/${CALICO_VERSION}/manifests/custom-resources.yaml"
kubectl wait --for=condition=Available deployment/tigera-operator -n tigera-operator --timeout=300s kubectl wait --for=condition=Available deployment/tigera-operator -n tigera-operator --timeout=300s
kubectl wait --for=condition=Ready nodes --all --timeout=600s kubectl wait --for=condition=Ready nodes --all --timeout=600s
@@ -43,4 +43,3 @@ for node in "${CLUSTER_NAME}-control-plane" "${CLUSTER_NAME}-worker"; do
docker cp /opt/cks-lab/tools/kube-bench "$node":/opt/kube-bench docker cp /opt/cks-lab/tools/kube-bench "$node":/opt/kube-bench
docker exec "$node" /opt/kube-bench/kube-bench version docker exec "$node" /opt/kube-bench/kube-bench version
done done

View File

@@ -1,17 +1,9 @@
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
$distribution = 'Ubuntu-24.04' $distribution = 'Ubuntu-24.04'
$linuxScript = (& wsl.exe --distribution $distribution --user root --exec wslpath -a "$PSScriptRoot/enter-lab.sh").Trim()
if (-not $linuxScript) { throw 'Could not locate the Linux lab entry script.' }
& wsl.exe --distribution $distribution --user root --exec bash -lc @' & wsl.exe --distribution $distribution --user root --exec bash $linuxScript
export KUBECONFIG=/opt/cks-lab/kubeconfig
context="$(kubectl config current-context 2>/dev/null || true)"
if [[ "$context" != "kind-cks-lab" ]]; then
echo "Safety check failed: expected kind-cks-lab, got ${context:-none}." >&2
exit 1
fi
echo "CKS lab: $(kubectl version --output=json | jq -r .serverVersion.gitVersion)"
echo "Context: $context"
exec bash
'@
if ($LASTEXITCODE -ne 0) { throw 'Could not enter the isolated CKS lab.' } if ($LASTEXITCODE -ne 0) { throw 'Could not enter the isolated CKS lab.' }

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -Eeuo pipefail
export KUBECONFIG=/opt/cks-lab/kubeconfig
expected_context=kind-cks-lab
context="$(kubectl config current-context 2>/dev/null || true)"
if [[ "$context" != "$expected_context" ]]; then
echo "Safety check failed: expected $expected_context, got ${context:-none}." >&2
exit 1
fi
echo "CKS lab: $(kubectl version --output=json | jq -r .serverVersion.gitVersion)"
echo "Context: $context"
required_tools=(kubectl kube-bench nano vim curl wget jq yq dig nc ss ps less)
missing_tools=()
for tool in "${required_tools[@]}"; do
command -v "$tool" >/dev/null 2>&1 || missing_tools+=("$tool")
done
if (( ${#missing_tools[@]} )); then
echo "Lab setup incomplete; missing: ${missing_tools[*]}. Run ./02-install-and-build.ps1." >&2
exit 1
fi
echo "Tools: ready (nano, curl, wget, jq, yq, dig, nc, tcpdump, ss); alias k=kubectl"
exec bash

View File

@@ -0,0 +1,17 @@
root@cks-lab-control-plane:/opt/kube-bench# ./kube-bench --benchmark cis-1.12 --config-dir cfg run --targets master --check 1.2.1,1.2.7,2.2,2.3
[INFO] 1 Control Plane Security Configuration
[INFO] 1.2 API Server
[PASS] 1.2.1 Ensure that the --anonymous-auth argument is set to false (Manual)
[PASS] 1.2.7 Ensure that the --authorization-mode argument includes Node (Automated)
== Summary master ==
2 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
== Summary total ==
2 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO

View File

@@ -1,6 +1,7 @@
[INFO] 1 Control Plane Security Configuration [INFO] 1 Control Plane Security Configuration
[INFO] 1.2 API Server [INFO] 1.2 API Server
[WARN] 1.2.1 Ensure that the --anonymous-auth argument is set to false (Manual) [WARN] 1.2.1 Ensure that the --anonymous-auth argument is set to false (Manual)
[PASS] 1.2.7 Ensure that the --authorization-mode argument includes Node (Automated)
== Remediations master == == Remediations master ==
1.2.1 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml 1.2.1 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
@@ -9,191 +10,13 @@ on the control plane node and set the below parameter.
== Summary master == == Summary master ==
0 checks PASS 1 checks PASS
0 checks FAIL 0 checks FAIL
1 checks WARN 1 checks WARN
0 checks INFO 0 checks INFO
[INFO] 2 Etcd Node Configuration
== Summary etcd ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 3 Control Plane Configuration
== Summary controlplane ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 4 Worker Node Security Configuration
== Summary node ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 5 Kubernetes Policies
== Summary policies ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
== Summary total == == Summary total ==
0 checks PASS 1 checks PASS
0 checks FAIL 0 checks FAIL
1 checks WARN 1 checks WARN
0 checks INFO 0 checks INFO
[INFO] 1 Control Plane Security Configuration
[INFO] 1.2 API Server
[PASS] 1.2.7 Ensure that the --authorization-mode argument includes Node (Automated)
== Summary master ==
1 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 2 Etcd Node Configuration
== Summary etcd ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 3 Control Plane Configuration
== Summary controlplane ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 4 Worker Node Security Configuration
== Summary node ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 5 Kubernetes Policies
== Summary policies ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
== Summary total ==
1 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 1 Control Plane Security Configuration
== Summary master ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 2 Etcd Node Configuration
[INFO] 2 Etcd Node Configuration
[PASS] 2.2 Ensure that the --client-cert-auth argument is set to true (Automated)
== Summary etcd ==
1 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 3 Control Plane Configuration
== Summary controlplane ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 4 Worker Node Security Configuration
== Summary node ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 5 Kubernetes Policies
== Summary policies ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
== Summary total ==
1 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 1 Control Plane Security Configuration
== Summary master ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 2 Etcd Node Configuration
[INFO] 2 Etcd Node Configuration
[PASS] 2.3 Ensure that the --auto-tls argument is not set to true (Automated)
== Summary etcd ==
1 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 3 Control Plane Configuration
== Summary controlplane ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 4 Worker Node Security Configuration
== Summary node ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
[INFO] 5 Kubernetes Policies
== Summary policies ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
== Summary total ==
1 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO

View File

@@ -0,0 +1,15 @@
root@cks-lab-worker:/opt/kube-bench# ./kube-bench --benchmark cis-1.12 --config-dir cfg run --targets master --check 4.2.1,4.2.2,4.2.3
Warning: Kubernetes version was not auto-detected because kubectl could not connect to the Kubernetes server. This may be because the kubeconfig information is missing or has credentials that do not match the server. Assuming default version 1.18
[INFO] 1 Control Plane Security Configuration
== Summary master ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO
== Summary total ==
0 checks PASS
0 checks FAIL
0 checks WARN
0 checks INFO

View File

@@ -0,0 +1,47 @@
apiVersion: v1
kind: Pod
metadata:
name: etcd
namespace: kube-system
labels:
component: etcd
spec:
hostNetwork: true
containers:
- name: etcd
image: registry.k8s.io/etcd:3.6.4-0
command:
- etcd
- --name=controlplane
- --data-dir=/var/lib/etcd
- --listen-client-urls=http://127.0.0.1:2379,https://10.0.0.10:2379
- --advertise-client-urls=https://10.0.0.10:2379
- --initial-advertise-peer-urls=https://10.0.0.10:2380
- --listen-peer-urls=https://10.0.0.10:2380
- --initial-cluster=controlplane=https://10.0.0.10:2380
- --client-cert-auth=false
- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
- --cert-file=/etc/kubernetes/pki/etcd/server.crt
- --key-file=/etc/kubernetes/pki/etcd/server.key
- --auto-tls=true
- --peer-client-cert-auth=false
- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
- --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt
- --peer-key-file=/etc/kubernetes/pki/etcd/peer.key
- --peer-auto-tls=true
- --listen-metrics-urls=http://0.0.0.0:2381
volumeMounts:
- name: etcd-data
mountPath: /var/lib/etcd
- name: etcd-certs
mountPath: /etc/kubernetes/pki/etcd
readOnly: true
volumes:
- name: etcd-data
hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
- name: etcd-certs
hostPath:
path: /etc/kubernetes/pki/etcd
type: DirectoryOrCreate

28
lab/lesson-37-verify.sh Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -Eeuo pipefail
manifest=${1:?Usage: lesson-37-verify.sh PATH_TO_MANIFEST}
[[ -f "$manifest" ]] || { echo "FAIL manifest not found"; exit 1; }
required=(
'--client-cert-auth=true'
'--auto-tls=false'
'--peer-client-cert-auth=true'
'--peer-auto-tls=false'
'--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt'
'--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt'
'--listen-metrics-urls=http://127.0.0.1:2381'
)
for flag in "${required[@]}"; do
if grep -Fqx " - $flag" "$manifest"; then
echo "PASS $flag"
else
echo "FAIL $flag"
fi
done
if grep -Eq 'http://0\.0\.0\.0:2381|http://127\.0\.0\.1:2379' "$manifest"; then
echo 'FAIL insecure etcd listener remains'
else
echo 'PASS no insecure etcd listener'
fi

View File

@@ -0,0 +1 @@
/usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/tmp/lesson-38-kubelet.yaml --anonymous-auth=false --authentication-token-webhook=true --authorization-mode=Webhook --read-only-port=0 --rotate-certificates=true

View File

@@ -0,0 +1,11 @@
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
anonymous:
enabled: true
webhook:
enabled: false
authorization:
mode: AlwaysAllow
readOnlyPort: 10255
rotateCertificates: false

17
lab/lesson-38-verify.sh Normal file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -Eeuo pipefail
config=${1:?Usage: lesson-38-verify.sh PATH_TO_CONFIG}
[[ -f "$config" ]] || { echo "FAIL configuration not found"; exit 1; }
check() {
local label=$1 expected=$2 query=$3 actual
actual="$(yq -r "$query" "$config")"
if [[ "$actual" == "$expected" ]]; then echo "PASS $label"; else echo "FAIL $label (got: $actual)"; fi
}
check 'anonymous authentication disabled' false '.authentication.anonymous.enabled'
check 'webhook authentication enabled' true '.authentication.webhook.enabled'
check 'webhook authorization selected' Webhook '.authorization.mode'
check 'read-only port disabled' 0 '.readOnlyPort'
check 'certificate rotation enabled' true '.rotateCertificates'

View File

@@ -0,0 +1,7 @@
# etcd transport and metrics hardening
The learner independently remediated an etcd static manifest to require client and peer certificates, disable automatic TLS, eliminate HTTP client exposure, and bind metrics to loopback while preserving the existing CA and certificate paths. This establishes a reliable baseline for the next CIS drill: reconciling kubelet configuration with its effective process.
## Evidence
`lab/lesson-37-verify.sh /tmp/lesson-37-etcd.yaml` reported every required control as PASS on 2026-08-27.

View File

@@ -0,0 +1,7 @@
# Kubelet configuration and effective flags
The learner reconciled an insecure KubeletConfiguration with approved effective flags, independently setting anonymous authentication off, webhook authentication and authorization on, the read-only port to zero, and certificate rotation on. Future CIS practice can now combine configuration-file review with process-argument verification.
## Evidence
`lab/lesson-38-verify.sh /tmp/lesson-38-kubelet.yaml` reported all five controls as PASS on 2026-08-27.

View File

@@ -0,0 +1,4 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Lesson 37: etcd static-manifest hardening</title><link rel="stylesheet" href="../assets/course.css"></head><body><main><p class="eyebrow">Lesson 0037 · 15 minutes · Linux performance lab · Cluster Setup</p><h1>Harden etcd without breaking membership</h1><p class="lede">This is a focused CIS remediation drill. It deliberately removes the cluster-entry and package-installation friction from the previous attempt.</p><div class="callout"><strong>Scope discipline:</strong> change only the insecure transport, authentication, and metrics flags. Preserve identity, data, listen/advertise peer addresses, initial cluster membership, certificates, mounts, and image.</div><h2>Task</h2><p>On the Linux lab shell, create <code>/tmp/lesson-37-etcd.yaml</code> from <code>lab/lesson-37-etcd-insecure.yaml</code>. Make it pass the supplied verifier.</p><ul><li>Require client and peer client certificates.</li><li>Disable automatic TLS for both client and peer traffic.</li><li>Keep the existing explicit CA, certificate, and key paths.</li><li>Ensure client traffic uses HTTPS only.</li><li>Bind the metrics listener only to <code>127.0.0.1:2381</code>.</li></ul><p>Do not edit the original fixture or verifier. Do not use <code>kubectl apply</code>; this is a static-manifest file exercise.</p><h2>Start and prove it</h2><pre><code>cd /mnt/c/Cloud-Team/04_Learning_and_Reference/Training/CKS
cp lab/lesson-37-etcd-insecure.yaml /tmp/lesson-37-etcd.yaml
nano /tmp/lesson-37-etcd.yaml
bash lab/lesson-37-verify.sh /tmp/lesson-37-etcd.yaml</code></pre><p>Completion means every line reports <code>PASS</code>. Send that output only.</p><h2>Documentation</h2><p>Use the official <a href="https://etcd.io/docs/v3.6/op-guide/security/">etcd transport security guide</a> if needed. The CKS objective is preserving the required configuration while closing only the proven exposure.</p><footer>Previous: <a href="0036-kube-bench-cis-remediation.html">kube-bench CIS remediation</a> · Tracker: <a href="../CKS-MASTERY-CHECKLIST.md">CKS Mastery Checklist</a></footer></main></body></html>

View File

@@ -0,0 +1,6 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Lesson 38: kubelet effective configuration</title><link rel="stylesheet" href="../assets/course.css"></head><body><main><p class="eyebrow">Lesson 0038 · 15 minutes · Linux performance lab · Cluster Setup</p><h1>Reconcile kubelet configuration with effective flags</h1><p class="lede">Kubelet security faults often come from believing a configuration file is the whole truth. Inspect the effective arguments, then make the structured configuration agree with the required boundary.</p><div class="callout"><strong>Scope:</strong> the effective arguments in this task are the approved cluster policy. Correct the supplied <code>KubeletConfiguration</code>; do not change the argument file or add unrelated fields.</div><h2>Task</h2><p>On the Linux lab shell, create <code>/tmp/lesson-38-kubelet.yaml</code> from <code>lab/lesson-38-kubelet-config.yaml</code>. It must match the security posture expressed by <code>lab/lesson-38-effective-args.txt</code>.</p><p>Bring all five controls into agreement: anonymous authentication, webhook authentication, authorization mode, read-only port, and certificate rotation.</p><h2>Start and verify</h2><pre><code>cd /mnt/c/Cloud-Team/04_Learning_and_Reference/Training/CKS
cat lab/lesson-38-effective-args.txt
cp lab/lesson-38-kubelet-config.yaml /tmp/lesson-38-kubelet.yaml
nano /tmp/lesson-38-kubelet.yaml
bash lab/lesson-38-verify.sh /tmp/lesson-38-kubelet.yaml</code></pre><p>Completion means five <code>PASS</code> lines. Send only that output.</p><h2>Exam-speed inspection</h2><pre><code>docker exec cks-lab-worker ps -ef | grep '[k]ubelet'
docker exec cks-lab-worker sed -n '1,120p' /var/lib/kubelet/config.yaml</code></pre><p>Use these after the task to compare the fixture with the real disposable worker. Do not modify the live worker configuration for this drill.</p><footer>Previous: <a href="0037-etcd-static-manifest-hardening.html">etcd static-manifest hardening</a> · Tracker: <a href="../CKS-MASTERY-CHECKLIST.md">CKS Mastery Checklist</a></footer></main></body></html>