Table of Contents
Understanding Auditd’s Role
auditd is the userspace component of the Linux Auditing System. The kernel produces audit events; auditd receives them, writes them to disk, and applies configuration such as rules and rate limits.
Key pieces:
- Kernel audit subsystem (enabled by
auditkernel parameter orCONFIG_AUDIT) auditddaemon (/sbin/auditdor/usr/sbin/auditd)auditctlfor runtime rule managementaugenrulesfor rules from config filesausearchandaureportfor reading and reporting on logs- Audit logs, usually in
/var/log/audit/audit.log
This chapter focuses specifically on configuring and using auditd, assuming you already understand general logging concepts.
Installing and Enabling Auditd
On common distributions:
- RHEL / CentOS / Rocky / Alma / Fedora:
sudo dnf install audit
sudo systemctl enable --now auditd- Debian / Ubuntu:
sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditdVerify it’s running:
sudo systemctl status auditd
sudo auditctl -s # show audit subsystem status
Typical auditctl -s output fields:
enabled:1(running),0(disabled),2(immutable)pid: PID ofauditdbacklog_limit: max queued records in kernellost: lost events count (should stay at 0)backlog_wait_time: time kernel waits before dropping/logging
Auditd Configuration Files
Main locations (paths may vary slightly by distro):
- Daemon config:
/etc/audit/auditd.conf - Rules:
- RHEL/Fedora-style:
/etc/audit/rules.d/*.rulesplus/etc/audit/audit.rules - Debian/Ubuntu: same structure, though they may ship different defaults
Key Options in `/etc/audit/auditd.conf`
Some of the most important options:
log_file = /var/log/audit/audit.log
Path of the main audit log.log_format = RAW|ENRICHEDRAW: numeric UIDs/GIDs, codes; best for tooling.ENRICHED: resolves names (usernames, paths); more readable but slightly heavier.max_log_file = <MB>
Maximum size of each log file before rotation (default often 8 MB or 32 MB).num_logs = <N>
How many rotated logs to keep (e.g.,5keepsaudit.log,audit.log.1, …audit.log.4).max_log_file_action = ROTATE|KEEP_LOGS|SUSPEND|IGNORE|SYSLOG
What to do whenmax_log_fileis reached:ROTATE: rotate and overwrite oldest beyondnum_logs.KEEP_LOGS: keep adding new files; can eventually fill disk.SUSPEND: stop logging until space is freed.IGNORE: continue writing past size (not recommended).SYSLOG: write warning via syslog.space_left = <MB>
When free space on the filesystem drops below this,space_left_actionis triggered.space_left_action = SYSLOG|EMAIL|EXEC|SUSPEND|SINGLE|HALT
How to react whenspace_leftis reached:SYSLOG: send a syslog warning.EMAIL: send email toaction_mail_acct.EXEC: rundispatcheror script.SUSPEND: stop logging.SINGLE: go to single-user mode.HALT: shut down the system.
The more severe actions are for very strict environments.admin_space_left = <MB>
Lower threshold thanspace_left; when reached,admin_space_left_actionis used (often more severe).flush = INCREMENTAL|DATA|SYNC|NONE
Controls how often data is flushed to disk vs buffered.name_format = NONE|HOSTNAME|FQDN|USER|NUMERIC
How to tag records with the system identity.
After modifying auditd.conf, reload:
sudo systemctl reload auditd
# or, if not supported:
sudo systemctl restart auditdManaging Audit Rules
Audit rules tell the kernel what to watch and which syscalls or files to record.
There are two main ways:
- Temporary (runtime) via
auditctl - Persistent (on boot) via
augenrules+ files under/etc/audit/rules.d/
Runtime Rules with `auditctl`
View current rules:
sudo auditctl -lRemove all rules:
sudo auditctl -DMark rules as immutable (cannot be changed until reboot):
sudo auditctl -e 2Mode values:
0: disabled1: enabled2: enabled and rules immutable
Once you set -e 2, you cannot change rules without rebooting; this is used for tamper-resistant configurations.
Persistent Rules with `augenrules`
The typical workflow:
- Put rule files in
/etc/audit/rules.d/with.rulesextension, e.g.: /etc/audit/rules.d/10-base.rules/etc/audit/rules.d/30-privileged.rules- Build and load them:
sudo augenrules --load- Confirm:
sudo auditctl -l
On boot, augenrules is usually called by the auditd unit to load all rules from /etc/audit/rules.d.
Audit Rule Types and Syntax
Audit rules mainly come in two kinds:
- Control/filter rules (
-D,-e,-f, etc.) - Watch rules for syscalls/paths (
-a,-w)
You’ll often see:
-a <list>,<action>for syscall rules-w <path> -p <perms> -k <key>for file watches
Watch Rules (`-w`)
These are easy to start with. General form:
-w <path> -p <rwxad> -k <key>-w <path>: path to watch-p: permission mask for events:r= readw= writex= executea= attribute change-k <key>: tag using a simple string (not actually stored askey, but askey=in the record for searching)
Examples:
Watch /etc/passwd for writes and attribute changes:
-w /etc/passwd -p wa -k passwd_changes
Watch /etc/sudoers for any modification:
-w /etc/sudoers -p wa -k sudoers_change
Note: -w rules are internally translated to -a syscall rules; they are path-based convenience syntax.
Syscall Rules (`-a`)
Syscall rules inspect particular syscalls based on architecture, filters, and fields.
Basic form:
-a <list>,<action> -S <syscall>[,<syscall>...] [conditions] -F key=<key><list>: one of:task: affects task creationexit: filters on syscall exit (most common)user,exclude, etc. (special-purpose)<action>: usuallyalways(log when matched) ornever(suppress)-S: syscall name (open,unlink,chmod, etc.)- Conditions:
-F <field><op><value>, such as: -F arch=b64(64-bit syscalls)-F uid=0(root user)-F auid>=1000 -F auid!=4294967295(real human logins)-F dir=/path(directory constraint)-F key=<name>: tag with a key
Example: log all attempts by non-root users to run chmod:
-a always,exit -F arch=b64 -S chmod -F uid!=0 -F key=chmod_nonroot
Example: log file deletions by real users in /home:
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F dir=/home -F auid>=1000 -F auid!=4294967295 -F key=home_delete
Note on auid vs uid:
uid: effective user ID for the process at the time.auid: audit user ID — the user who originally logged in, persists acrosssudo,su, etc.
For tracking real user sessions,auidis generally what you want.
Example Baseline Rule File
A minimal hardening-friendly set in /etc/audit/rules.d/10-base.rules:
# Erase all existing rules
-D
# Set buffer size
-b 8192
# Enable auditing and lock rules after they are set
-e 2
Another file, /etc/audit/rules.d/30-identity.rules:
# Watch passwd and group databases
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
And /etc/audit/rules.d/40-privileged.rules:
# Watch changes to sudoers
-w /etc/sudoers -p wa -k scope
# Track use of sudo
-w /var/log/sudo.log -p wa -k sudo_log # path may differ by distroAfter saving:
sudo augenrules --loadUsing ausearch to Query Audit Logs
ausearch understands the audit log format and filters by fields and keys.
Common options:
-k <key>: search by rule key-x <exe>: filter by executable-ua <auid>: filter by audit user ID (login user)-m <type>: filter by message type (SYSCALL,USER_LOGIN, etc.)-ts <time>: start time (e.g.-ts today,-ts 10:00)-te <time>: end time
Examples:
Show all events tagged with key passwd_changes:
sudo ausearch -k passwd_changesShow all sudo-related events in the last hour:
sudo ausearch -k sudo_log -ts recent
Show all failed login attempts (message type often USER_LOGIN or USER_AUTH):
sudo ausearch -m USER_LOGIN -sv no
(-sv no filters by success=no.)
Print in a more human-readable, interpreted format:
sudo ausearch -k home_delete --interpretInterpreting a SYSCALL Record
A SYSCALL record may look like:
type=SYSCALL msg=audit(1700000000.123:456): arch=c000003e syscall=59 success=yes exit=0 \
a0=55c3a5b6b4d0 a1=55c3a5b6b520 a2=55c3a5b6b540 a3=8 items=2 ppid=1234 pid=5678 \
auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 \
tty=pts0 ses=2 comm="sudo" exe="/usr/bin/sudo" key="sudo_exec"Critical fields:
success=yes/no: whether the syscall succeededauid=1000: original login user (UID 1000)uid=0 euid=0 ...: current identity (root in this example)comm="sudo"andexe="/usr/bin/sudo": command name and executable pathkey="sudo_exec": rule key that triggered this eventitems=2: number of path items, see accompanyingPATHrecords
Use ausearch --interpret to decode numeric IDs and flags into names.
Summarizing with aureport
aureport builds summaries such as:
- By user
- By executable
- Authentication failures
- System calls, etc.
Examples:
Overall summary:
sudo aureportAuthentication report:
sudo aureport -auFailed logins:
sudo aureport -au --failedFile access report:
sudo aureport -fProcess/executable report:
sudo aureport -x
Include time range with --start/--end if needed:
sudo aureport -x --start today --end nowIntegrating Auditd with Other Tools
audispd and Plugins
Some distros split responsibilities:
auditdwrites local logs.audispddispatches events to plugins (e.g., for forwarding).
Plugins live under /etc/audisp/plugins.d/ or similar. Common use cases:
- Forward audit logs to a SIEM via syslog
- Real-time alerting scripts based on certain keys
Enabling a plugin involves:
- Editing its config file in
plugins.d - Setting
active = yes - Configuring its destination/server/port as appropriate
Syslog and Central Logging
While audit logs are structured separately, you may want key events also present in syslog or in a central logging stack.
Methods include:
- Use an
audispdplugin that sends key events to syslog. - Use a log shipper (e.g. Filebeat, rsyslog modules) to send
/var/log/audit/audit.logto a central server.
Keep in mind:
- Don’t rely on copying raw audit logs alone for real-time alerting; use filtering and keys to reduce noise.
- Avoid double-logging huge volumes (performance and storage impact).
Performance and Reliability Considerations
Auditd can produce a lot of data and overhead if misconfigured.
Avoiding Excessive Logging
- Target specific paths instead of using global rules like “log all
open()calls”. - Use
auidfilters to track real users (auid>=1000 -F auid!=4294967295) instead of system daemons. - Focus on high-value areas: authentication, privilege escalations, key config files, security-sensitive directories.
Monitor:
sudo auditctl -s: checklost=is 0./var/log/audit/audit.log: watch foraudit backlog limit exceededmessages.
Adjust:
-bbuffer size in rules (-b 8192,-b 16384).backlog_limitin kernel parameters (audit_backlog_limit=8192on kernel cmdline) if needed.
Preventing Disk-Full Situations
Effective use of:
max_log_file,num_logsmax_log_file_action
UseROTATEorKEEP_LOGScarefully.
Configure space_left and admin_space_left with appropriate actions (e.g. SYSLOG then SUSPEND) so you’re alerted before the partition fills.
Example Use Cases
Monitoring Critical Config Files
In /etc/audit/rules.d/50-etc.rules:
-w /etc/ssh/sshd_config -p wa -k ssh_config
-w /etc/hosts -p wa -k network_config
-w /etc/fstab -p wa -k mount_configLoad:
sudo augenrules --loadQuery later:
sudo ausearch -k ssh_config --interpretTracking Use of Specific Binaries
Suppose you want to track whenever someone runs /bin/su:
-a always,exit -F arch=b64 -S execve -F exe=/bin/su -F auid>=1000 -F auid!=4294967295 -F key=su_usage
Add to /etc/audit/rules.d/60-su.rules and load via augenrules.
Then:
sudo ausearch -k su_usage --interpretMonitoring Access to a Sensitive Directory
Track reads/writes in /secret by real users:
-a always,exit -F arch=b64 -S open,openat,creat,truncate,ftruncate \
-F dir=/secret -F auid>=1000 -F auid!=4294967295 -F key=secret_accessLater:
sudo ausearch -k secret_access --interpret
sudo aureport -f --summary | grep secretHardening Auditd
For environments that require strong tamper resistance:
- Load rules at boot from
/etc/audit/rules.d. - At the end of your rules, set immutable mode:
-e 2- Protect
/etc/auditand/var/log/auditwith strict file permissions and backups. - Consider kernel parameters:
audit=1: enable audit at boot.audit_backlog_limit=<N>: raise backlog limit.
Once -e 2 is set and the system has booted with audit=1, even root cannot modify audit rules without rebooting, which gives you a more trustworthy trail for incident response.