Background & Why bash_history Isn’t Enough
Many sysadmins still rely on ~/.bash_history to track user activity. This approach is fraught with risk. Anyone who gains shell access can easily disable history tracking with a few simple tricks: running unset HISTFILE, prefixing commands with a leading space, or symlinking the history file to /dev/null. When configuration files are tampered with or data is leaked, you are left with virtually no audit trail.
The Linux Audit Framework (powered by the auditd daemon) tackles this problem directly at the kernel level. Every critical system call—such as opening a file (openat), writing (write), deleting (unlinkat), or executing a binary (execve)—is intercepted by the kernel. An attacker can wipe user-space history, but they cannot tamper with logs already recorded at the kernel layer, which also records security events generated by security frameworks like SELinux and AppArmor.
Resource overhead is minimal. On an Ubuntu 22.04 server (2 vCPUs, 4GB RAM) running Nginx and Node.js at roughly 1,200 req/s, the auditd daemon consumes less than 35MB of RAM and under 1.5% CPU.
Installing the Service
Red Hat-family distributions (RHEL, Rocky Linux, AlmaLinux) typically come with auditd pre-installed. On Ubuntu/Debian, install it via APT:
sudo apt update
sudo apt install -y auditd audispd-plugins
For CentOS Stream or Rocky Linux (if not included in minimal installs):
sudo dnf install -y audit
Enable and start the service on system boot:
sudo systemctl enable auditd
sudo systemctl start auditd
Important Note: Running systemctl restart auditd is often blocked by design. This safeguards against rogue processes restarting the daemon to interrupt logging streams. To reload rules without interrupting the service, run:
sudo augenrules --load
# If restarting the entire process is strictly required:
sudo service auditd restart
Detailed Configuration
A standard auditd setup consists of two main parts: the daemon configuration file at /etc/audit/auditd.conf and the rule directory at /etc/audit/rules.d/.
1. Tuning auditd.conf to Prevent Disk Exhaustion
The default log file at /var/log/audit/audit.log can grow rapidly, making tools like ncdu and duf for visual disk usage analysis essential when troubleshooting sudden capacity spikes. Open /etc/audit/auditd.conf and adjust the size-control parameters:
# Limit each log file to a maximum of 50MB
max_log_file = 50
# Keep up to 10 rotated log files (~500MB total fixed disk usage)
num_logs = 10
# Automatically rotate logs upon reaching the size limit
max_log_file_action = ROTATE
# Asynchronous disk flushing to prevent I/O bottlenecks
flush = INCREMENTAL_ASYNC
freq = 50
2. Configuring Audit Rules
Avoid editing /etc/audit/audit.rules directly because the system will overwrite it on reboot. Instead, create a dedicated file at /etc/audit/rules.d/custom.rules:
sudo nano /etc/audit/rules.d/custom.rules
Below is a production-ready configuration template:
# Clear all existing rules before loading
-D
# Set buffer size to 8192 events (prevents dropped log events during sudden traffic spikes)
-b 8192
# 1. Monitor user account and privilege files
-w /etc/passwd -p wa -k identity_changes
-w /etc/shadow -p wa -k identity_changes
-w /etc/group -p wa -k identity_changes
-w /etc/gshadow -p wa -k identity_changes
-w /etc/sudoers -p wa -k sudoers_changes
-w /etc/sudoers.d/ -p wa -k sudoers_changes
# 2. Monitor SSH configuration
-w /etc/ssh/sshd_config -p wa -k sshd_config
# 3. Record all commands executed by real users (UID >= 1000)
-a always,exit -F arch=b64 -S execve -F auid>=1000 -F auid!=unset -k user_commands
-a always,exit -F arch=b32 -S execve -F auid>=1000 -F auid!=unset -k user_commands
# 4. Monitor system clock modifications
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time_change
-a always,exit -F arch=b64 -S clock_settime -k time_change
# 5. Lock rules in immutable mode (must be the final line)
-e 2
Core parameters to remember:
-w <path>: Path to the target file or directory to monitor.-p wa: Captures write events (w) and file attribute changes (a).-k <key>: Assigns a searchable key label for fast log queries withausearch.-F auid>=1000: Filters events to include only real logged-in users. This discards background daemons such as cron, nginx, or prometheus to prevent log flooding.-e 2: Sets all rules to immutable mode. Once enabled, no account—includingroot—can modify or disable rules without a full system reboot.
After saving the file, load the new configuration into the kernel:
sudo augenrules --load
Querying and Analyzing Incident Logs
The raw log file contains hex-encoded strings and raw unix timestamps, making manual inspection tedious. Use the two standard audit utilities instead: ausearch and aureport.
1. Verifying Rules Loaded in the Kernel
sudo auditctl -l
2. Tracing Modifications to Sensitive Files
When you suspect unauthorized changes to system accounts, filter events using the key identity_changes:
sudo ausearch -k identity_changes -i
The -i (interpret) option automatically resolves timestamps into local time and translates UIDs/GIDs into human-readable usernames. The output is clear and straightforward:
type=SYSCALL msg=audit(21/10/2026 14:22:05.312:108) : arch=x86_64 syscall=openat success=yes exit=3 comm="vim" exe="/usr/bin/vim" auid=kien.nguyen uid=root gid=root key="identity_changes"
The log line above pinpoints the exact sequence: user kien.nguyen (the original auid) used root privileges via vim to modify the file.
3. Filtering User Commands Run Today
To inspect all commands entered by users since the start of the day:
sudo ausearch -ts today -k user_commands -i
The output returns the full command-line arguments and the parent process that executed each command.
4. Generating Overview Reports with aureport
When collaborating with security compliance teams or conducting routine reviews, aureport quickly aggregates key metrics:
- Summary of authentication attempts (successful and failed):
sudo aureport --auth -i
- List of most frequently accessed files:
sudo aureport -f -i --summary
- Audit of privilege elevation sessions (
sudo/su):
sudo aureport -u -i
By monitoring critical privilege files and tracking user command execution, you establish an independent logging mechanism that provides comprehensive audit trails for incident response—immune to user-space tampering. To prevent local logs from being deleted during a system breach, consider centralizing Linux logs to a dedicated remote server.

