How to Perform a System Security Audit with auditd on RHEL 7

Security auditing is a critical practice for any production RHEL 7 system, especially those subject to compliance frameworks such as PCI-DSS, HIPAA, or DISA STIG. The Linux Audit Framework, centered on the auditd daemon, provides kernel-level monitoring of system calls, file access, user authentication, and privilege escalation — generating a tamper-evident log trail that satisfies regulatory requirements. This guide walks you through enabling and configuring auditd, writing audit rules, and using the ausearch and aureport tools to analyze the resulting logs on RHEL 7.

Prerequisites

  • A RHEL 7 system with root or sudo access
  • The audit package installed (installed by default on RHEL 7)
  • A basic understanding of Linux file permissions and system calls

Step 1: Verifying and Starting auditd

The auditd service is part of the audit package and is installed by default on RHEL 7. Verify it is present and running:

# Check if the audit package is installed
rpm -q audit

# Install if missing
sudo yum install -y audit

# Check service status
sudo systemctl status auditd

# Enable auditd to start at boot
sudo systemctl enable auditd

# Start the service
sudo systemctl start auditd

Confirm the audit daemon is actively logging by checking its log file:

sudo tail -20 /var/log/audit/audit.log

Important: Unlike most systemd services, auditd should not be restarted with systemctl restart — this can cause a brief logging gap. Use the audit-specific reload command instead:

sudo service auditd reload

Step 2: Understanding the Audit Rules File

Audit rules are defined in /etc/audit/audit.rules. On a freshly installed RHEL 7 system this file is minimal, containing only a few default rules. The structure of rule files follows the same syntax as the auditctl command-line tool:

sudo cat /etc/audit/audit.rules

A typical default output looks like:

## This file is automatically generated from /etc/audit/rules.d
-D
-b 8192
-f 1

The directives mean:

  • -D — Delete all existing rules before loading these
  • -b 8192 — Set the kernel audit buffer to 8192 entries
  • -f 1 — Set failure mode to 1 (log failures silently)

On RHEL 7, rules are also read from individual .rules files in /etc/audit/rules.d/, which are merged into /etc/audit/audit.rules at service startup by augenrules.

Step 3: Writing File Watch Rules with -w

The most common audit rule type watches a file or directory for access. The -w flag specifies the path, -p specifies the permissions to watch, and -k assigns a searchable key tag:

# Watch /etc/passwd for reads, writes, attribute changes, and executes
sudo auditctl -w /etc/passwd -p rwxa -k passwd_changes

# Watch /etc/shadow for all access
sudo auditctl -w /etc/shadow -p rwxa -k shadow_changes

# Watch the sudoers file for modifications
sudo auditctl -w /etc/sudoers -p wa -k sudoers_changes

# Watch an entire directory
sudo auditctl -w /etc/ssh/ -p wa -k sshd_config_changes

Permission flags for -p:

  • r — read
  • w — write
  • x — execute
  • a — attribute change (ownership, permissions)

To make rules persistent, add them to /etc/audit/rules.d/audit.rules using the same syntax (without sudo auditctl):

sudo vi /etc/audit/rules.d/audit.rules
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/sudoers -p wa -k sudoers_changes
-w /etc/ssh/sshd_config -p wa -k sshd_config

Step 4: Writing System Call Rules with -a

System call rules audit specific kernel syscalls, which is essential for detecting privilege escalation and unauthorized program execution. The syntax uses -a action,list:

# Audit all execve() calls by non-root users (monitor command execution)
sudo auditctl -a always,exit -F arch=b64 -S execve -F auid>=1000 -F auid!=4294967295 -k user_commands

# Audit setuid/setgid program execution
sudo auditctl -a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -k privilege_escalation

# Audit failed file access attempts (permission denied)
sudo auditctl -a always,exit -F arch=b64 -S open -F exit=-EACCES -k access_denied
sudo auditctl -a always,exit -F arch=b64 -S open -F exit=-EPERM -k access_denied

# Monitor use of the chmod system call
sudo auditctl -a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -k chmod_calls

Key fields used in syscall rules:

  • arch=b64 — 64-bit architecture (use b32 for 32-bit, or add both)
  • auid — Audit UID (the login UID, set at login and preserved across su/sudo)
  • euid — Effective UID

Step 5: Using Pre-configured Rule Sets

RHEL 7 ships with pre-built rule sets designed for common compliance frameworks in /usr/share/doc/audit/:

ls /usr/share/doc/audit/

You will find files such as:

  • stig.rules — DISA STIG compliance rules
  • nispom.rules — NISPOM (National Industrial Security Program) rules
  • pci.rules — PCI-DSS compliance rules
  • nis.rules — NIS rules

To activate a pre-configured rule set:

# Copy the desired ruleset into the rules.d directory
sudo cp /usr/share/doc/audit/stig.rules /etc/audit/rules.d/stig.rules

# Regenerate the active audit.rules file
sudo augenrules --load

# Verify the rules are active
sudo auditctl -l | head -30

Step 6: Making Rules Immutable

For high-security environments, you can lock the audit configuration so it cannot be modified without a reboot. Add this as the last line in your rules file:

# Lock the audit configuration (requires reboot to change rules)
-e 2

Setting -e 2 sets the kernel to enforce mode: any attempt to modify audit rules will be blocked and logged.

Step 7: Searching Audit Logs with ausearch

The ausearch tool queries /var/log/audit/audit.log using structured filters. It is far more efficient than grep for audit data:

# Search by key (tag assigned in -k)
sudo ausearch -k passwd_changes

# Search for events involving a specific user
sudo ausearch -ua root

# Search for login events
sudo ausearch -m USER_LOGIN

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

# Search for events in the last 10 minutes
sudo ausearch --start recent

# Search in a specific time range
sudo ausearch --start "03/15/2024 08:00:00" --end "03/15/2024 17:00:00"

# Combine filters: failed sudo usage by UID 1001
sudo ausearch -k sudoers_changes -ua 1001 -sv no

# Show results in a human-readable interpreted format
sudo ausearch -k passwd_changes -i

Step 8: Generating Compliance Reports with aureport

The aureport tool generates summary reports from audit log data — ideal for periodic security reviews and compliance documentation:

# Summary report of all audit events
sudo aureport

# Report on authentication events
sudo aureport -au

# Report on failed authentication
sudo aureport -au --failed

# Report on all account modifications
sudo aureport -m

# Report on file access events
sudo aureport -f

# Report on executable launches
sudo aureport -x

# Report on logins
sudo aureport -l

# Report on abnormal terminations (crashes, kills)
sudo aureport -a

# Summary of events by user
sudo aureport --summary -i

# Events from the last 24 hours
sudo aureport --start yesterday --end now

Step 9: Verifying Current Active Rules

Check what audit rules are currently loaded in the kernel:

# List all active rules
sudo auditctl -l

# Show audit system status (enabled, buffer size, failure mode)
sudo auditctl -s

Conclusion

The Linux Audit Framework on RHEL 7 provides comprehensive, kernel-level visibility into system activity that is essential for both security operations and regulatory compliance. By combining persistent file watch rules, syscall monitoring, and the pre-built compliance rule sets shipped with the audit package, you can stand up a robust audit trail in minutes. The ausearch and aureport tools then make that data actionable — enabling you to investigate incidents, identify unauthorized access, and produce the evidence required by auditors. Treat your audit log as a critical system asset: protect it, monitor its size, and review its contents regularly.