GCP Enable Linux Auditd Logging
More Info:
Deploy Linux auditd logging on Container-Optimized OS nodes so kernel-level audit events from nodes are captured and shipped to Cloud Logging. This provides host-level forensic visibility.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS GKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify node OS and scope
- On any machine with kubectl access, list nodes and their OS images to confirm which are Container-Optimized OS:
kubectl get nodes -o widekubectl get nodes -o json | jq '.items[] | {name: .metadata.name, osImage: .status.nodeInfo.osImage}'
- Decide whether you want auditd logging on all COS nodes or only on specific node pools (e.g., production).
- On any machine with kubectl access, list nodes and their OS images to confirm which are Container-Optimized OS:
-
Check for existing auditd logging DaemonSet
- On any machine with kubectl access, run:
kubectl get daemonsets -A -o json \| jq '.items[] | select(.spec.template.spec.containers[].image | contains("gcr.io/stackdriver-agents/stackdriver-logging-agent")) \| {name: .metadata.name, annotations: .metadata.annotations."kubernetes.io/description", namespace: .metadata.namespace, status: .status}'
- If a DaemonSet is present with a description indicating COS auditd logging to Cloud Logging and it is fully available on all target COS nodes, document that this control is covered and proceed to step 6 for periodic re-verification.
- On any machine with kubectl access, run:
-
Review/prepare deployment manifests (IaC or manual)
- If no suitable DaemonSet exists, download the reference manifests on your IaC workstation or any machine with kubectl:
curl https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/os-audit/cos-auditd-logging.yaml \-o cos-auditd-logging.yaml
- Open
cos-auditd-logging.yamland review: namespace, resource requests/limits, tolerations, and any labels/annotations to ensure they match your cluster standards and target only COS nodes you intend to monitor.
- If no suitable DaemonSet exists, download the reference manifests on your IaC workstation or any machine with kubectl:
-
Deploy or update the DaemonSet (change via console/CLI/IaC policy)
- If you manage manifests via IaC (Terraform, Config Sync, etc.), add
cos-auditd-logging.yamlto the appropriate repo/module and apply using your standard pipeline. - For direct CLI-based clusters, on a machine with kubectl access, you may deploy with:
kubectl apply -f cos-auditd-logging.yaml
- Ensure this change is reflected in your cloud provider configuration management (e.g., documenting in GKE cluster configuration or IaC) so it is reapplied if the cluster is recreated.
- If you manage manifests via IaC (Terraform, Config Sync, etc.), add
-
Verify pod rollout and coverage
- On any machine with kubectl access:
kubectl get pods --namespace=cos-auditd -o widekubectl get daemonset cos-auditd-logging --namespace=cos-auditd -o json \| jq '.status'
- Confirm desired number of pods equals the number of target COS nodes and that pods are in
Runningstate on those nodes.
- On any machine with kubectl access:
-
Validate logs in Cloud Logging and document decision
- In the cloud console (Logging > Logs Explorer), filter for logs from the auditd logging agent (e.g., by namespace
cos-auditdor the DaemonSet/pod name) and confirm kernel-level audit events from COS nodes are present. - Record in your security documentation whether COS auditd logging is: enabled for all COS nodes, enabled for specific node pools only (with rationale), or intentionally not enabled (with accepted risk and justification).
- In the cloud console (Logging > Logs Explorer), filter for logs from the auditd logging agent (e.g., by namespace
Using kubectl
kubectl cannot enable or configure Linux auditd logging on Container-Optimized OS nodes because this control is implemented via cloud provider / managed control plane configuration and supporting DaemonSets defined in manifests. To address this finding, follow the guidance in the Manual Steps section, using the cloud console and/or IaC to deploy and manage the required auditd logging resources.
Automation
#!/usr/bin/env bash
# Check for Linux auditd logging (CIS GKE 5.7.2) via cos-auditd-logging DaemonSet
# Run on any machine with kubectl access and cluster-wide RBAC.
set -euo pipefail
echo "== CIS GKE 5.7.2: Linux auditd logging status =="
# 1. Show all DaemonSets using the Stackdriver logging agent image (matches the audit command)
echo
echo "== DaemonSets using gcr.io/stackdriver-agents/stackdriver-logging-agent =="
kubectl get daemonsets -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.containers[].image
| contains("gcr.io/stackdriver-agents/stackdriver-logging-agent"))
| {
namespace: .metadata.namespace,
name: .metadata.name,
description: .metadata.annotations["kubernetes.io/description"],
desired: .status.desiredNumberScheduled,
ready: .status.numberReady,
nodes_misscheduled: .status.numberMisscheduled
}
' || echo "No matching DaemonSets found."
# 2. Specifically look for the reference implementation (cos-auditd-logging)
echo
echo "== cos-auditd-logging DaemonSets (reference manifests) =="
kubectl get daemonset -A \
| awk 'NR==1 || /cos-auditd-logging/'
# 3. For each matching DaemonSet, show node coverage and readiness
echo
echo "== Detailed readiness for matching DaemonSets =="
kubectl get daemonsets -A -o json \
| jq -r '
.items[]
| select(.spec.template.spec.containers[].image
| contains("gcr.io/stackdriver-agents/stackdriver-logging-agent"))
| [
.metadata.namespace,
.metadata.name,
.status.desiredNumberScheduled,
.status.currentNumberScheduled,
.status.numberReady,
.status.numberUnavailable,
.status.numberMisscheduled
]
| @tsv
' \
| awk 'BEGIN {
OFS="\t";
print "NAMESPACE","DAEMONSET","DESIRED","SCHEDULED","READY","UNAVAILABLE","MISSCHEDULED"
}
{ print }'
# 4. Optionally, show Pods for the typical namespace (cos-auditd), if present
if kubectl get ns cos-auditd >/dev/null 2>&1; then
echo
echo "== Pods in namespace cos-auditd =="
kubectl get pods -n cos-auditd -o wide
else
echo
echo "Namespace 'cos-auditd' not found; manifests may be using a different namespace."
fi
echo
echo "== Interpretation =="
cat <<'EOF'
Problem indicators you should investigate:
- No DaemonSets listed under "DaemonSets using gcr.io/stackdriver-agents/stackdriver-logging-agent":
likely means cluster-wide auditd logging is not deployed.
- DESIRED > 0 but READY < DESIRED for any DaemonSet:
auditd logging is not running on all targeted nodes.
- numberMisscheduled > 0:
Pods are scheduled onto nodes where they should not run (taints/labels mismatch).
- Namespace 'cos-auditd' missing AND no equivalent DaemonSet in another namespace:
reference auditd logging manifests have likely not been applied.
Because this control is MANUAL, you must decide whether:
- The existing DaemonSet(s) provide sufficient kernel-level audit logging coverage, or
- You need to deploy or adjust a DaemonSet (for example, using cos-auditd-logging.yaml)
so that all intended nodes run the auditd logging agent.
EOF