The Linux Audit Framework, managed by the auditd daemon, records security-relevant kernel events to a structured log for compliance auditing, incident investigation, and intrusion detection. On RHEL 9, auditd is installed and enabled by default, giving you an immediate foundation for building a comprehensive security event trail. This tutorial covers configuring the audit daemon log rotation settings, writing persistent audit rules to monitor file access, process execution, and network connections, and using the ausearch and aureport tools to query and summarize the collected data. Following these steps will bring your system closer to meeting requirements in frameworks such as CIS RHEL 9 Benchmark and PCI-DSS.

Prerequisites

  • RHEL 9 server with auditd installed (installed by default; confirm with rpm -q audit)
  • A non-root user with sudo privileges
  • Basic familiarity with Linux file paths and system administration
  • Sufficient disk space in /var/log/audit for your expected log volume

Step 1 — Check auditd Status and Default Configuration

Verify that auditd is running and review the key settings in its main configuration file before making changes.

sudo systemctl status auditd

# View the main configuration file
cat /etc/audit/auditd.conf

# Check currently loaded audit rules
sudo auditctl -l

# Check the current log file location and size
ls -lh /var/log/audit/

# Display auditd version
auditd --version

Step 2 — Tune auditd Log Rotation Settings

Edit /etc/audit/auditd.conf to configure how many log files to keep, the maximum size of each, and what action to take when disk space runs low. These settings prevent the audit log from consuming all available disk space.

sudo cp /etc/audit/auditd.conf /etc/audit/auditd.conf.bak

sudo tee /etc/audit/auditd.conf > /dev/null <<'EOF'
log_file = /var/log/audit/audit.log
log_format = ENRICHED
log_group = root
priority_boost = 4
flush = INCREMENTAL_ASYNC
freq = 50
num_logs = 10
disp_qos = lossy
dispatcher = /sbin/audispd
name_format = NONE
max_log_file = 50
max_log_file_action = ROTATE
space_left = 500
space_left_action = SYSLOG
admin_space_left = 100
admin_space_left_action = SUSPEND
disk_full_action = SUSPEND
disk_error_action = SYSLOG
EOF

sudo systemctl restart auditd
sudo systemctl status auditd

Step 3 — Write Persistent Audit Rules

Create a persistent rules file in /etc/audit/rules.d/ to monitor sensitive file modifications, track all process execution, and log outbound network connection attempts. Rules in this directory survive reboots and are compiled by augenrules.

sudo tee /etc/audit/rules.d/audit.rules > /dev/null <<'EOF'
# Delete all existing rules first
-D

# Increase buffer size for high-traffic systems
-b 8192

# Failure mode: 1 = print a message, 2 = panic (use 1 for production)
-f 1

# --- File integrity: watch for writes and attribute changes ---
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/group -p wa -k group_changes
-w /etc/sudoers -p wa -k sudoers_changes
-w /etc/sudoers.d/ -p wa -k sudoers_changes
-w /etc/ssh/sshd_config -p wa -k sshd_config

# --- Process execution: log all exec syscalls on 64-bit kernel ---
-a always,exit -F arch=b64 -S execve -k exec_commands
-a always,exit -F arch=b32 -S execve -k exec_commands

# --- Network: log outbound connect() calls ---
-a always,exit -F arch=b64 -S connect -k network_connect
-a always,exit -F arch=b32 -S connect -k network_connect

# --- Privileged commands ---
-a always,exit -F path=/usr/bin/sudo -F perm=x -k privileged_sudo
-a always,exit -F path=/usr/bin/su -F perm=x -k privileged_su

# Lock rules so they cannot be changed at runtime (comment out during development)
# -e 2
EOF

# Compile and load all rules from /etc/audit/rules.d/
sudo augenrules --load
sudo auditctl -l

Step 4 — Add and Test Temporary Rules with auditctl

Use auditctl to add rules at runtime for testing without modifying the persistent rules file. These rules are lost on reboot or when augenrules --load is run again.

# Add a temporary watch on /tmp for any writes
sudo auditctl -w /tmp -p wa -k tmp_writes

# Confirm the rule is loaded
sudo auditctl -l | grep tmp_writes

# Trigger the rule by writing a file
touch /tmp/audit_test_file

# Check that the event was logged
sudo ausearch -k tmp_writes -ts recent

# Remove the temporary rule
sudo auditctl -W /tmp -p wa -k tmp_writes

Step 5 — Search Audit Logs with ausearch

The ausearch tool lets you filter the binary audit log by key, time range, user, syscall, and more. It interprets numeric UIDs and syscall numbers into human-readable form.

# Search for all events tagged with the passwd_changes key today
sudo ausearch -k passwd_changes -ts today

# Search for all sudo executions in the last hour
sudo ausearch -k privileged_sudo -ts recent

# Search for events by a specific user (replace 1001 with the actual UID)
sudo ausearch -ua 1001 -ts today

# Search for failed login attempts
sudo ausearch -m USER_LOGIN -sv no -ts today

# Show raw audit records (useful for parsing)
sudo ausearch -k exec_commands -ts today -i | head -60

Step 6 — Generate Compliance Reports with aureport

The aureport command produces formatted summary reports from the audit log covering authentication events, file access, anomalies, and more — useful for daily review and compliance evidence.

# Summary of all audit events today
sudo aureport --start today --end now

# Authentication report (logins, su, sudo)
sudo aureport -au --start today --end now

# Executable report — what programs ran today
sudo aureport -x --start today --end now | head -40

# File access report
sudo aureport -f --start today --end now | head -40

# Anomaly report (failed system calls, access denied)
sudo aureport --anomaly --start today --end now

# Failed events report
sudo aureport --failed --start today --end now

Conclusion

Your RHEL 9 system now has a hardened auditd configuration with log rotation limits that protect disk space, persistent rules watching critical authentication files, all process executions, and outbound network connections, and convenient search and reporting tools for incident response and compliance reviews. The rules file in /etc/audit/rules.d/audit.rules is the authoritative source — edit it and run sudo augenrules --load whenever you add or remove rules. For regulated environments, consider appending the CIS RHEL 9 audit rule set which covers additional syscalls and file paths required by the benchmark.

Next steps: How to Set Up Checksum Monitoring with AIDE on RHEL 9, How to Forward auditd Logs to a Remote Syslog Server with audisp-remote, and How to Configure SELinux Policies for Custom Applications on RHEL 9.