Kubelet Seccomp Default Parameter Set To True
More Info:
Enabling seccompDefault applies the RuntimeDefault seccomp profile to all workloads that do not specify one. This reduces the syscall attack surface available to containers by default.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every worker node, back up the current kubelet configuration file:
sudo cp -a /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak.$(date +%F-%H%M%S) -
On every worker node, edit
/var/lib/kubelet/config.yamlto enable the default seccomp profile. If theseccompDefaultfield exists, set it totrue; if not, add it underapiVersion/kind/...at the top level of the KubeletConfiguration:sudo sed -i 's/^seccompDefault:.*/seccompDefault: true/' /var/lib/kubelet/config.yaml || \echo "seccompDefault: true" | sudo tee -a /var/lib/kubelet/config.yamlThen open the file and confirm indentation and YAML validity:
sudo vi /var/lib/kubelet/config.yamlEnsure there is a line like:
seccompDefault: true -
On every worker node, ensure the kubelet is using the config file (adjust if your systemd unit differs). Inspect the kubelet systemd unit:
systemctl cat kubelet | sed -n '1,120p'Confirm either
--config=/var/lib/kubelet/config.yamlis present inExecStart, or add it by editing the drop-in or unit file per your distribution’s guidance. -
On every worker node, restart the kubelet to apply the change (this will disrupt pods on that node while they are rescheduled):
sudo systemctl daemon-reloadsudo systemctl restart kubeletsudo systemctl status kubelet --no-pager -
On every worker node, verify the kubelet process is running and pick out the node’s kubelet PID:
/bin/ps -fC kubelet -
On every worker node, confirm that
seccompDefaultis now set totruein the active configuration by checking the live config file and ensuring the kubelet process is healthy:grep -n 'seccompDefault' /var/lib/kubelet/config.yaml/bin/ps -fC kubelet
Using kubectl
kubectl cannot be used to enable seccompDefault for the kubelet because this setting is controlled entirely by host-level kubelet configuration and flags on every worker node (for example in /var/lib/kubelet/config.yaml or the kubelet systemd unit). To remediate this finding, follow the guidance in the Manual Steps section on each worker node.
Automation
#!/usr/bin/env bash
#
# Automation: Enable seccompDefault in /var/lib/kubelet/config.yaml on every worker node
#
# Usage (from an admin machine with SSH access to worker nodes as root or via sudo):
# 1) Put all worker node hostnames/IPs into /root/worker-nodes.txt (one per line)
# 2) Run:
# bash enable-kubelet-seccomp-default.sh
#
# This script is idempotent and safe to re-run.
set -euo pipefail
WORKER_LIST_FILE="/root/worker-nodes.txt"
SSH_USER="root" # change to your SSH user if needed
SSH_OPTS="-o BatchMode=yes -o StrictHostKeyChecking=accept-new"
if [[ ! -f "${WORKER_LIST_FILE}" ]]; then
echo "Worker node list file not found: ${WORKER_LIST_FILE}" >&2
exit 1
fi
echo "Reading worker nodes from ${WORKER_LIST_FILE}"
mapfile -t NODES < "${WORKER_LIST_FILE}"
if [[ "${#NODES[@]}" -eq 0 ]]; then
echo "No nodes listed in ${WORKER_LIST_FILE}" >&2
exit 1
fi
# Remote script to run on each worker node
read -r -d '' REMOTE_SCRIPT <<'EOF'
set -euo pipefail
KUBELET_CONFIG="/var/lib/kubelet/config.yaml"
SYSTEMD_UNIT="kubelet.service"
echo "=== $(hostname): processing kubelet config ==="
if [[ ! -f "${KUBELET_CONFIG}" ]]; then
echo "ERROR: ${KUBELET_CONFIG} not found; kubelet may be configured differently on this node." >&2
exit 1
fi
# Ensure the YAML has a top-level apiVersion to place seccompDefault under;
# do not alter structure otherwise.
# We'll append seccompDefault: true only if not already true.
CURRENT_SETTING="$(grep -E '^[[:space:]]*seccompDefault:' "${KUBELET_CONFIG}" 2>/dev/null || true)"
if [[ -n "${CURRENT_SETTING}" ]]; then
# Normalize any existing line to 'seccompDefault: true'
if echo "${CURRENT_SETTING}" | grep -q 'seccompDefault:[[:space:]]*true'; then
echo "seccompDefault already set to true; no change needed."
else
echo "seccompDefault found but not true; updating to true."
cp "${KUBELET_CONFIG}" "${KUBELET_CONFIG}.bak.$(date +%s)"
# Replace any existing seccompDefault line with 'seccompDefault: true'
# (preserves indentation)
perl -pi -e 's/^(\s*seccompDefault:\s*).*/${1}true/' "${KUBELET_CONFIG}"
fi
else
echo "seccompDefault not present; adding seccompDefault: true at end of file."
cp "${KUBELET_CONFIG}" "${KUBELET_CONFIG}.bak.$(date +%s)"
printf "\nseccompDefault: true\n" >> "${KUBELET_CONFIG}"
fi
# Reload kubelet so the new config takes effect.
# Operational impact: this restarts kubelet, which can briefly impact node status.
if systemctl is-enabled --quiet "${SYSTEMD_UNIT}"; then
echo "Restarting kubelet via systemd..."
systemctl daemon-reload
systemctl restart "${SYSTEMD_UNIT}"
else
echo "WARNING: ${SYSTEMD_UNIT} not enabled under systemd; restart kubelet manually." >&2
fi
# Verification: confirm kubelet is running and seccompDefault is true in config
echo "Verifying kubelet process and seccompDefault setting..."
if ! /bin/ps -fC kubelet >/dev/null 2>&1; then
echo "ERROR: kubelet process not found after restart." >&2
exit 1
fi
if ! grep -Eq '^[[:space:]]*seccompDefault:[[:space:]]*true[[:space:]]*$' "${KUBELET_CONFIG}"; then
echo "ERROR: seccompDefault: true not found in ${KUBELET_CONFIG} after modification." >&2
exit 1
fi
echo "SUCCESS: kubelet running and seccompDefault: true configured."
EOF
for NODE in "${NODES[@]}"; do
[[ -z "${NODE}" ]] && continue
echo "===== Connecting to worker node: ${NODE} ====="
ssh ${SSH_OPTS} "${SSH_USER}@${NODE}" "${REMOTE_SCRIPT}" || {
echo "ERROR: remediation failed on node ${NODE}" >&2
}
done
echo "=== Cluster-wide verification ==="
for NODE in "${NODES[@]}"; do
[[ -z "${NODE}" ]] && continue
echo "--- ${NODE} ---"
ssh ${SSH_OPTS} "${SSH_USER}@${NODE}" "\
echo 'ps output:' && /bin/ps -fC kubelet || echo 'kubelet not found'; \
echo 'seccompDefault line:' && grep -E '^[[:space:]]*seccompDefault:' /var/lib/kubelet/config.yaml || echo 'seccompDefault not set'"
done
echo "Done."