Introduction
The Linux Audit Framework (auditd) is a kernel-level subsystem that records system calls, file accesses, user logins, and privileged operations to an immutable log before any user-space process — including a compromised root shell — can suppress them. Unlike application logs that an attacker can delete, audit records are written at the syscall boundary and buffered in kernel memory before being flushed to disk.
For IT professionals supporting regulated environments (PCI-DSS, HIPAA, ISO 27001, NIST 800-53), auditd is often a hard requirement. For everyone else it is one of the highest-value, lowest-cost monitoring controls available on any Linux system.
This guide covers:
- Installing and configuring
auditdfor production use - Writing targeted audit rules for privileged commands, sensitive files, and authentication
- Using
ausearchandaureportto investigate events - Forwarding events to a SIEM via
audisp-remoteorrsyslog - Hardening the audit daemon itself
Prerequisites
- A Linux host running RHEL 8/9, Rocky Linux 8/9, or Ubuntu 22.04/24.04
- Root or
sudoaccess /var/log/audit/with at least 2 GB of available disk space- Optional: Wazuh agent or a syslog forwarder already installed (for SIEM integration)
Step 1 — Install auditd
RHEL / Rocky Linux
sudo dnf install -y audit audit-libs audispd-plugins
sudo systemctl enable --now auditdUbuntu / Debian
sudo apt update && sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditdVerify it is running and the kernel module is loaded:
sudo systemctl status auditd
sudo auditctl -sExpected output from auditctl -s includes enabled 1 and a non-zero pid.
Step 2 — Configure the Audit Daemon (auditd.conf)
The main config controls log rotation, max log size, and what to do when disk space runs out.
sudo nano /etc/audit/auditd.confKey settings to review and tighten:
# /etc/audit/auditd.conf
log_file = /var/log/audit/audit.log
log_format = ENRICHED # Includes UID/GID names alongside numeric IDs
max_log_file = 100 # MB per log file before rotation
num_logs = 10 # Keep 10 rotated files (≈1 GB total)
max_log_file_action = ROTATE # Rotate rather than halt
# Disk space safety valve
space_left = 500 # MB remaining before warning
space_left_action = SYSLOG # Log a warning — change to EMAIL if you have mail configured
admin_space_left = 100 # Critical threshold
admin_space_left_action = SUSPEND # Suspend logging rather than fill disk
# Prevent log tampering (requires immutable rules — see Step 4)
flush = INCREMENTAL_ASYNC
freq = 50Reload after changes:
sudo systemctl restart auditdStep 3 — Load a Baseline Rule Set
Audit rules live in /etc/audit/rules.d/ as .rules files. Files are merged in alphabetical order at daemon start. A clean layout:
/etc/audit/rules.d/
├── 10-base.rules # Buffer size and failure mode
├── 20-access.rules # File and directory watches
├── 30-priv.rules # Privileged commands
├── 40-auth.rules # Login and authentication
├── 50-network.rules # Network config changes
├── 99-finalize.rules # Lock rules (immutable)
10-base.rules — Buffer and Failure Mode
sudo tee /etc/audit/rules.d/10-base.rules > /dev/null <<'EOF'
## Increase the kernel audit buffer to handle bursts
-b 8192
## Panic on audit failure (use 1 for syslog only in dev)
-f 2
EOFNote:
-f 2causes a kernel panic on audit failure. In a lab, use-f 1(syslog warning only) until you are confident in the configuration.
20-access.rules — Sensitive File Watches
sudo tee /etc/audit/rules.d/20-access.rules > /dev/null <<'EOF'
## /etc/passwd and shadow — credential store changes
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
## SSH authorized keys
-w /root/.ssh -p wa -k ssh-keys
-w /home/ -p wa -k home-ssh-keys
## Crontab changes
-w /etc/cron.d/ -p wa -k cron
-w /etc/cron.daily/ -p wa -k cron
-w /etc/crontab -p wa -k cron
-w /var/spool/cron -p wa -k cron
## Audit log itself
-w /var/log/audit/ -p wa -k audit-logs
## Syslog config
-w /etc/rsyslog.conf -p wa -k syslog
-w /etc/rsyslog.d/ -p wa -k syslog
## Kernel module loading
-w /sbin/insmod -p x -k modules
-w /sbin/modprobe -p x -k modules
-w /sbin/rmmod -p x -k modules
-a always,exit -F arch=b64 -S init_module,finit_module,delete_module -k modules
EOF30-priv.rules — Privileged Command Execution
These rules catch every execution of setuid/setgid binaries — a key lateral-movement indicator:
sudo tee /etc/audit/rules.d/30-priv.rules > /dev/null <<'EOF'
## Privilege escalation via sudo / su
-w /bin/su -p x -k priv-esc
-w /usr/bin/sudo -p x -k priv-esc
## Setuid/setgid discovery — enumerate them first
## Run: find / -perm /6000 -type f 2>/dev/null and add rules per binary
-a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k setuid-exec
-a always,exit -F arch=b64 -S execve -C gid!=egid -F egid=0 -k setgid-exec
## System time changes (clock skew = log tampering indicator)
-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change
-w /etc/localtime -p wa -k time-change
## Network configuration changes
-a always,exit -F arch=b64 -S sethostname,setdomainname -k network-config
-w /etc/hosts -p wa -k network-config
-w /etc/hostname -p wa -k network-config
EOF40-auth.rules — Login and Authentication Events
sudo tee /etc/audit/rules.d/40-auth.rules > /dev/null <<'EOF'
## PAM and login events
-w /etc/pam.d/ -p wa -k pam-config
-w /var/log/faillog -p wa -k auth
-w /var/log/lastlog -p wa -k auth
## Failed login syscalls (uid -1 = unset, i.e. before auth)
-a always,exit -F arch=b64 -S open -F dir=/etc/security -F success=0 -k auth-fail
EOF99-finalize.rules — Immutable Lock
This is critical: once rules are locked, they cannot be modified until reboot — even by root.
sudo tee /etc/audit/rules.d/99-finalize.rules > /dev/null <<'EOF'
## Lock the audit configuration — requires reboot to change rules
-e 2
EOFLoad All Rules
sudo augenrules --load
sudo auditctl -l # List active rulesStep 4 — Querying Audit Logs
ausearch — Event Lookup
# All events for a specific key (e.g. identity changes)
sudo ausearch -k identity --start today
# Events by username
sudo ausearch -ua root --start today
# Failed syscalls only
sudo ausearch -sv no --start today
# Events in a time window
sudo ausearch --start "06/29/2026 08:00:00" --end "06/29/2026 09:00:00"aureport — Summary Reports
# Authentication summary
sudo aureport -au
# Failed authentication events
sudo aureport -au --failed
# Executable events
sudo aureport -x --summary
# Anomaly report (unusual events)
sudo aureport --anomaly
# Full login report
sudo aureport -lausearch with --interpret
# Human-readable output with UID resolution
sudo ausearch -k sudoers -iStep 5 — Forward Events to a SIEM
Option A: audisp-remote (native audit forwarding)
Install and configure the remote plugin to push events to a central auditd server:
sudo nano /etc/audit/plugins.d/au-remote.confactive = yes
direction = out
path = /sbin/audisp-remote
type = always
args = <siem-ip>
format = stringOn the receiving server, configure /etc/audit/auditd.conf:
tcp_listen_port = 60Option B: rsyslog (works with Wazuh, Graylog, Splunk)
sudo tee /etc/rsyslog.d/60-audit.conf > /dev/null <<'EOF'
# Forward audit events to SIEM
$InputFileName /var/log/audit/audit.log
$InputFileTag audit:
$InputFileStateFile audit-log
$InputFileSeverity info
$InputFileFacility local6
$InputRunFileMonitor
local6.* @@<siem-ip>:514
EOF
sudo systemctl restart rsyslogOption C: Wazuh Agent (recommended)
If the Wazuh agent is installed, it auto-collects /var/log/audit/audit.log with the localfile block already in its default config. Verify:
grep -A5 "audit" /var/ossec/etc/ossec.confVerification and Testing
Trigger and Confirm a Known Event
# Trigger an identity change
sudo useradd testaudituser
sudo userdel testaudituser
# Search for it
sudo ausearch -k identity --start recentYou should see type=ADD_USER and type=DEL_USER records with full context.
Confirm Immutable Lock
sudo auditctl -e 0 # Attempt to disable auditingExpected: Error sending enable request: Operation not permitted — the lock is working.
Confirm Rules Survived Reboot
sudo reboot
# After reboot:
sudo auditctl -l | wc -l # Rule count should match pre-rebootCheck for Audit Buffer Overflows
sudo auditctl -s | grep lostIf lost is non-zero, increase the buffer (-b) in 10-base.rules.
Troubleshooting
auditd won't start — "audit pid already exists"
sudo rm /var/run/audit_pid
sudo systemctl start auditdRules not persisting across reboots
Ensure rules are in /etc/audit/rules.d/ (not /etc/audit/audit.rules directly). Run sudo augenrules --load and verify the service ExecStartPost calls augenrules:
systemctl cat auditd | grep augenrulesHigh CPU from auditd during heavy I/O
Narrow overly broad directory watches. Replace -w /home/ -p wa with specific subdirectories, or use -F dir= filters scoped to specific users:
-a always,exit -F arch=b64 -S open,openat -F dir=/home/highvalue-user -F perm=rwa -k home-accessausearch returns nothing for a key
Confirm the key is present in active rules:
sudo auditctl -l | grep <key>If missing, the .rules file may have a syntax error. Check:
sudo augenrules --checkLog rotation deleting events before investigation
Increase num_logs in auditd.conf or configure log shipping before rotation:
# /etc/logrotate.d/audit
/var/log/audit/audit.log {
rotate 30
daily
compress
postrotate
/sbin/service auditd restart 2>/dev/null || true
endscript
}Summary
You now have a production-grade auditd deployment that:
- Captures authentication, privilege escalation, file tampering, and kernel module events at the syscall level
- Uses immutable rules that cannot be disabled by a compromised root session
- Provides
ausearchandaureportfor rapid investigation - Forwards events to a SIEM for long-term retention and correlation
The next step is integrating auditd events with a SIEM rule set (Wazuh's 0585-audit_rules.xml ruleset, or Sigma rules for Elastic/Splunk) to build alerting on high-fidelity indicators like execve with euid=0 from a non-root caller, or writes to /etc/passwd outside of change-management windows.
For a deeper rule set baseline, the CIS Benchmarks and DISA STIG projects both publish auditd rule sets that map directly to compliance controls — start with the CIS-provided audit.rules and trim to your environment's noise tolerance.