How to Audit a Linux System with auditd
Set up auditd on Linux to track file access, syscalls, and privilege use. Covers persistent rules, file watches, ausearch, and aureport across major distros.
Before you start
- ▸Root or sudo access on the target system
- ▸Familiarity with a terminal text editor (nano, vim)
- ▸Sufficient disk space for audit logs (recommend at least 1 GB dedicated)
- ▸Basic understanding of Linux syscalls and file permissions
The Linux Audit subsystem gives you a kernel-level record of security-relevant events: file access, system calls, authentication attempts, privilege escalation, and more. auditd is the userspace daemon that collects those records and writes them to disk. Unlike log scrapers that work at the application layer, audit hooks sit inside the kernel itself, making them much harder for an attacker to silently bypass. This guide covers installing and starting auditd, writing persistent rules, watching specific files and directories, and extracting useful information from the audit log.
Install and Enable auditd
Most server-oriented distributions ship auditd by default. Check before installing.
Debian / Ubuntu
sudo apt update && sudo apt install -y auditd audispd-plugins
Fedora / RHEL / Rocky
sudo dnf install -y audit audit-libs
Arch Linux
sudo pacman -S audit
Enable and start the service with systemd:
sudo systemctl enable --now auditd
Verify it is running:
sudo systemctl status auditd
On RHEL 9 / Rocky 9 and newer, auditd is protected by systemd's RefuseManualStop; use service auditd stop or the provided init wrapper if you ever need to stop it during testing.
Understanding the Configuration File
The main configuration lives at /etc/audit/auditd.conf. The defaults are sane for most systems, but two settings are worth reviewing immediately:
- max_log_file_action — controls what happens when a log file reaches
max_log_fileMB. Set toROTATEfor production systems;SUSPENDstops auditing rather than dropping records, useful for high-security environments. - space_left_action and admin_space_left_action — define reactions when disk space runs low.
SYSLOGis the minimum;HALTenforces a strict "no audit, no run" policy.
sudo grep -E 'max_log_file|space_left' /etc/audit/auditd.conf
Writing Audit Rules
Rules are managed in two ways: transiently with auditctl (lost on reboot) or persistently in /etc/audit/rules.d/. Always write persistent rules; use auditctl only for live testing. The augenrules tool compiles everything under rules.d/ into /etc/audit/audit.rules and loads it.
Rule Syntax Primer
-a action,list— appends a rule; common lists arealways,exitandnever,exit.-S syscall— matches a specific syscall by name or number.-F field=value— filters (UID, GID, path, architecture, etc.).-k key— tags records with a searchable keyword.-w path/-p permissions— file/directory watch shorthand (rread,wwrite,xexecute,aattribute change).
Create a Rules File
sudo nano /etc/audit/rules.d/50-local.rules
A practical starting ruleset:
# Remove any existing rules
-D
# Increase the buffers to handle bursts
-b 8192
# Failure mode: 1 = log failures, 2 = kernel panic (high-security only)
-f 1
# Watch critical authentication files
-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
# Watch SSH configuration
-w /etc/ssh/sshd_config -p wa -k sshd_config
# Log all uses of privileged commands
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -k root_commands
# Monitor changes to audit configuration itself
-w /etc/audit/ -p wa -k audit_config
-w /sbin/auditctl -p x -k audit_tools
-w /sbin/auditd -p x -k audit_tools
# Log time changes (potential log tampering indicator)
-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time_change
-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time_change
# Detect module loading/unloading
-a always,exit -F arch=b64 -S init_module,finit_module,delete_module -k kernel_modules
# Lock the ruleset (comment out during development)
-e 2
Warning: -e 2 makes the ruleset immutable until the next reboot. Comment it out while you are still testing; uncomment it for production.
Load the rules:
sudo augenrules --load
Confirm they loaded cleanly:
sudo auditctl -l
Watching Files and Directories
File watches are the fastest way to answer "who touched this file?" Add them with -w either in a rules file or transiently for quick investigation:
# Transient: watch /var/www/html for any writes or attribute changes
sudo auditctl -w /var/www/html -p wa -k webroot
Directory watches are recursive only one level deep by default in older kernels. On kernels 6.6+ with fanotify-backed audit watches, behavior may differ — check uname -r and your distribution's kernel notes. For deep trees on older kernels, add watches to each subdirectory or use an inotify-based tool alongside auditd.
# Persistent: watch a specific application config
echo '-w /etc/nginx/nginx.conf -p rwa -k nginx_config' | sudo tee -a /etc/audit/rules.d/50-local.rules
sudo augenrules --load
Reading the Audit Log
Raw logs land in /var/log/audit/audit.log. They are readable but dense. Use ausearch and aureport for human-usable output.
ausearch — Event-Level Queries
# Search by key tag
sudo ausearch -k identity --interpret
# Search by a specific user (by login UID)
sudo ausearch -ua 1001 --interpret
# Search events in the last 30 minutes
sudo ausearch -ts recent --interpret
# Search for failed events only
sudo ausearch --success no --interpret
The --interpret (or -i) flag translates numeric UIDs, syscall numbers, and architecture codes into human-readable strings. Always use it when reading output manually.
aureport — Summary Reports
# High-level summary of all event types
sudo aureport
# Summary of authentication events
sudo aureport --auth
# Failed authentication attempts
sudo aureport --auth --failed
# All executable events
sudo aureport --executable
# Events tagged with a specific key
sudo aureport --key --summary
Parsing a Raw Record
When you need the raw log, each record looks similar to this (output will vary):
sudo tail -f /var/log/audit/audit.log | grep 'key="identity"'
A typical record contains: type (event class), msg (timestamp and serial), syscall, pid, uid/auid (real UID vs. login UID), comm (command name), exe (full path), and key. The auid field survives sudo and su transitions, making it the reliable field for attribution.
Verification
Trigger a known event and confirm it appears in the log:
# Trigger the identity watch
sudo touch /etc/passwd
# Search for it
sudo ausearch -k identity -ts recent -i
You should see a record with type=SYSCALL referencing open or openat, the path /etc/passwd, and your login UID in auid. If the search returns nothing, run sudo auditctl -l to confirm the rule is loaded, and check sudo auditctl -s for the enabled/backlog status.
Troubleshooting
No events appearing
- Run
sudo auditctl -sand check thatenabledis1or2. If it shows0, the subsystem is disabled at the kernel level (rare; check kernel config withgrep AUDIT /boot/config-$(uname -r)). - Confirm
augenrules --loadexited cleanly; a bad rule silently fails to load the entire file on some versions. Checkjournalctl -u auditdfor parsing errors.
Log fills disk rapidly
- The
-a always,exit -S execverule on busy systems generates enormous volume. Narrow it with additional-Ffilters (e.g.,-F euid=0) or move it to a separate rules file behind a higher number so you can disable it quickly. - Adjust
max_log_fileandnum_logsinauditd.conf, or integrate withsystemd-journalvia theaudisp-syslogplugin and let journald handle rotation.
Rules lost after reboot
Rules placed only via auditctl do not persist. Always write them to /etc/audit/rules.d/ and run sudo augenrules --load. Also confirm the auditd service is enabled: sudo systemctl is-enabled auditd.
Frequently asked questions
- What is the difference between auid and uid in audit records?
- uid is the effective user ID at the time of the syscall, which changes when you run sudo or su. auid (audit UID) is stamped at login time and persists across those transitions, making it the reliable field for tracing an action back to the original human user.
- Will auditd catch actions taken by the root user?
- Yes. Kernel-level audit hooks fire regardless of privilege level. Root can clear the log after the fact if given the opportunity, which is why shipping logs off-host to a SIEM in real time is recommended for high-security environments.
- Does -w on a directory watch files recursively?
- On most production kernels (pre-6.6), directory watches cover only the immediate directory and its direct children, not deeper subdirectories. For deep trees, add explicit watches per subdirectory or supplement with an inotify-based solution.
- What does -e 2 actually do and can it be reversed without rebooting?
- -e 2 sets the kernel audit subsystem to immutable mode; no rule changes or configuration modifications are permitted until the next reboot. It cannot be reversed at runtime by any user, including root. Only use it once your ruleset is stable and tested.
- How do I reduce audit log noise from high-frequency syscalls?
- Narrow rules with additional -F filters such as euid=0, auid>=1000, or specific exe paths. You can also prepend a -a never,exit rule for known noisy processes before the broad catch-all rule, since the kernel evaluates rules top-to-bottom and stops at the first match.
Related guides
Manage Secrets with Ansible Vault
Encrypt Ansible secrets with AES-256 using ansible-vault: encrypt files and inline vars, automate with password files, and isolate group-level secrets with vault IDs.
AppArmor Explained
Learn how AppArmor profiles work, how to switch between enforce and complain mode, create new profiles, and diagnose access denials on Ubuntu, Debian, and Arch.
Apply CIS Benchmarks with OpenSCAP
Use OpenSCAP and scap-security-guide to evaluate, report on, and remediate Linux systems against CIS Benchmarks — covering install, eval, and automation.
How to Audit Linux Hardening with Lynis
Run Lynis to audit your Linux server, interpret the hardening index and warning output, and work through findings from critical to low-effort wins.