Audit Linux Systems With Auditd
Auditd is a service that can watch for various events including:
- failed/successful logins
- file or directory access and modifications
- process related events
- system calls
- user defined events using keys (labels)
Installation
auditd is usually pre-installed on RHEL-like distributions but may need to be installed manually on Ubuntu. If not already installed, install with:
# For RHEL-like Distros
sudo dnf install audit
# For Ubuntu
sudo apt update
sudo apt install auditd
On RHEL-like systems, auditd.service is configured to refuse manual start, stop, or restart actions. This is for security reasons, since stopping auditd could prevent events from being logged. Because of this, you should not attempt to start, stop, or restart the service using systemctl.
Verify auditd.service is running:
[tim@alma9 ~]$ systemctl status auditd
β auditd.service - Security Auditing Service
Loaded: loaded (/usr/lib/systemd/system/auditd.service; enabled; preset: enabled)
Active: active (running) since Fri 2025-07-25 16:29:13 UTC; 3min 39s ago
Docs: man:auditd(8)
https://github.com/linux-audit/audit-documentation
Main PID: 624 (auditd)
Tasks: 4 (limit: 12157)
Memory: 7.2M
CPU: 116ms
CGroup: /system.slice/auditd.service
ββ624 /sbin/auditd
ββ626 /usr/sbin/sedispatch
Jul 25 16:29:13 localhost augenrules[639]: enabled 1
Jul 25 16:29:13 localhost augenrules[639]: failure 1
Jul 25 16:29:13 localhost augenrules[639]: pid 624
Jul 25 16:29:13 localhost augenrules[639]: rate_limit 0
Jul 25 16:29:13 localhost augenrules[639]: backlog_limit 8192
Jul 25 16:29:13 localhost augenrules[639]: lost 0
Jul 25 16:29:13 localhost augenrules[639]: backlog 4
Jul 25 16:29:13 localhost augenrules[639]: backlog_wait_time 60000
Jul 25 16:29:13 localhost augenrules[639]: backlog_wait_time_actual 0
Jul 25 16:29:13 localhost systemd[1]: Started Security Auditing Service.
Define Temporary Audit Rules
Temporary rules defined with auditctl are cleared at reboot. Persistent rules should be added under /etc/audit/rules.d/ as shown in the next section. Still, temporary audit rules are useful for troubleshooting situations.
To define a watch rule to monitor file access/modification:
auditctl -w path_to_file_or_dir -p permissions -k key_name
-w is the file or directory to watch.
Valid permissions are:
rread filewwrite filexexecute fileaattribute change (i.e.chmod)
The -k option simply adds a tag (label) to events, which makes them easier to find using ausearch or grep.
For example, to watch /etc/passwd for file write and attribute change access:
sudo auditctl -w /etc/passwd -p wa -k user-modify
To test this rule, create a new user to trigger a write event on /etc/passwd:
sudo useradd testuser
Entries are logged in /var/log/audit/audit.log. We can search using our key user-modify:
[tim@alma9 ~]$ sudo grep "user-modify" /var/log/audit/audit.log
type=CONFIG_CHANGE msg=audit(1753466493.897:1942): auid=0 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 op=add_rule key="user-modify" list=4 res=1AUID="root"
type=SYSCALL msg=audit(1753466510.341:1951): arch=c000003e syscall=257 success=yes exit=5 a0=ffffff9c a1=561c438d6fc0 a2=20902 a3=0 items=1 ppid=9295 pid=9297 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="useradd" exe="/usr/sbin/useradd" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="user-modify"ARCH=x86_64 SYSCALL=openat AUID="root" UID="root" GID="root" EUID="root" SUID="root" FSUID="root" EGID="root" SGID="root" FSGID="root"
type=SYSCALL msg=audit(1753466510.355:1954): arch=c000003e syscall=82 success=yes exit=0 a0=7ffc527f1ef0 a1=561c438d6fc0 a2=7ffc527f1e60 a3=100 items=5 ppid=9295 pid=9297 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="useradd" exe="/usr/sbin/useradd" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="user-modify"ARCH=x86_64 SYSCALL=rename AUID="root" UID="root" GID="root" EUID="root" SUID="root" FSUID="root" EGID="root" SGID="root" FSGID="root"
To watch /etc/ recursively for changes to configuration files:
sudo auditctl -w /etc/ -p wa -k etc-watch
Define Persistent Audit Rules
The main config file /etc/audit/audit.rules is auto-generated by augenrules from /etc/audit/rules.d/*.rules files.
Add new rules by creating a new custom file, like /etc/audit/rules.d/10-user-modify.rules to keep rules organized. Paste the command as you would in the CLI, but omitting auditcl.
# /etc/audit/rules.d/10-user-modify.rules
-w /etc/passwd -p wa -k user-modify
Since we cannot systemctl restart auditd.service, to apply the new rule:
sudo augenrules --load
List active rules with auditctl -l:
[tim@alma9 ~]$ sudo auditctl -l
[sudo] password for tim:
-w /etc/passwd -p wa -k user-modify
Search Audit Logs
Use ausearch to search audit logs. By default, it searches the /var/log/audit/audit.log file.
sudo ausearch -i -k user-modify
-i will translate UIDs/GIDs/Syscall IDs to named values. For example, running ausearch -k user-modify, we see:
syscall=44uid=0gid=0
With ausearch -i -k user-modify we get the following:
syscall=sendtouid=rootgid=root
We can filter logs in other ways too:
# Filter by key
sudo ausearch -k user-modify
# Filter by time
# ts: time start
# te: time end
sudo ausearch -ts today
# using MM/DD/YY
sudo ausearch -ts 07/24/25 -te 07/25/25
# filter by executable/process name
sudo ausearch -x vim
# filter by syscall
sudo ausearch -sc openat
Create Audit Reports
Use aureport to generate audit reports. aureport reads from /var/log/audit/audit.log by default. You can also specify a different log file with -if <file> if needed.
To generate an overview audit report:
[tim@alma9 ~]$ sudo aureport
Summary Report
======================
Range of time in logs: 07/25/25 16:29:13.859 - 07/25/25 18:38:00.296
Selected time for report: 07/25/25 16:29:13 - 07/25/25 18:38:00.296
Number of changes in configuration: 9
Number of changes to accounts, groups, or roles: 19
Number of logins: 1
Number of failed logins: 218
Number of authentications: 6
Number of failed authentications: 0
Number of users: 2
Number of terminals: 6
Number of host names: 22
Number of executables: 12
Number of commands: 10
Number of files: 5
Number of AVC's: 3
Number of MAC events: 2
Number of failed syscalls: 3
Number of anomaly events: 0
Number of responses to anomaly events: 0
Number of crypto events: 1318
Number of integrity events: 0
Number of virt events: 0
Number of keys: 1
Number of process IDs: 491
Number of events: 2185
Report failed/successful logins (I have redacted public IPs):
[tim@alma9 ~]$ sudo aureport -l | head
Login Report
============================================
# date time auid host term exe success event
============================================
1. 07/25/25 16:29:29 0 x.x.x.x /dev/pts/0 /usr/sbin/sshd yes 87
2. 07/25/25 16:37:17 (unknown) x.x.x.x ssh /usr/sbin/sshd no 281
3. 07/25/25 16:46:33 root x.x.x.x ssh /usr/sbin/sshd no 291
...
Report file access and modifications:
[tim@alma9 ~]$ sudo aureport -f
File Report
===============================================
# date time file syscall success exe auid event
===============================================
1. 07/25/25 16:29:14 gnutls.config 262 no /usr/sbin/chronyd -1 20
2. 07/25/25 16:29:14 /var/log/hawkey.log 262 no /usr/sbin/logrotate -1 24
3. 07/25/25 16:29:14 /var/log/hawkey.log 262 no /usr/sbin/logrotate -1 26
4. 07/25/25 18:01:50 /etc/passwd 257 yes /usr/sbin/useradd 0 1951
5. 07/25/25 18:01:50 /etc/ 82 yes /usr/sbin/useradd 0 1954
Report system calls:
[tim@alma9 ~]$ sudo aureport --syscall
Syscall Report
=======================================
# date time syscall pid comm auid event
=======================================
1. 07/25/25 16:29:13 44 639 auditctl -1 6
2. 07/25/25 16:29:13 44 639 auditctl -1 7
3. 07/25/25 16:29:13 44 639 auditctl -1 8
...
We can also pipe the output of ausearch into aureport to customize reports. For example, to create a report based on the user-modify key defined earlier:
[tim@alma9 ~]$ sudo ausearch -k user-modify | sudo aureport -f
File Report
===============================================
# date time file syscall success exe auid event
===============================================
1. 07/25/25 18:01:50 /etc/passwd 257 yes /usr/sbin/useradd 0 1951
2. 07/25/25 18:01:50 /etc/passwd 82 yes /usr/sbin/useradd 0 1954