Skip to main content

Ensure Audit Log Path Argument Is Set

More Info:โ€‹

Enable auditing on the Kubernetes API Server and set the desired audit log path.

Risk Levelโ€‹

Medium

Addressโ€‹

Security

Compliance Standardsโ€‹

  • CIS Kubernetes

Triage and Remediationโ€‹

Remediationโ€‹

Manual Steps
  1. On every control plane node, open the API server static pod manifest for editing:

    sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
  2. In the container command/args section for kube-apiserver, add or update the audit log path argument so it is present as its own list item, for example:

    - --audit-log-path=/var/log/apiserver/audit.log

    Ensure it is aligned with the other - -- arguments under the same list.

  3. Still on the same node, make sure the target directory exists and has appropriate permissions:

    sudo mkdir -p /var/log/apiserver
    sudo chown root:root /var/log/apiserver
    sudo chmod 700 /var/log/apiserver
  4. Save the file and exit the editor. The kubelet will automatically detect the change to /etc/kubernetes/manifests/kube-apiserver.yaml and restart the API server static pod; expect a brief control-plane disruption during the restart.

  5. After 1โ€“2 minutes, verify that the API server process now includes the --audit-log-path argument on every control plane node:

    /bin/ps -ef | grep kube-apiserver | grep -v grep

    Confirm the output shows a segment similar to:
    --audit-log-path=/var/log/apiserver/audit.log

Using kubectl

kubectl cannot configure API server process flags or edit the static pod manifest on disk, so it cannot be used to set --audit-log-path. This must be fixed directly on each control plane node by editing /etc/kubernetes/manifests/kube-apiserver.yaml; see the Manual Steps section for the exact procedure.

Automation
#!/usr/bin/env bash
#
# Remediation: Ensure kube-apiserver has --audit-log-path set
# Scope: every control plane node
# Usage: run as root on each control plane node
#

set -euo pipefail

APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
AUDIT_LOG_DIR="/var/log/apiserver"
AUDIT_LOG_FILE="${AUDIT_LOG_DIR}/audit.log"
BACKUP_SUFFIX=".pre_audit_log_path.bak"

echo "[*] Ensuring kube-apiserver --audit-log-path is configured"

if [[ $EUID -ne 0 ]]; then
echo "ERROR: Run this script as root." >&2
exit 1
fi

if [[ ! -f "${APISERVER_MANIFEST}" ]]; then
echo "ERROR: Manifest not found at ${APISERVER_MANIFEST}" >&2
exit 1
fi

# Create log directory and file with safe permissions (idempotent)
mkdir -p "${AUDIT_LOG_DIR}"
touch "${AUDIT_LOG_FILE}"
chmod 700 "${AUDIT_LOG_DIR}"
chmod 600 "${AUDIT_LOG_FILE}"
chown root:root "${AUDIT_LOG_DIR}" "${AUDIT_LOG_FILE}" || true

# Backup once (idempotent)
if [[ ! -f "${APISERVER_MANIFEST}${BACKUP_SUFFIX}" ]]; then
cp "${APISERVER_MANIFEST}" "${APISERVER_MANIFEST}${BACKUP_SUFFIX}"
echo "[*] Backup created at ${APISERVER_MANIFEST}${BACKUP_SUFFIX}"
fi

# Ensure yamlfix utility function
ensure_audit_log_arg() {
local manifest="$1"
local arg="--audit-log-path=${AUDIT_LOG_FILE}"

# If exact arg already present, nothing to do
if grep -qE -- "[[:space:]]- ${arg}([[:space:]]|\$)" "${manifest}"; then
echo "[*] ${arg} already present in ${manifest}"
return 0
fi

# If any --audit-log-path exists with different value, replace it
if grep -qE -- "[[:space:]]- --audit-log-path=" "${manifest}"; then
sed -i "s#\([[:space:]]-\s*--audit-log-path=\).*#\1${AUDIT_LOG_FILE}#g" "${manifest}"
echo "[*] Updated existing --audit-log-path to ${AUDIT_LOG_FILE}"
return 0
fi

# Insert new arg under the kube-apiserver command args
# Handles common kubeadm-style manifest with 'command:' and '-' args
if grep -qE '^\s*command:\s*$' "${manifest}"; then
# Insert after the last existing dash-arg under command:
# Fallback: append to the first args list under containers if pattern differs
if perl -0pe '' 2>/dev/null >/dev/null; then
# Try to insert using perl for minimal structure disturbance
perl -0pi -e '
my $arg = q('"${arg}"');
s{
(command:\s*\n(?:\s*-\s*[^\n]+\n)*)(\s*-\s*--)
}{
my ($head, $firstarg) = ($1, $2);
my $ins = $head =~ /\Q$arg\E/ ? $head : $head . " - $arg\n";
$ins . $firstarg
}ex if !/\Q'"${arg}"'\E/;
' "${manifest}" || true
fi
fi

# If still no arg, append to any args list under containers
if ! grep -qE -- "[[:space:]]- ${arg}([[:space:]]|\$)" "${manifest}"; then
# Append to the first list item under 'containers:' if args/command not easily parsed
# Simple, safe append near other flags
# This appends under the first occurrence of '- kube-apiserver'
if grep -qE '^\s*- name:\s*kube-apiserver\s*$' "${manifest}"; then
awk -v arg="${arg}" '
$0 ~ /^\s*- name:\s*kube-apiserver\s*$/ && !inserted {
print $0
inserted=1
next
}
inserted && $0 ~ /^\s*image:\s*/ && !printed_arg {
print " command:"
print " - kube-apiserver"
print " - " arg
printed_arg=1
print $0
next
}
{ print $0 }
' "${manifest}" >"${manifest}.tmp" && mv "${manifest}.tmp" "${manifest}"
fi
fi

# Final check; if still missing, fail loudly
if ! grep -qE -- "[[:space:]]- ${arg}([[:space:]]|\$)" "${manifest}"; then
echo "ERROR: Failed to ensure ${arg} in ${manifest}. Please edit manually." >&2
return 1
fi

echo "[*] Ensured ${arg} is present in ${manifest}"
}

ensure_audit_log_arg "${APISERVER_MANIFEST}"

echo "[*] kube-apiserver manifest updated. Note: editing a static pod manifest in /etc/kubernetes/manifests will cause the kubelet to restart the kube-apiserver pod automatically."

echo "[*] Waiting for kube-apiserver to restart with new arguments (up to 120s)..."
sleep 10

# Simple wait loop for process to contain the new flag
end=$((SECONDS + 120))
while (( SECONDS < end )); do
if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q -- "--audit-log-path=${AUDIT_LOG_FILE}"; then
break
fi
sleep 5
done

echo "[*] Verification:"
/bin/ps -ef | grep kube-apiserver | grep -v grep | sed 's/^/ /'

if /bin/ps -ef | grep kube-apiserver | grep -v grep | grep -q -- "--audit-log-path=${AUDIT_LOG_FILE}"; then
echo "[*] PASS: kube-apiserver is running with --audit-log-path=${AUDIT_LOG_FILE}"
exit 0
else
echo "ERROR: kube-apiserver is not running with the expected --audit-log-path flag." >&2
exit 1
fi

Additional Reading:โ€‹