Controller Manager Should Disable Profiling
More Info:
Verifies that the controller manager --profiling argument is set to false so detailed profiling data is not exposed to potential attackers.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every control plane node, open the kube-controller-manager static pod manifest for editing:
sudo vi /etc/kubernetes/manifests/kube-controller-manager.yaml -
In the
spec.containers[0].command(orargs) list, add or update the profiling flag so it is explicitly disabled:- --profiling=falseEnsure there is no other
--profiling=entry with a different value. -
Save the file and exit the editor. The kube-controller-manager static pod will be automatically restarted by the kubelet because the manifest under
/etc/kubernetes/manifestschanged. Be aware this briefly restarts the controller manager on this control plane node. -
Repeat steps 1–3 on every control plane node that has a
/etc/kubernetes/manifests/kube-controller-manager.yamlfile. -
After the controller manager has restarted on a node, verify that profiling is disabled by inspecting the running process on that node:
ps -ef | grep kube-controller-manager | grep -v grepConfirm the output includes
--profiling=falseand does not include--profiling=trueor a bare--profilingflag.
Using kubectl
kubectl cannot change the --profiling flag for the controller manager because it is configured via the static pod manifest on each control plane node at /etc/kubernetes/manifests/kube-controller-manager.yaml. To remediate this finding, follow the guidance in the Manual Steps section on each control plane node.
Automation
#!/usr/bin/env bash
#
# Automation: Disable profiling in kube-controller-manager static pod manifest
#
# Target: every control plane node
# Preconditions: run as root on each control plane node
set -euo pipefail
MANIFEST="/etc/kubernetes/manifests/kube-controller-manager.yaml"
ARG_NAME="--profiling"
DESIRED="${ARG_NAME}=false"
echo ">>> Ensuring ${DESIRED} in ${MANIFEST}"
if [[ ! -f "${MANIFEST}" ]]; then
echo "ERROR: Manifest not found at ${MANIFEST}. This script is only for static pod deployments."
exit 1
fi
# Backup once (idempotent)
BACKUP="${MANIFEST}.pre-profiling-fix.bak"
if [[ ! -f "${BACKUP}" ]]; then
cp -p "${MANIFEST}" "${BACKUP}"
echo "Created backup ${BACKUP}"
fi
# Function to test if manifest already has desired arg
has_desired_arg() {
grep -E '^\s*-\s*'"${DESIRED}"'\s*$' "${MANIFEST}" >/dev/null 2>&1
}
# Function to test if any --profiling arg exists
has_any_profiling_arg() {
grep -E '^\s*-\s*'"${ARG_NAME}="' "${MANIFEST}" >/dev/null 2>&1
}
# Ensure a --profiling=false argument exists, replacing any existing --profiling=...
if has_desired_arg; then
echo ">>> ${DESIRED} already present in ${MANIFEST}"
else
if has_any_profiling_arg; then
echo ">>> Updating existing ${ARG_NAME} argument to false"
# Replace any existing --profiling=<value> with --profiling=false on the arg lines
# This keeps indentation and surrounding structure intact.
sed -i -E 's|^(\s*-\s*'"${ARG_NAME}"'=).*|\1false|' "${MANIFEST}"
else
echo ">>> Adding ${DESIRED} to kube-controller-manager container args"
# Insert the argument under the kube-controller-manager container args list.
# This uses a conservative awk approach that:
# - Detects the kube-controller-manager container block
# - Inserts the arg under its args: list if present
# - If no args: list exists, creates one.
tmpfile="$(mktemp)"
awk -v arg="${DESIRED}" '
$0 ~ "name:[[:space:]]*kube-controller-manager" { in_kcm=1 }
in_kcm && $0 ~ "name:" && $0 !~ "kube-controller-manager" { in_kcm=0 }
in_kcm && $0 ~ "args:[[:space:]]*$" {
in_args=1
print
getline nextline
# Insert arg as first item under args if not already there
if (nextline ~ /^[ \t]*-[ \t]/) {
print " - " arg
}
print nextline
while ((getline l) > 0) {
if (l ~ /^[^ \t-]/ || l ~ /^[ \t]*[A-Za-z0-9_-]+:/) {
print l
in_args=0
break
}
print l
}
next
}
in_kcm && !in_args && $0 ~ "image:" && !seen_args_block {
# No args: block seen yet; create one before image line
print " args:"
print " - " arg
seen_args_block=1
}
{ print }
' "${MANIFEST}" > "${tmpfile}"
mv "${tmpfile}" "${MANIFEST}"
fi
fi
echo ">>> Waiting for kube-controller-manager static pod restart (triggered by manifest change)..."
sleep 10
echo ">>> Verification: checking running kube-controller-manager process flags"
/bin/ps -ef | grep kube-controller-manager | grep -v grep || {
echo "WARNING: kube-controller-manager process not found. Static pod may still be starting."
}
if /bin/ps -ef | grep kube-controller-manager | grep -v grep | grep -q -- "${DESIRED}"; then
echo "SUCCESS: kube-controller-manager is running with ${DESIRED}"
else
echo "WARNING: ${DESIRED} not detected in running kube-controller-manager process."
echo "Current process line(s):"
/bin/ps -ef | grep kube-controller-manager | grep -v grep || true
exit 1
fi