Incident Response with Splunk Audit and RHACS
Duration: ~25 minutes
Overview
201-11 Repudiation: an exec or policy kill with no durable trail is an incident you cannot explain. 201-06 stood up Splunk and kube-apiserver audit. 301-04 made ACS kill a violating process.
This lab is the use of those two sensors together: generate (or reuse) a bad action, hunt it in Splunk (API audit + optional stackrox-*), join it to the ACS violation, and write a five-line timeline a SOC lead could hand to an incident commander.
Why it matters
ACS names the process. Audit names the Kubernetes user and verb. Neither stream alone answers “who exec’d dnf into which pod, and did runtime enforce fire?” CIS still cares that audit left the masters (1.2.21); IR cares that you can query it under time pressure.
What does it solve
-
Violations in ACS with no API identity
-
Splunk
exechits with no process name -
Rewriting the timeline from memory after the pod is gone
-
Forensics theater (snapshots, chain-of-custody binders) before you can search
Your Mission
Confirm Splunk is up (reinstall if 201-07 cleanup tore it down), generate an exec against the 301-04 probe or a sleeper, hunt both indexes, and fill in the timeline table.
Prerequisites
-
Splunk +
ClusterLogForwarderfrom 201-06, or re-runsetup/splunk-lab/install.sh -
RHACS Central (optional notifier into Splunk if
ROX_API_TOKENwas set at install) -
Something to hunt: leftover
301-04-runtimeprobe, or a sleeper in this lab
Click each step only if you need a hint.
Part A: SIEM still there?
Splunk route and password
oc get route splunk-web -n splunk -o jsonpath='https://{.spec.host}{"\n"}' 2>/dev/null || echo "Splunk missing — reinstall"
If the route is missing (typical after 201-07 cleanup):
cd ~/openshift-security-roadshow/setup/splunk-lab
SPLUNK_RUN_CLEAN_FIRST=false ./install.sh
Then:
oc get route splunk-web -n splunk -o jsonpath='https://{.spec.host}{"\n"}'
echo "admin password:"
oc -n splunk get secret splunk-auth -o jsonpath='{.data.password}' | base64 -d; echo
Sign in as admin. Hunt in Search & Reporting. First boot can take 10–25 minutes if you reinstall.
|
Part B: Generate the bad action
Exec into the 301-04 probe (or a sleeper)
Prefer the probe if 301-04 is still deployed—then ACS and audit line up on the same pod.
if oc get deploy pkgmgr-probe -n 301-04-runtime >/dev/null 2>&1; then
POD=$(oc get pod -l app=pkgmgr-probe -n 301-04-runtime -o jsonpath='{.items[0].metadata.name}')
echo "Using probe $POD"
oc exec "$POD" -n 301-04-runtime -- /bin/bash -c 'dnf --version || true; echo IR-LAB-EXEC'
else
oc new-project 301-05-ir || oc project 301-05-ir
oc run sleeper --image=registry.access.redhat.com/ubi9/ubi -- sleep infinity
oc wait pod/sleeper --for=condition=Ready --timeout=90s
oc exec sleeper -- echo IR-LAB-EXEC
fi
date -u +%Y-%m-%dT%H:%M:%SZ
| Note the UTC timestamp. If ACS runtime enforce is still on, the probe pod may be killed (that is evidence, not failure). |
Seed Splunk if the forwarder is slow
cd ~/openshift-security-roadshow/setup/splunk-lab
chmod +x push-recent-audit.sh
./push-recent-audit.sh
| Same helper as 201-06. Gives you kube-apiserver lines without waiting on the collector. |
Part C: Hunt and join
API audit in Splunk
Search:
index=main sourcetype="kube:apiserver:audit" (pkgmgr-probe OR sleeper OR 301-04-runtime OR 301-05-ir) exec
Expand an event: user.username, objectRef.namespace, objectRef.name, objectRef.subresource (exec), verb (create / connect), sourceIPs. That is who called the API.
|
RHACS in Splunk (if the notifier is installed)
index=* sourcetype="stackrox-*" (pkgmgr-probe OR 301-04-runtime OR "Package Manager")
Empty stackrox-* means the notifier was not configured—open Violations in Central for the same window. You still have the audit half.
|
ACS console + pod logs
oc get route central -n stackrox -o jsonpath='https://{.spec.host}{"\n"}'
oc get events -n 301-04-runtime --sort-by='.lastTimestamp' 2>/dev/null | tail -20
oc get events -n 301-05-ir --sort-by='.lastTimestamp' 2>/dev/null | tail -20
Central Violations: policy, deployment, process, enforcement. Events: Killing / Started. Together with Splunk you can fill the table below.
|
Part D: Five-line timeline
Fill this in from the hunts (example answers in the hint).
| # | Question | Your evidence (source) |
|---|---|---|
1 |
When (UTC)? |
Splunk |
2 |
Which Kubernetes user? |
Audit |
3 |
Which namespace / pod? |
|
4 |
What process ran? |
ACS violation (e.g. |
5 |
Did runtime enforce fire? |
ACS enforcement + OpenShift |
Example filled row (collapsible)
14:02:11Z — lab-user — 301-04-runtime / pkgmgr-probe-… — dnf --version — yes, ACS runtime enforce killed the pod; Deployment recreated a replica.
Detection rule worth keeping: IF (exec in a prod-like namespace) AND (ACS package-manager violation within 60s) THEN page the on-call.
Debrief
IR on OpenShift is Splunk audit + RHACS, not a separate forensics appliance for the first hour. Preserve the SIEM and Central; snapshot the node later if you need disk.
What breaks without this:
-
ACS-only → you know
dnfran, not which API user -
Audit-only → you know
exechappened, not which binary -
Tearing Splunk down after 201-07 and never reinstalling → 301 has no hunt UI
Cleanup only deletes 301-05-ir (not Splunk, not ACS policies).
|
