Skip to content

auditd: file access and syscall logging

Linux doesn’t write every access to /etc/shadow or every unlink call to syslog. For incident investigation and compliance this is critical. auditd solves this: the Linux Audit kernel subsystem records system calls, file access, and more.

Installation and Startup

auditd comes in the audit package available in any distribution.

# Debian/Ubuntu
apt install auditd

# RHEL/CentOS/Alma
yum install audit

# Arch
pacman -S audit

After installation, start the service via systemd.

systemctl enable --now auditd

Check status and current rules:

systemctl status auditd
auditctl -l
Note

On RHEL-based distributions with SELinux enabled, you may need to adjust policies for auditd to work with non-standard paths. Standard installation usually covers most cases.

File Monitoring: the -w Flag

The -w flag adds a watch rule for a file. By default it tracks open, read, write, truncate, chmod, and chown.

# Watch the password file
auditctl -w /etc/shadow -p rwxa -k shadow_access

# Watch the nginx config directory
auditctl -w /etc/nginx/ -p rwxa -k nginx_config
FlagMeaning
-wpath to watch
-ppermissions: r(read), w(write), x(execute), a(append)
-kkeyword for searching in logs

Verify rules:

auditctl -l

Remove a rule by key:

auditctl -W /etc/shadow -p rwxa -k shadow_access

Rules added via auditctl don’t survive reboots. For persistence, write rules to /etc/audit/rules.d/:

echo "-w /etc/shadow -p rwxa -k shadow_access" >> /etc/audit/rules.d/audit.rules

On RHEL, rules load from /etc/audit/audit.rules via the augenrules script. Same works on Debian/Ubuntu.

System Call Logging: the -S Flag

The -S flag records the specified system call for all processes or with filters.

# Log file deletions
auditctl -S unlink -S unlinkat -k file_deletion

# Log socket creation
auditctl -S socket -k network_socket

Check available system calls with ausyscall --dump. Not all calls are available on every architecture — on x86_64 some go through the compat layer.

Warning

Excessive syscall monitoring generates massive log volume. On production servers, limit rules with filters.

Combined rule — syscall plus path:

# Only deletions from /var/log/
auditctl -S unlink -S unlinkat -w /var/log/ -p wa -k log_deletion

Filtering by UID and Executable

Without filters, rules apply globally. Add conditions for targeted monitoring.

# Only rm executions by www-data user
auditctl -S execve -a always,entry -F arch=b64 -F uid=33 -F exe=/usr/bin/rm -k rm_by_www

# All access() calls to file from any uid
auditctl -a always,entry -S access -F path=/etc/shadow -F perm=r -k shadow_read

Core filter fields:

FlagDescriptionExample
-Ffield to compare-F uid=1000
archarchitecture (b32/b64)-F arch=b64
uidreal UID-F uid=33
euideffective UID-F euid=0
exefull path to executable-F exe=/bin/bash
permaccess permissions-F perm=awx

Combine filters into a chain via -a:

auditctl -a always,entry -S openat -F dir=/etc -F perm=w -F uid=0 -k etc_write_root

Reading Logs: ausearch

Logs live in /var/log/audit/audit.log. Binary format, read with ausearch.

# Search by keyword
ausearch -k shadow_access

# Search by time (today, last hour)
ausearch -k shadow_access -ts today
ausearch -k shadow_access -ts recent

# Search by user
ausearch -k shadow_access -ui 0

# Search by event type
ausearch -m SYSCALL -k file_deletion

# Filter by result (success/failure)
ausearch -k shadow_access -sv success
ausearch -k shadow_access -sv failed

Useful output formats:

# Raw text (default)
ausearch -k shadow_access -i

# CSV for parsing
ausearch -k shadow_access --format csv
Tip

For automation, use -if (input file) — read from a dump instead of the live log:

ausearch -if /tmp/audit_events.dump -k shadow_access

Reading Logs: aureport

aureport aggregates logs into readable reports.

# Summary of all events
aureport

# System call report
aureport -s

# File event report
aureport -f

# User report
aureport -u

# Timeline report
aureport -t

# Errors and failures only
aureport --failed

Typical aureport -s output:

Syscall Report
============================================
UID        Syscall    Count
--------------------------------------------
0          unlink      12
0          openat      8
33         unlink      3

Quick investigation combo — summary then details:

aureport -t -i | head -20
ausearch -k file_deletion -ts recent | less

For SIEM or ELK ingestion, convert logs to JSON or text:

ausearch -k shadow_access --format json > /var/log/audit/shadow_access.json

auditd doesn’t require complex setup to start capturing critical events. Install the package, add a few rules with keywords, and get comfortable with ausearch and aureport for log review.