| |

LFCS 146 ๐Ÿง System Auditing โ€” auditd

โฑ๏ธ Estimated read: 11 min | |

The previous chapter covered AppArmor, which confines applications using path-based profiles. This chapter covers the system-wide audit framework: the kernel component that records security-relevant events and the auditd daemon that writes them to disk. Unlike AppArmor, which blocks actions, auditd observes and records. It does not prevent a file from being read; it records who read it, when, and with what result. The LFCS exam tests the distinction between the temporary auditctl rules and the persistent rules in /etc/audit/rules.d/, the syntax of the two rule types (file watches and syscall rules), and the commands that query the log (ausearch and aureport).

Key point: The auditctl command adds rules to the running kernel. The rules are lost on reboot. The persistent rules live in /etc/audit/rules.d/*.rules, and the augenrules --load command compiles them into /etc/audit/audit.rules and loads them into the kernel. The -w flag creates a file watch. The -a flag creates a syscall rule. The -k flag assigns a key that the ausearch command uses to filter the log.


Why system auditing requires a specific mental model

The observation problem. The audit framework records what happened, not what should have happened. It is a black box recorder, not a firewall. The policy defines which events are recorded. A file watch on /etc/passwd records every read, write, execute, and attribute change. A syscall rule on execve records every program execution. The log is the evidence. The exam tests the rules that produce the evidence.

The persistence problem. The auditctl -w /etc/passwd -p wa command adds a rule to the running kernel. The rule is active immediately. The auditctl -l command shows the loaded rules. But the rule is not saved to disk. A reboot reloads the kernel, and the rule is gone. The persistent configuration is the /etc/audit/rules.d/ directory. The files in this directory are numbered (e.g., 10-base-config.rules, 30-stig.rules, 99-finalize.rules), and the augenrules script concatenates them in alphabetical order into the /etc/audit/audit.rules file. The auditd service loads that file at boot .

The rule-type problem. The audit framework has two rule types. A file watch (-w) monitors a specific path. A syscall rule (-a) monitors a system call, optionally filtered by the architecture, the syscall name, and the arguments. The file watch is simpler and is the correct choice for monitoring sensitive files like /etc/passwd, /etc/shadow, and /etc/sudoers. The syscall rule is more powerful and is the correct choice for recording program executions, privilege escalations, and network connections .

The log problem. The audit log is at /var/log/audit/audit.log. The raw log is a sequence of records, each with a type, a timestamp, and a set of fields. The ausearch command searches the log by key, by message type, by user, and by time. The aureport command produces summary reports: authentication events, failed events, executable events, and file access events. The two commands are the primary interface to the log .

The trade-off. More rules produce more evidence, but they also produce more overhead. A syscall rule on every execve call records every program that runs on the system. This is valuable for intrusion detection, but it generates a large log. The rule design must balance the evidence against the storage and the performance. The exam tests the syntax, not the tuning.


a. The file watches and the syscall rules

The -w flag creates a file watch. The -p flag specifies the permissions that trigger the audit: r for read, w for write, x for execute, and a for attribute change. The -k flag assigns a key for the search.

# Watch the passwd file for writes and attribute changes
sudo auditctl -w /etc/passwd -p wa -k identity

# Watch the shadow file for reads, writes, and attribute changes
sudo auditctl -w /etc/shadow -p rwa -k identity

# Watch the sudoers file for writes
sudo auditctl -w /etc/sudoers -p wa -k privilege_escalation

The -w rule monitors a specific inode. If the file is replaced (e.g., by a package upgrade that creates a new file), the watch is lost. The -W flag (or the -F path= syntax in the syscall rule) monitors the path instead of the inode, which survives the replacement .

The -a flag creates a syscall rule. The syntax is -a action,list -S syscall -F field=value -k key.

# Record all execve calls from users with UID >= 1000
sudo auditctl -a always,exit -F arch=b64 -S execve -F auid>=1000 -F auid!=unset -k user-exec

# Record privilege escalation attempts
sudo auditctl -a always,exit -F arch=b64 -S execve -F euid=0 -F uid!=0 -k priv_esc

The action is always (always record) or never (never record). The list is exit for syscall rules. The -S flag specifies the syscall name. The -F arch=b64 filters to the 64-bit architecture. The -F auid>=1000 filters to the users with a login UID of 1000 or higher. The auid is the audit UID, which is the original login identity and survives the sudo and su transitions .


b. The persistent rules and the augenrules command

The persistent rules live in /etc/audit/rules.d/. The files are numbered to control the order. The augenrules --load command compiles the files into /etc/audit/audit.rules and loads them into the kernel.

# Create a persistent rule file
sudo tee /etc/audit/rules.d/30-identity.rules <<'EOF'
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p rwa -k identity
-w /etc/sudoers -p wa -k privilege_escalation
EOF

# Load the rules
sudo augenrules --load

The auditctl -l command lists the loaded rules. The auditctl -s command shows the audit status: enabled 1 means the audit is active, and enabled 2 means the configuration is locked (immutable mode). The auditctl -D command deletes all the rules, which is useful for testing .

The auditd.conf file controls the daemon behavior: the log file path, the maximum log size, the number of rotations, and the action when the disk is full.

# /etc/audit/auditd.conf
max_log_file = 50
num_logs = 8
max_log_file_action = rotate
space_left_action = syslog
disk_full_action = syslog

The max_log_file is the size in MB. The num_logs is the number of rotated files. The space_left_action and disk_full_action are the actions when the disk is low or full. The syslog value keeps the system running, while the halt value powers off the machine to avoid unaudited activity .


c. The log queries and the reports

The ausearch command searches the log. The -k flag filters by key. The -m flag filters by message type. The -ts flag filters by time. The -ua flag filters by user.

# Search by key
sudo ausearch -k identity

# Search by message type
sudo ausearch -m EXECVE

# Search recent events
sudo ausearch -ts recent

# Search by user
sudo ausearch -ua 1000

The aureport command produces summary reports. The -au flag produces the authentication report. The -f flag produces the file access report. The -x flag produces the executable report. The --failed flag shows only the failed events.

# Authentication report
sudo aureport -au

# File access summary
sudo aureport -f --summary

# Failed events
sudo aureport --failed

The ausearch output includes the type, the msg (timestamp and event ID), the syscall, the uid, the comm (command name), the exe (executable path), the key, and the success field. The aureport output is a summary count, which is useful for the trend analysis .


Complete Example Session

# ============================================
# PART 1: CHECK THE AUDIT STATUS
# ============================================

sudo auditctl -s
# enabled 1
# failure 1
# pid 742
# ============================================
# PART 2: ADD A TEMPORARY FILE WATCH
# ============================================

sudo auditctl -w /etc/passwd -p wa -k identity
sudo auditctl -l
# -w /etc/passwd -p wa -k identity
# ============================================
# PART 3: TRIGGER THE WATCH
# ============================================

sudo useradd testuser
# The /etc/passwd file is modified.
# ============================================
# PART 4: SEARCH THE LOG
# ============================================

sudo ausearch -k identity
# Shows the useradd event with the uid, comm, and exe.
# ============================================
# PART 5: CREATE A PERSISTENT RULE
# ============================================

sudo tee /etc/audit/rules.d/30-identity.rules <<'EOF'
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p rwa -k identity
EOF

sudo augenrules --load
# ============================================
# PART 6: VERIFY THE LOADED RULES
# ============================================

sudo auditctl -l
# -w /etc/passwd -p wa -k identity
# -w /etc/shadow -p rwa -k identity
# ============================================
# PART 7: ADD A SYSCALL RULE
# ============================================

sudo auditctl -a always,exit -F arch=b64 -S execve -F auid>=1000 -F auid!=unset -k user-exec
# ============================================
# PART 8: GENERATE A REPORT
# ============================================

sudo aureport -au
# Shows the authentication events.
# ============================================
# PART 9: CLEAN UP THE TEMPORARY RULES
# ============================================

sudo auditctl -D
sudo auditctl -l
# No rules

The nine parts trace the audit workflow: status check, temporary watch, trigger, search, persistent rule, verification, syscall rule, report, and cleanup.


Quick Reference

Rule Commands

CommandPurpose
auditctl -w <path> -p <perms> -k <key>File watch
auditctl -a always,exit -S <syscall> -k <key>Syscall rule
auditctl -lList loaded rules
auditctl -DDelete all rules
auditctl -sShow status

Permission Flags

FlagMeaning
rRead
wWrite
xExecute
aAttribute change

Persistent Rules

LocationPurpose
/etc/audit/rules.d/*.rulesPersistent rules
/etc/audit/audit.rulesGenerated file
augenrules --loadCompile and load

Log Queries

CommandPurpose
ausearch -k <key>Search by key
ausearch -m <type>Search by message type
ausearch -ts recentRecent events
aureport -auAuthentication report
aureport -fFile access report

Configuration

FilePurpose
/etc/audit/auditd.confDaemon config
/var/log/audit/audit.logAudit log

Best Practices

โœ… Do This:

sudo augenrules --load
<!-- Load persistent rules after editing -->          # โœ…
sudo ausearch -k identity
<!-- Search by the key assigned to the rule -->       # โœ…
sudo auditctl -l
<!-- Verify rules are loaded -->                      # โœ…

โŒ Don’t Do This:

# Rely on auditctl for persistence
<!-- Rules are lost on reboot -->                     # โŒ
# Ignore the auid field
<!-- sudo transitions lose the uid, not auid -->     # โŒ
# Generate huge logs without rotation
<!-- Configure max_log_file and num_logs -->          # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Rules lost after rebootUsed auditctl onlyAdd to /etc/audit/rules.d/
Watch stops workingInode replacedUse path-based watch
No log entriesauditd not runningsystemctl start auditd
Log fills diskNo rotationConfigure auditd.conf
Cannot search by keyNo -k in the ruleAdd -k to the rule

Real-World Examples

1. File Watch

sudo auditctl -w /etc/passwd -p wa -k identity

2. Syscall Rule

sudo auditctl -a always,exit -F arch=b64 -S execve -k user-exec

3. List Rules

sudo auditctl -l

4. Status

sudo auditctl -s

5. Persistent Rule

sudo tee /etc/audit/rules.d/30-identity.rules

6. Load Rules

sudo augenrules --load

7. Search by Key

sudo ausearch -k identity

8. Search by Type

sudo ausearch -m EXECVE

9. Auth Report

sudo aureport -au

10. File Report

sudo aureport -f

Visual

Audit Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Application / Syscall                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Kernel audit subsystem                      โ”‚
โ”‚  โ†’ Checks rules                              โ”‚
โ”‚  โ†’ Records matching events                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  auditd daemon                               โ”‚
โ”‚  โ†’ Writes /var/log/audit/audit.log           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ausearch / aureport                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Rule Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  auditctl -w /etc/passwd -p wa -k identity   โ”‚
โ”‚  โ†’ Rule loaded into kernel                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Event occurs (write to /etc/passwd)         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Kernel records the event                    โ”‚
โ”‚  โ†’ auditd writes it to audit.log             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ausearch -k identity                        โ”‚
โ”‚  โ†’ Returns the matching entries              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Audit daemonauditd
Kernel interfaceauditctl
File watch-w <path> -p <perms> -k <key>
Syscall rule-a always,exit -S <syscall>
Persistent rules/etc/audit/rules.d/*.rules
Load rulesaugenrules --load
Search by keyausearch -k <key>
Reportaureport -au
Log file/var/log/audit/audit.log
Config file/etc/audit/auditd.conf

Key takeaways:

  • The auditctl command is the runtime tool. It adds rules to the running kernel. The rules are lost on reboot. The auditctl -l lists the loaded rules. The auditctl -s shows the status.
  • The persistent rules are in /etc/audit/rules.d/. The files are numbered, and the augenrules --load command compiles them into the runtime configuration. The auditd service loads the rules at boot.
  • The file watch is for specific paths. The -w flag monitors a path. The -p flag specifies the permissions that trigger the audit. The -k flag assigns a key for the search.
  • The syscall rule is for broader monitoring. The -a flag monitors a syscall with the -F filters. The auid field is the login identity and survives the sudo and su.
  • The ausearch and aureport commands query the log. The ausearch searches by key, type, user, and time. The aureport produces summary reports.

Remember: The audit framework records what happens. The auditctl is the runtime. The augenrules is the persistence. The -w is the file watch. The -a is the syscall. The -k is the search key. The ausearch is the query. The exam tests the persistence and the query commands.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!