Monitor VPS Activity with Linux Auditd
The Linux Audit Daemon (auditd) is a kernel-level auditing framework that records every significant event on your server according to rules you define. Whether it's file access, login/logout activity, system calls, or permission changes — auditd captures it all in a tamper-evident audit log. It's ideal for VPS environments requiring compliance (PCI-DSS, HIPAA, SOC 2) or simply wanting to know who did what on the server.
Why Use auditd on a VPS
Tools like fail2ban defend against external attacks, but auditd operates at the kernel level and answers questions like:
- Who logged in and when — and did they succeed?
- Was
/etc/passwdor/etc/shadowopened or modified? - When was
sudoorsuused to gain root? - Which process opened an outbound network connection?
- Were any user accounts created or deleted?
Unlike syslog, where applications decide what to log, auditd works at the kernel level. Once a rule is in place, there is no way for a process to bypass it.
Install auditd
# Ubuntu / Debian
sudo apt update && sudo apt install auditd audispd-plugins -y
# RHEL / Rocky Linux / AlmaLinux / CentOS
sudo dnf install audit audit-libs -y
# Check version
auditctl --version
# Enable and start
sudo systemctl enable auditd --now
# Verify status
sudo systemctl status auditd
Key Files and Directories
| File / Directory | Purpose |
|---|---|
/etc/audit/auditd.conf | Main daemon config — log path, rotation, disk space policy |
/etc/audit/rules.d/ | Rule files directory (persists across reboots) |
/etc/audit/audit.rules | Merged active rules file (auto-generated) |
/var/log/audit/audit.log | Main log file where all events are recorded |
Basic auditd.conf Configuration
sudo nano /etc/audit/auditd.conf
Adjust these key settings:
# Number of log files to keep (rotation)
num_logs = 10
# Max log file size (MB) before rotation
max_log_file = 20
# Action when disk space is low
space_left_action = SYSLOG
admin_space_left_action = SUSPEND
# Action when disk is full
disk_full_action = SUSPEND
disk_error_action = SUSPEND
num_logs = 5 and max_log_file = 10 to prevent audit logs from consuming too much space.Writing Audit Rules
Create a new rule file inside /etc/audit/rules.d/:
sudo nano /etc/audit/rules.d/50-security.rules
Add the following rules:
# Flush existing rules
-D
# Buffer size (increase if backlog occurs)
-b 8192
# Prevent rule changes at runtime (-e 1 = enabled, -e 2 = immutable)
-e 1
## === Identity / Authentication ===
-w /var/log/wtmp -p wa -k logins
-w /var/log/btmp -p wa -k logins
-w /var/log/lastlog -p wa -k logins
-w /var/run/utmp -p wa -k session
# User and group files
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
## === SSH Monitoring ===
-w /etc/ssh/sshd_config -p wa -k ssh_config
-w /root/.ssh/ -p war -k ssh_keys
## === Critical System Calls ===
# Privilege escalation via execve
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -k privilege_escalation
# Permission and ownership changes
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -k permission_change
-a always,exit -F arch=b64 -S chown,fchown,fchownat,lchown -F auid>=1000 -k ownership_change
# Mount events
-a always,exit -F arch=b64 -S mount -F auid>=1000 -k mounts
## === Critical System Files ===
-w /etc/crontab -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
-w /var/spool/cron/ -p wa -k cron
-w /etc/hosts -p wa -k network_config
-w /etc/sysctl.conf -p wa -k kernel_config
-w /sbin/iptables -p x -k firewall
-w /sbin/nft -p x -k firewall
Load the new rules:
# Apply immediately without restart
sudo augenrules --load
# Or restart the service
sudo systemctl restart auditd
# Confirm rules loaded
sudo auditctl -l
Reading and Searching Audit Logs
Use ausearch and aureport to filter and summarize audit events:
# View all today's events
sudo ausearch --start today
# Search by key
sudo ausearch -k identity
sudo ausearch -k sudoers
sudo ausearch -k ssh_keys
# Search by user
sudo ausearch -ua root --start today
# View login failures
sudo ausearch -m USER_AUTH --success no --start today
# Authentication summary report
sudo aureport -au
# All sudo usage
sudo aureport --comm -i | grep sudo
# Human-readable file access report
sudo ausearch -k identity | aureport --file -i
Forwarding Logs via audispd-plugins
By default, audit events only go to /var/log/audit/audit.log. To also forward to syslog or a SIEM:
# Edit the syslog plugin (Ubuntu/Debian)
sudo nano /etc/audisp/plugins.d/syslog.conf
# Change: active = no → active = yes
# Restart auditd
sudo systemctl restart auditd
# Confirm events reach syslog
sudo grep audit /var/log/syslog | tail -20
Verify auditd Is Working Correctly
# Check daemon status
sudo systemctl status auditd
# List loaded rules
sudo auditctl -l
# Show audit subsystem status
sudo auditctl -s
# Test: touch /etc/passwd and check the log
sudo touch /etc/passwd
sudo ausearch -k identity --start recent
# Event count summary for today
sudo aureport --start today --summary
# Check backlog (should be 0 or very low)
sudo auditctl -s | grep backlog
backlog exceeds 1000, increase -b in your rules file to 16384 or higher to prevent event loss under heavy load.Troubleshooting Common Issues
Error: "audit: backlog limit exceeded"
Events are being generated faster than the daemon can process them. The kernel starts dropping events.
# Increase buffer in /etc/audit/rules.d/50-security.rules
-b 16384
# Reload
sudo augenrules --load
# Verify
sudo auditctl -s | grep backlog_limit
Error: "auditd: Cannot open /var/log/audit/audit.log"
The log directory is missing or has incorrect permissions.
sudo mkdir -p /var/log/audit
sudo chmod 700 /var/log/audit
sudo chown root:root /var/log/audit
sudo systemctl restart auditd
Error: "Rule exists" on augenrules --load
Duplicate rules exist across files inside rules.d/.
# List all currently loaded rules
sudo auditctl -l
# Find duplicates across rule files
cat /etc/audit/rules.d/*.rules | sort | uniq -d
Error: "auditd: Unable to set audit daemon PID"
Common on containers or some VPS providers where the kernel does not expose the audit subsystem.
# Check if kernel supports audit
grep -i audit /boot/config-$(uname -r) | head
# Check kernel messages
dmesg | grep audit
Audit Log Filling Up Disk
Tighten the rotation policy in auditd.conf.
# Edit /etc/audit/auditd.conf
max_log_file = 10
num_logs = 5
max_log_file_action = ROTATE
sudo systemctl restart auditd
# Check current usage
du -sh /var/log/audit/
Error: "-F auid!=4294967295" in rule file
The value 4294967295 is -1 as an unsigned integer — it means "unset" UID. Newer kernels accept the alias unset.
# For kernel >= 3.x
-F auid!=unset
# For older kernels use the numeric value
-F auid!=4294967295
Frequently Asked Questions
How is auditd different from syslog?
Syslog records only what applications choose to send. auditd works at the Linux kernel level — every system call matching a rule is recorded automatically, regardless of whether the application logs it. This makes audit logs significantly more trustworthy for security investigations and compliance evidence.
Does auditd slow down the server?
The performance impact is minimal for typical VPS workloads. The main risk is overly broad rules — for example, auditing every execve call without filtering generates enormous volumes of events and can affect performance. Keep rules targeted to the files and calls you actually need to monitor.
How do I send audit logs to a SIEM?
Use audispd-plugins to forward events to syslog, then use Filebeat, Fluentd, or rsyslog to ship them to Elasticsearch, Splunk, Graylog, or your SIEM of choice. Another option is Wazuh, which integrates with auditd natively and provides a ready-made UI for analyzing events.