Skip to main content
RunBook Academy

← All labs in Linux

Lab · intermediate · ~45 min

Lab: auditd watch and search

B · Nested virtualisationC · Simulation

Objectives

  • Write auditd rules
  • Trigger events without weakening the watched files
  • Query with ausearch
  • Summarise with aureport

Prerequisites

This lab sets up auditd rules, generates events, and queries the audit log. By the end you will have the discipline for production audit deployment.

Requirements

  • A disposable lab host or VM with auditd installed. Do not run this on a shared or production system: you load a rule file into /etc/audit/rules.d/ and touch identity files.
  • Root access via sudo.
  • Nothing else. The lab needs no spare disk, no loop device, and no test filesystem.

Tasks

Task 1: Verify auditd is running

sudo systemctl status auditd
sudo auditctl -s     # status

Task 2: Write rules

sudo tee /etc/audit/rules.d/99-lab.rules <<EOF
-w /etc/passwd -p wa -k passwd
-w /etc/shadow -p wa -k shadow
-w /etc/sudoers -p wa -k sudoers
-w /usr/bin/sudo -p x -k privileged
EOF
sudo augenrules --load
sudo auditctl -l

Task 3: Trigger events

A watch fires on the syscall, not on the result. A metadata write is recorded even when the values it writes are identical to the values already there. That is the whole trick: you can exercise a watch on a sensitive file without weakening it.

Record the starting state first, so you can prove nothing moved:

stat -c '%n %a %U:%G %y' /etc/passwd /etc/shadow /etc/sudoers

Now generate the events. touch -r FILE FILE reads the timestamps from the file itself and writes them straight back, so the utimensat call is always issued and the file is never altered:

sudo touch -r /etc/passwd  /etc/passwd
sudo touch -r /etc/shadow  /etc/shadow
sudo touch -r /etc/sudoers /etc/sudoers

# Privileged execution
sudo ls /root

Re-run the stat command. Every field is identical. Task 4 will still find the events.

Task 4: Query

sudo ausearch -k passwd -ts recent
sudo ausearch -k shadow -ts recent
sudo ausearch -k sudoers -ts recent
sudo ausearch -k privileged -ts recent

The shadow records are the interesting ones. Read the SYSCALL line: syscall=utimensat, success=yes, and the PATH line names /etc/shadow. The watch caught the call even though the timestamps it wrote were the timestamps already there. An audit trail records intent, not diffs.

Task 5: Summarise

sudo aureport --summary -ts today
sudo aureport --file -ts today
sudo aureport --comm -i -ts today      # commands run; there is no --sudo report
sudo ausearch -m USER_CMD -ts today -i # the sudo-specific view

If any of these prints “no matches”, check that the events you expect are in the log at all with sudo ausearch -ts today | head before concluding the rules are wrong — an empty report and a missing rule look the same from here.

Task 6: Document

AUDITD LAB
==========
Host: <host>
Date: 2026-08-09

Rules loaded:
- /etc/passwd watched
- /etc/shadow watched
- /etc/sudoers watched
- /usr/bin/sudo execution watched

Events captured:
- metadata writes on the watched identity files
- privileged execution

Verification:
- ausearch returns expected events
- aureport summary shows the expected categories
- stat confirms no mode, owner or timestamp changed
- lab rule file removed and rules reloaded

Validation

The lab succeeded when all three hold:

# 1. The four lab rules are loaded.
sudo auditctl -l | grep -E 'passwd|shadow|sudoers|/usr/bin/sudo'

# 2. Each key returns at least one syscall record.
for k in passwd shadow sudoers privileged; do
  printf '%-12s %s\n' "$k" \
    "$(sudo ausearch -k "$k" -ts today 2>/dev/null | grep -c '^type=SYSCALL')"
done

# 3. The watched files are untouched.
stat -c '%n %a %U:%G' /etc/passwd /etc/shadow /etc/sudoers

Expected on a Debian-family host: /etc/passwd 644 root:root, /etc/shadow 640 root:shadow, /etc/sudoers 440 root:root. On a RHEL-family host /etc/shadow is 0 root:root. Either way, the modes must match what you recorded in Task 3.

Cleanup

Remove the lab rules and return auditd to its previous rule set:

sudo rm -f /etc/audit/rules.d/99-lab.rules
sudo augenrules --load
sudo auditctl -l

The final auditctl -l must no longer list the four lab rules. If the host had no rules before the lab, it prints No rules.

Confirm you left no permission damage behind:

stat -c '%n %a %U:%G' /etc/shadow /etc/gshadow

/etc/shadow and /etc/gshadow must still be 640 root:shadow on Debian-family systems, or 0 root:root on RHEL-family systems. If either is 644, fix it now:

# Debian-family
sudo chown root:shadow /etc/shadow /etc/gshadow
sudo chmod 0640 /etc/shadow /etc/gshadow

Then rotate every password on the host. A hash that has been world-readable is a leaked hash, whatever the mode says afterwards.

The audit records you generated stay in /var/log/audit/. Leave them: rotation removes them on its own schedule, and deleting audit logs by hand is its own bad habit.

Deliverables

  • · Persistent auditd rules
  • · Verified events in the audit log
  • · ausearch and aureport queries
  • · A host returned to its pre-lab audit configuration and permissions

Verification status

Last reviewed
2026-08-09
Executed end to end
not yet run on hardware

The commands and configuration here have been reviewed against the verified software versions, but nobody has run this lab start to finish on a system meeting its prerequisites. Treat the Expected Outcome as the intended result rather than an observed one, and keep the Cleanup section to hand.