Ensure Etcd Pod Specification File Ownership Is Root
More Info:
Ensure that the /etc/kubernetes/manifests/etcd.yaml file ownership is set to root:root.
Risk Level
Low
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every control plane node, confirm the etcd manifest exists and view its current ownership:
ls -l /etc/kubernetes/manifests/etcd.yaml -
On every control plane node, set the file owner and group to root:
sudo chown root:root /etc/kubernetes/manifests/etcd.yaml -
(Optional) Re-check the file metadata directly:
stat /etc/kubernetes/manifests/etcd.yaml -
On every control plane node, verify the fix using the benchmark audit command:
/bin/sh -c 'if test -e /etc/kubernetes/manifests/etcd.yaml; then find /etc/kubernetes/manifests/etcd.yaml -name '*etcd*' | xargs stat -c %U:%G; fi'Confirm the output is:
root:root
Using kubectl
kubectl cannot modify host filesystem permissions or ownership, so it cannot be used to change /etc/kubernetes/manifests/etcd.yaml to root:root. This must be fixed directly on every control plane node at the OS level; see the Manual Steps section for the required commands.
Automation
#!/usr/bin/env bash
#
# Fix ownership of the etcd static pod manifest on every control plane node.
# Usage:
# 1) Copy this script to each control plane node and run with sudo, OR
# 2) From an admin machine with SSH access, use the "SSH fan-out" mode below.
#
# This script is idempotent and safe to re-run.
set -euo pipefail
ETCD_MANIFEST="/etc/kubernetes/manifests/etcd.yaml"
run_local() {
echo "==> Running on local host: $(hostname -f || hostname)"
if [ ! -e "$ETCD_MANIFEST" ]; then
echo " [INFO] $ETCD_MANIFEST does not exist on this node; nothing to do."
return 0
fi
# Show current ownership
current_own="$(stat -c '%U:%G' "$ETCD_MANIFEST")" || {
echo " [ERROR] Unable to stat $ETCD_MANIFEST"
return 1
}
echo " Current ownership: $current_own"
# Fix ownership to root:root if needed
if [ "$current_own" != "root:root" ]; then
echo " Changing ownership to root:root ..."
chown root:root "$ETCD_MANIFEST"
else
echo " Ownership already root:root; no change needed."
fi
# Verification (matches the audit intent)
echo " Verifying ownership..."
verify="$(
/bin/sh -c '
if test -e /etc/kubernetes/manifests/etcd.yaml; then
find /etc/kubernetes/manifests/etcd.yaml -name "*etcd*" | xargs stat -c %U:%G
fi
'
)"
echo " Audit output: $verify"
if [ "$verify" != "root:root" ]; then
echo " [ERROR] Verification failed: expected root:root"
return 1
fi
echo " [OK] $ETCD_MANIFEST is owned by root:root"
}
run_ssh_fanout() {
# Fan-out mode: run the local fix on multiple control plane nodes via SSH.
# Usage example from an admin machine:
# CONTROL_PLANE_NODES="cp1.example.com cp2.example.com" ./this_script.sh fanout
#
# Requires passwordless SSH or suitable auth to each host.
: "${CONTROL_PLANE_NODES:?Set CONTROL_PLANE_NODES='node1 node2 ...' for fanout mode}"
for node in $CONTROL_PLANE_NODES; do
echo "====> Connecting to control plane node: $node"
ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$node" 'bash -s' <<'EOF'
set -euo pipefail
ETCD_MANIFEST="/etc/kubernetes/manifests/etcd.yaml"
echo "==> Running on control plane node: $(hostname -f || hostname)"
if [ ! -e "$ETCD_MANIFEST" ]; then
echo " [INFO] $ETCD_MANIFEST does not exist on this node; nothing to do."
exit 0
fi
current_own="$(stat -c '%U:%G' "$ETCD_MANIFEST")" || {
echo " [ERROR] Unable to stat $ETCD_MANIFEST"
exit 1
}
echo " Current ownership: $current_own"
if [ "$current_own" != "root:root" ]; then
echo " Changing ownership to root:root ..."
sudo chown root:root "$ETCD_MANIFEST"
else
echo " Ownership already root:root; no change needed."
fi
echo " Verifying ownership..."
verify="$(
/bin/sh -c '
if test -e /etc/kubernetes/manifests/etcd.yaml; then
find /etc/kubernetes/manifests/etcd.yaml -name "*etcd*" | xargs stat -c %U:%G
fi
'
)"
echo " Audit output: $verify"
if [ "$verify" != "root:root" ]; then
echo " [ERROR] Verification failed: expected root:root"
exit 1
fi
echo " [OK] $ETCD_MANIFEST is owned by root:root"
EOF
echo
done
}
case "${1:-local}" in
local)
# Run directly on a control plane node (requires root or sudo privileges).
run_local
;;
fanout)
# Run from an admin machine to multiple control plane nodes via SSH.
run_ssh_fanout
;;
*)
echo "Usage: $0 [local|fanout]"
exit 1
;;
esac