Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

auditd: Linux Audit Logging

By Kokil Thapa | Last reviewed: September 2026

auditd: Linux Audit Logging answers a question application logs rarely cover: who touched a file, which process escalated privileges, and when a config change happened on disk. On production Ubuntu servers I maintain for Linux system administration clients, auditd sits below PHP-FPM and Apache. It watches syscalls the kernel already handles. That depth makes it the right tool when you need tamper evidence after a breach, not just error traces. This guide walks through install, rules, log reading, and forwarding—without the noise that fills a default install.

What is auditd and how does Linux audit logging work?

Linux audit logging is built into the kernel. The audit subsystem hooks syscalls before they complete. When a rule matches, the kernel writes a structured record. The auditd daemon reads those records from a netlink socket and persists them to disk.

Application logs tell you what your code decided. Audit logs tell you what the operating system actually did. That gap matters on shared hosting boxes, legal-tech portals with document uploads, and any server where a compromised account might edit .env or cron files outside your app.

auditd: Linux Audit Logging FlowUser Processopen, exec, setuidKernel Auditrule match + recordauditddaemon persists/var/log/audit/audit.log rotatedRemote SIEMaudisp-remote pluginForensics: ausearch, aureport, ausearch -iWho changed /etc/passwd? Which UID ran sudo?
How auditd: Linux Audit Logging captures kernel events and routes them to local files or a remote collector.

The main components are straightforward. auditd is the userspace daemon. auditctl loads rules at runtime. Files under /etc/audit/rules.d/ make rules survive reboots. Tools like ausearch and aureport query the binary-ish log format humans hate reading raw.

Audit records are append-only by design. Root can stop the daemon or fill the disk, but a well-configured setup with log rotation and disk quotas raises the bar for silent tampering. Pair auditd with strict file permissions on /etc/audit/ and your log directory.

Key fields in an audit record

Each line in audit.log is a single event. Common keys include type (event class), msg=audit(timestamp:id), pid, uid, auid (login UID), ses, and comm (command name). File watches add name and cwd.

The login UID (auid) is especially useful. It tracks which user session started a process chain, even after sudo or su. On a legal-tech portal where staff upload affidavits, knowing the original login behind a root shell matters.

How do you install and enable auditd on Ubuntu?

On Ubuntu 22.04 and 24.04 LTS, install the audit package and enable the service. The daemon name is auditd; systemd unit is auditd.service.

sudo apt update
sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd
sudo systemctl status auditd

Confirm the kernel has audit enabled:

grep audit /boot/config-$(uname -r)
# CONFIG_AUDIT=y expected

If you run inside Docker or a stripped custom kernel, audit may be disabled. Containers often lack the full audit trail you get on bare metal or a VM. For production Laravel hosts I manage, auditd runs on the host OS, not inside the app container.

Backlog settings matter under load. A busy web server can generate thousands of events if rules are too broad. Tune before you go live:

# /etc/audit/auditd.conf (excerpt)
log_file = /var/log/audit/audit.log
max_log_file = 50
num_logs = 5
max_log_file_action = ROTATE
space_left = 100
space_left_action = SYSLOG
admin_space_left_action = SUSPEND

SUSPEND stops new audit records when disk space runs out. That protects the root filesystem but creates a blind spot. Monitor free space on /var the same way you watch MySQL data directories. See Linux server monitoring with Netdata and alerts for a practical pattern.

How do you write audit rules with auditctl and audit.rules?

Rules tell the kernel what to record. You can add them live with auditctl or persist them under /etc/audit/rules.d/. On boot, augenrules merges those files into /etc/audit/audit.rules.

Start with immutable rules last—once set, they cannot change until reboot. That is a security feature, not a footgun, if you test first.

Audit Rule MatchingSyscall EntryFilter Match?Record Event-w path watchperm, key=mykey-a always,exitsyscall filters-F fielduid, pid, archUse distinct keys (-k) for each rule groupausearch -k sshd_config tracks one concern fast
Syscall filters and file watches in auditd: Linux Audit Logging—always tag rules with a searchable key.

File watches for config and credential paths

Watch critical paths on a typical LAMP or Laravel stack:

# /etc/audit/rules.d/50-app-hardening.rules
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k priv_esc
-w /etc/sudoers.d/ -p wa -k priv_esc
-w /etc/ssh/sshd_config -p wa -k sshd_config
-w /var/www/myapp/.env -p wa -k app_secrets
-w /etc/cron.d/ -p wa -k cron_change
-w /etc/cron.daily/ -p wa -k cron_change

Permission flags: r read, w write, x execute, a attribute change. wa catches writes and metadata changes—what you usually want for config files.

Syscall rules for privilege changes and execution

Track setuid/setgid and execve for selected binaries:

-a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k setuid_root
-a always,exit -F arch=b64 -S setuid,setgid,setreuid,setregid -k priv_change

Load and persist:

sudo augenrules --load
sudo auditctl -l

Test on a staging box first. A rule that logs every execve on a busy PHP-FPM host will crush I/O. Narrow with -F exe=/usr/bin/sudo or path filters when you can.

Make rules immutable after validation

-e 2

Place -e 2 at the end of your rules file. It locks audit configuration until reboot. I enable this only after a full test cycle on servers under support and maintenance contracts where change control is strict.

How do you search and interpret audit logs?

Raw audit.log lines are dense. Use the audit tools instead of grep alone—though regex patterns still help when you pipe output.

Common queries:

# Failed logins today
sudo aureport --failed --summary

# Events tied to a rule key
sudo ausearch -k sshd_config -i

# Activity by login UID
sudo ausearch -au 1000 --start today -i

# File watch events on identity files
sudo ausearch -k identity -i

The -i flag translates numeric IDs to names. That alone saves minutes during an incident.

aureport produces summaries: logins, executions, anomalies, events by key. Run a weekly cron job that emails a summary to ops. It catches slow burns—repeated sudo failures, odd midnight file edits—that never trigger application alerts.

Correlate with journald and application logs

Audit timestamps use epoch seconds in the msg=audit(...) field. Match them against journald and rsyslog entries for the same window. On a compromised box, the attacker may clear app logs but miss audit files if permissions and remote forwarding were set up correctly.

For a client portal like Mijar Law Associates, I would correlate audit records on document directories with Laravel's own access logs. Neither source alone tells the full story.

How does auditd compare to rsyslog and journald for security?

All three belong on a production server. They solve different problems. Treating auditd as a replacement for application logging is a common mistake.

Capabilityauditd (kernel audit)journaldrsyslog
Data sourceSyscalls, file watches, MAC (AppArmor/SELinux)stdout, systemd units, kernel printkAny program that writes syslog
Tamper resistanceStrong when immutable rules + remote shipModerate; root can truncate journalDepends on remote forwarding
File access detailPath, UID, AUID, syscallOnly if app logs itOnly if app logs it
Volume riskHigh if rules too broadMedium with default settingsMedium; filter in config
Best useCompliance, forensics, insider threatService debugging, boot issuesCentral aggregation, legacy apps
Three Logging Layersauditdkernel security eventsjournaldunit and service outputrsyslognetwork and app syslogCentral ELK / Loki / Splunksee structured logging best practicesDo not disable auditd because journald existsThey overlap minimally at the security layer
auditd, journald, and rsyslog stack together—centralize via ELK or similar, not by picking one tool.

Official documentation from the auditd man page and Red Hat's system auditing guide describe the same split. Kernel audit is the only layer that sees unauthorized reads of /etc/shadow even when no daemon logged an error.

For structured application logs, follow structured logging best practices in your Laravel or WordPress code. Ship those logs separately. Use auditd for the OS boundary.

How do you forward audit logs to a central SIEM?

Local logs die with the disk. Remote forwarding is how you preserve evidence when an attacker gains root. The audispd-plugins package provides plugins under /etc/audisp/plugins.d/.

Enable audisp-remote for syslog or SIEM

# /etc/audisp/plugins.d/au-remote.conf
active = yes
direction = out
path = /sbin/audisp-remote
type = always
format = string
# /etc/audisp/audisp-remote.conf
remote_server = siem.example.com
port = 601
transport = tcp
queue_file = /var/spool/audit/remote.log
queue_size = 1000

Restart the audit stack:

sudo systemctl restart auditd

Many teams also ship /var/log/audit/audit.log through Filebeat into Elasticsearch. Parse with the auditd module. Either path beats keeping logs only on a single EC2 instance.

Production auditd TopologyWeb 01auditd + rulesWeb 02auditd + rulesDB HostMySQL 9.7SIEM / ELKlong-term retentionImmutable rules (-e 2) on each nodeFirewall allow 601/tcpnftables or iptables90-day retention mincompliance baseline
Typical multi-server auditd: Linux Audit Logging setup with remote aggregation and locked local rules.

Sister sites on my shared Deployer pipeline—legal portals and translation services—share one SIEM bucket. Standardized rule files under version control keep drift low. The same Git repo that holds deploy.php can hold audit/rules.d/ snippets.

Harden the audit pipeline itself

  1. Restrict read access: chmod 600 /var/log/audit/audit.log and root-owned /etc/audit/.
  2. Forward off-box before local rotation deletes evidence you still need.
  3. Alert on auditd stop events via systemd unit monitoring.
  4. Log auditctl -D attempts if rules are not yet immutable during rollout.
  5. Document which keys map to which compliance control—PCI, ISO, or internal policy.

Combine with network controls from iptables vs nftables so only your collector reaches the remote port. Audit logs contain hostnames, paths, and usernames—treat them as sensitive data.

Performance tuning on busy Laravel hosts

PHP-FPM generates heavy file I/O. Watching entire /var/www trees is usually wrong. Watch secrets and deploy hooks instead:

  • .env, storage/ keys, and custom deploy.php release paths
  • /etc/php/ version switches after upgrades
  • Composer and artisan invocations via sudo (if your deploy user uses it)

I've seen audit backlogs drop events when backlog_limit is too low. Check for audit: backlog limit exceeded in dmesg or journal. Raise limits in rules:

-b 8192

Balance against RAM. On a 2 GB VPS common for small Nepal business sites (Rs 1,500–2,500/month, ~USD 11–19), start with 4096 and adjust after a load test.

Integration with user and backup workflows

When staff accounts change, audit user and group management paths: /etc/passwd, visudo, SSH keys under /home/*/.ssh/. Backup jobs should not trigger thousands of false positives—exclude read-only backup tool binaries if needed with careful syscall filters.

Database dumps belong in your automated backup audit story too. Watch the cron file that runs mysqldump, not every read of the dump directory.

For performance baselines after enabling auditd, compare I/O wait via Linux performance tuning basics before and after rule rollout. A few milliseconds of extra latency beats flying blind during an incident.

Key Takeaways

  • Install auditd on production Linux hosts and define focused rules under /etc/audit/rules.d/—not catch-all watches.
  • Tag every rule with a -k key so ausearch -k answers incident questions in seconds.
  • Ship logs remotely; local-only audit data disappears with the compromised server.
  • Use -e 2 immutable mode only after staging tests confirm rule volume is acceptable.
  • Layer auditd with journald, rsyslog, and app logs—each covers a different blind spot.
  • Monitor disk space and backlog drops; noisy rules hurt performance more than auditd itself.

People Also Ask

Does auditd work in Docker containers?

Partially. The container shares the host kernel, but default Docker setups do not expose full audit control inside the container namespace. Serious compliance workloads run auditd on the host and correlate container IDs from journald or your orchestrator. Do not assume in-container audit equals host-level coverage.

What is the difference between auid and uid in audit logs?

uid is the effective user at event time. auid (audit login UID) is the user who originally logged in to the session. After sudo, uid may be 0 while auid still shows the staff account—exactly what you need for accountability.

Can auditd log failed login attempts?

Yes. PAM and sshd emit audit events on authentication failures. Use aureport --failed or ausearch -m USER_LOGIN -sv no depending on your distro's PAM audit integration. Pair with fail2ban for prevention; auditd gives you the forensic record.

How long should you retain audit logs?

Retention depends on policy, not technology. Many teams keep 90–365 days online and archive to cold storage longer. Legal and financial clients often specify minimum windows—define that before sizing disk and SIEM indices. The Ubuntu wiki on Security/Audit links to community rule sets you can adapt.

Ship auditd before you need the logs

auditd: Linux Audit Logging is cheap insurance on any Linux server that holds client data, payment hooks, or SSH access. Install it on the next maintenance window, start with a dozen high-value watches, forward logs off-host, and rehearse one ausearch query so your team knows the workflow. If you want help hardening Ubuntu servers, audit rules in Git, or tying OS logs into your existing monitoring stack, see Linux system administration in Nepal or testing and optimization services—or contact us to review your current setup.

Frequently Asked Questions

auditd is the userspace daemon for Linux kernel audit logging. The kernel hooks syscalls before they complete; when a rule matches, it writes a structured record. auditd reads those records from a netlink socket and persists them to disk, typically /var/log/audit/audit.log. Unlike application logs that show what your code decided, audit logs show what the operating system actually did—file access, user ID changes, failed logins. That depth makes auditd the right tool when you need tamper evidence after a breach, not just error traces from PHP-FPM or Apache.

On Ubuntu 22.04 and 24.04 LTS, install the audit package and enable the service. Run sudo apt update, then sudo apt install auditd audispd-plugins. Enable and start with sudo systemctl enable --now auditd, then confirm with sudo systemctl status auditd. Verify the kernel has audit enabled by checking grep audit /boot/config-$(uname -r) for CONFIG_AUDIT=y. If you run inside Docker or a stripped custom kernel, audit may be disabled. For production Laravel hosts, run auditd on the host OS, not inside the app container.

auditd stores logs in /var/log/audit/audit.log by default, configured in /etc/audit/auditd.conf. Records are append-only by design—root can stop the daemon or fill the disk, but a well-configured setup with log rotation and disk quotas raises the bar for silent tampering. Typical rotation settings include max_log_file = 50, num_logs = 5, and max_log_file_action = ROTATE. Restrict read access with chmod 600 on the log file and keep /etc/audit/ root-owned. Forward logs off-box before local rotation deletes evidence you still need for forensics.

uid is the effective user at event time. auid (audit login UID) is the user who originally logged in to the session. After sudo, uid may be 0 while auid still shows the staff account.

Rules tell the kernel what to record. Add them live with auditctl or persist them under /etc/audit/rules.d/—on boot, augenrules merges those files into /etc/audit/audit.rules. File watches use -w with permission flags: r read, w write, x execute, a attribute change; wa catches writes and metadata changes. Syscall rules track setuid, setgid, and execve events. Always tag rules with a searchable -k key. Load with sudo augenrules --load and list with sudo auditctl -l. Test on staging first—a rule logging every execve on a busy PHP-FPM host will crush I/O.

Watch critical paths, not entire trees. On a typical stack, monitor /etc/passwd, /etc/shadow, /etc/group with key identity; /etc/sudoers and /etc/sudoers.d/ with key priv_esc; /etc/ssh/sshd_config with key sshd_config; your app .env with key app_secrets; and /etc/cron.d/ and /etc/cron.daily/ with key cron_change. On busy Laravel hosts, watching entire /var/www trees is usually wrong—watch secrets and deploy hooks instead: .env, storage/ keys, custom deploy.php release paths, and /etc/php/ version switches after upgrades. Narrow syscall rules with -F exe=/usr/bin/sudo when possible.

Raw audit.log lines are dense—use audit tools instead of grep alone. Common queries: sudo aureport --failed --summary for failed logins today; sudo ausearch -k sshd_config -i for events tied to a rule key; sudo ausearch -au 1000 --start today -i for activity by login UID; sudo ausearch -k identity -i for file watch events on identity files. The -i flag translates numeric IDs to names, saving minutes during an incident. aureport produces summaries: logins, executions, anomalies, events by key. Run a weekly cron job that emails a summary to ops to catch slow burns like repeated sudo failures or odd midnight file edits.

All three belong on a production server—they solve different problems. auditd captures kernel syscalls, file watches, and MAC events with strong tamper resistance when immutable rules and remote shipping are configured. journald handles stdout, systemd units, and kernel printk with moderate tamper resistance since root can truncate the journal. rsyslog aggregates any program writing syslog with tamper resistance depending on remote forwarding. Only kernel audit sees unauthorized reads of /etc/shadow even when no daemon logged an error. Stack them together and centralize via ELK or similar—do not pick one tool as a replacement for the others.

Partially. Containers share the host kernel, but default Docker setups do not expose full audit control inside the container namespace. Serious compliance workloads run auditd on the host and correlate container IDs from journald or your orchestrator.

Local logs die with the disk—remote forwarding preserves evidence when an attacker gains root. The audispd-plugins package provides plugins under /etc/audit/plugins.d/. Enable audisp-remote by setting active = yes in /etc/audisp/plugins.d/au-remote.conf and configuring remote_server, port, transport, queue_file, and queue_size in /etc/audisp/audisp-remote.conf. Restart with sudo systemctl restart auditd. Many teams also ship /var/log/audit/audit.log through Filebeat into Elasticsearch using the auditd module. Standardize rule files under version control in the same Git repo that holds deploy.php to keep drift low across multi-server setups.

Placing -e 2 at the end of your rules file locks audit configuration until reboot—rules cannot change without a reboot. This is a security feature, not a footgun, if you test first. Root can otherwise stop the daemon or modify rules; immutable mode raises the bar for silent tampering during an active breach. Enable it only after a full test cycle on staging confirms rule volume is acceptable. On servers under strict change control, immutable rules combined with remote log forwarding make it much harder for an attacker to cover tracks by altering audit configuration mid-incident.

PHP-FPM generates heavy file I/O, and overly broad rules hurt more than auditd itself. Watching entire /var/www trees is usually wrong. Noisy rules can generate thousands of events and crush I/O; check dmesg or journal for audit: backlog limit exceeded when backlog_limit is too low. Raise limits with -b 8192 in rules, balanced against RAM. On a 2 GB VPS common for small Nepal business sites, start with 4096 and adjust after a load test. Tune /etc/audit/auditd.conf backlog settings before going live. A few milliseconds of extra latency beats flying blind during an incident.

Yes. PAM and sshd emit audit events on authentication failures. Use sudo aureport --failed --summary or sudo ausearch -m USER_LOGIN -sv no depending on your distro PAM audit integration. Pair with fail2ban for prevention—auditd gives you the forensic record that prevention tools alone cannot. During an incident, correlate audit timestamps from the msg=audit(...) field against journald and rsyslog entries for the same window. On a compromised box, attackers may clear application logs but miss audit files if permissions and remote forwarding were configured correctly before the breach.

Retention depends on policy, not technology. Many teams keep 90–365 days online and archive to cold storage longer. Legal and financial clients often specify minimum windows—define that before sizing disk and SIEM indices. Local rotation with num_logs = 5 and max_log_file = 50 MB files handles short-term storage, but forward off-box for longer retention. Audit logs contain hostnames, paths, and usernames—treat them as sensitive data in your SIEM bucket. Document which rule keys map to which compliance control—PCI, ISO, or internal policy—so retention aligns with audit requirements.

auditd itself is free—install via apt on Ubuntu with no licensing fee. The main cost is disk space, SIEM storage, and the VPS hosting the daemon.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: