$ run as a normal user# run as root (or with sudo)
Skills in this chapter
- Audit logs, Falco, immutable containers and threat detection
Turn on audit logging
An audit policy says which requests to log and in how much detail. The API server writes them to a file.
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages: [RequestReceived]
rules:
- level: None
resources: [{ group: "", resources: [events] }]
- level: Metadata
resources: [{ group: "", resources: [secrets, configmaps] }]
- level: RequestResponse
namespaces: [shop]
resources: [{ group: "", resources: [pods] }]
- level: MetadataIn kube-apiserver.yaml:
--audit-policy-file=/etc/kubernetes/audit/policy.yaml
--audit-log-path=/var/log/kubernetes/audit/audit.log
--audit-log-maxage=7
--audit-log-maxbackup=3
--audit-log-maxsize=100Add hostPath volumes and mounts for the policy file and the log folder.
| Level | Logs |
|---|---|
| None | Nothing |
| Metadata | Who, what, when — no bodies (use it for secrets!) |
| Request | Plus the request body |
| RequestResponse | Plus the response body |
tail -n 2 /var/log/kubernetes/audit/audit.log | jq '{user: .user.username, verb, uri: .requestURI}'
grep '"resource":"secrets"' /var/log/kubernetes/audit/audit.log | jq -r '.user.username' | sort | uniq -cRemember
Rules are checked in order; the first match wins. Put specific rules before the catch-all.
Detect behaviour with Falco
Falco reads system calls (eBPF) and checks them against rules. A match writes an alert (stdout, file, syslog, webhook).
helm install falco falcosecurity/falco -n falco --create-namespace
journalctl -u falco -f
kubectl exec -it web-7d9f -n shop -- sh
grep "Terminal shell in container" /var/log/syslog | tail -1- rule: Write below etc in container
desc: A process in a container writes to /etc
condition: open_write and container and fd.name startswith /etc
output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline file=%fd.name container=%container.name image=%container.image.repository)"
priority: WARNING
tags: [container, filesystem]Exam tip
A typical task: change an existing Falco rule's output format or priority, find which pod triggered it, and stop that pod. Local overrides go in falco_rules.local.yaml.
Make containers immutable
A container should not change at run time: read-only root, no shell tools, no package manager, no privilege.
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
runAsNonRoot: trueInvestigate a suspicious pod
Contain first, then collect evidence, then remove.
- Isolate: label the pod and apply a deny-all NetworkPolicy for that label.
- Collect:
kubectl logs,kubectl describe, events, audit log entries, Falco alerts,crictl inspect. - Find the source: which image, which service account, which node.
- Remove: delete the pod; fix the image or the policy; rotate secrets it could read.