Skip to content
LinuxHow-To Published Updated 5 min readViews unavailable

How to Set Up Security Monitoring on Linux with auditd

Configuring the Linux audit daemon to watch specific files, commands, and syscalls, then actually query the resulting logs for something useful.

auditd is the userspace component of the Linux kernel’s audit subsystem — logging security-relevant events (file access, syscalls, command execution) at a level of detail well beyond ordinary system logs, and a natural complement to SELinux enforcement.

Step 1: install and start auditd

sudo dnf install audit    # RHEL/Fedora
sudo apt install auditd   # Debian/Ubuntu
sudo systemctl enable --now auditd

Step 2: watch a specific sensitive file for changes

sudo auditctl -w /etc/passwd -p wa -k passwd_changes

-p wa watches for write and attribute-change events; -k tags matching log entries with a searchable key, making them easy to filter out from everything else auditd logs.

Step 3: watch a specific syscall system-wide

sudo auditctl -a always,exit -F arch=b64 -S execve -k exec_tracking

This logs every execve (program execution) system call — useful for building a record of what actually ran on the system, not just what was configured to run.

Step 4: make rules persistent across reboots

# /etc/audit/rules.d/audit.rules
-w /etc/passwd -p wa -k passwd_changes
-a always,exit -F arch=b64 -S execve -k exec_tracking
sudo augenrules --load

Rules set with auditctl directly are cleared on reboot — persisting them means adding them to the rules.d configuration and reloading.

Step 5: query logs by the key you assigned

sudo ausearch -k passwd_changes
sudo ausearch -k exec_tracking -ts today

Tagging rules with -k at creation time is what makes this kind of targeted, readable querying possible later — untagged rules still log, but require much more manual log-parsing to filter.

Step 6: generate a summary report

sudo aureport --summary
sudo aureport -x --summary

aureport produces human-readable summaries (failed logins, executable usage, file access patterns) rather than requiring you to read raw audit records directly.

Step 7: watch for a specific user’s activity

sudo auditctl -a always,exit -F arch=b64 -F uid=1001 -S execve -k user_1001_exec

Step 8: check current active rules

sudo auditctl -l

Why tagging rules with -k is worth doing from the very first rule you write

An untagged audit log grows into an enormous, undifferentiated stream very quickly on any active system — the -k key is what turns that stream back into something queryable by intent (“show me passwd_changes,” not “show me everything and let me grep for it”). Establishing this habit from the first rule, rather than retrofitting it later, is what actually makes auditd’s output usable during a real incident investigation instead of just theoretically comprehensive.

Step 9: watch privilege escalation specifically

sudo auditctl -w /etc/sudoers -p wa -k sudoers_changes
sudo auditctl -a always,exit -F arch=b64 -S execve -F path=/usr/bin/sudo -k sudo_usage

Beyond watching for the sudoers file being edited, logging every actual invocation of sudo itself (rather than only changes to its configuration) gives a record of who escalated privileges and when — combined with ausearch -k sudo_usage, this produces exactly the kind of “who did what, as root, and when” trail that’s often the first thing requested during a security incident review, and one that’s much harder to reconstruct after the fact from ordinary shell history alone, since shell history is trivially editable by the very user being audited.

Step 10: make the audit configuration itself tamper-resistant

# as the LAST line in /etc/audit/rules.d/audit.rules
-e 2

-e 2 puts the audit system into immutable mode — once set, no further rule changes (additions, deletions, or clearing) are possible until the next reboot, and even root cannot alter the running configuration without restarting the machine, which is itself a loud, logged event. This closes a real gap: without it, an attacker who gains root can simply delete or weaken the audit rules covering their own activity, erasing the trail as they go. Immutable mode trades operational flexibility (a rule change now requires a reboot, not a live auditctl call) for the guarantee that whatever rules were loaded at boot stay in force for the rest of that boot’s lifetime — a tradeoff worth making deliberately for any system where audit integrity matters more than being able to tweak rules without a restart.

Step 11: watch for rule and audit-config manipulation itself

sudo auditctl -w /etc/audit/rules.d/ -p wa -k audit_config_changes
sudo auditctl -w /etc/audit/auditd.conf -p wa -k audit_config_changes

Even short of full immutable mode, explicitly watching auditd’s own configuration files for changes means any attempt to weaken auditing is itself captured in the log it’s trying to escape — a form of self-monitoring that catches exactly the kind of tampering an attacker with root access would otherwise be able to perform invisibly.

Step 12: keep the log itself from silently filling the disk

# /etc/audit/auditd.conf
max_log_file = 50
max_log_file_action = rotate
num_logs = 10
space_left_action = email
admin_space_left_action = suspend

A high-volume rule set (broad execve tracking especially) can generate a genuinely large audit log fast enough to matter — max_log_file and num_logs bound total disk usage through rotation, while space_left_action/admin_space_left_action define what happens as free space actually runs low, up to and including suspending auditing entirely rather than letting it fill the disk and take down every other service competing for that same space. Leaving these at overly generous or unbounded defaults on a busy system is a common, avoidable way “turn on more logging” quietly becomes “ran out of disk space,” which is a far worse outcome than the audit gap a sensible rotation policy briefly risks instead.

Related:

Sources:

Comments