## Auditd + Laurel: Host-Based Detection Done Right ### What They Are **Auditd** is the Linux Audit Framework—a kernel-level system that logs security-relevant events: file access, system calls, process execution, user authentication, privilege changes. It's been in the kernel since 2.6 and is rock solid. **Laurel** is a plugin that transforms auditd's notoriously awkward multi-line log format into clean, structured JSON—perfect for shipping to Loki. ### Why This Combination Works Auditd alone has two problems: 1. The log format is painful (events split across multiple lines, encoded arguments) 2. High-volume logging can impact performance if not tuned Laurel solves the first problem elegantly. Proper rule tuning solves the second. ### Installation ```bash # Auditd (likely already installed) sudo apt install auditd audispd-plugins # Laurel - grab the latest release wget https://github.com/threathunters-io/laurel/releases/latest/download/laurel-x86_64-musl sudo mv laurel-x86_64-musl /usr/local/sbin/laurel sudo chmod 755 /usr/local/sbin/laurel # Create laurel user and directories sudo useradd -r -s /usr/sbin/nologin laurel sudo mkdir -p /var/log/laurel /etc/laurel sudo chown laurel:laurel /var/log/laurel ``` ### Configuration **/etc/laurel/config.toml:** ```toml [auditlog] # Output JSON logs here - point Promtail/Loki agent at this file = "/var/log/laurel/audit.json" size = 100000000 # 100MB rotation generations = 5 [transform] # Enrich with useful context execve-argv = "array" execve-env = "delete" # Don't log environment (secrets risk) [filter] # Drop noisy low-value events filter-keys = ["exclude-noise"] ``` **/etc/audit/plugins.d/laurel.conf:** ```ini active = yes direction = out path = /usr/local/sbin/laurel type = always args = --config /etc/laurel/config.toml format = string ``` ### High-Value Audit Rules Here's a starter set focused on actual intrusion indicators—not compliance checkbox noise: **/etc/audit/rules.d/intrusion-detection.rules:** ```bash # Clear existing rules -D # Buffer size (tune based on your load) -b 8192 # Failed file access (credential hunting) -a always,exit -F arch=b64 -S open,openat -F exit=-EACCES -F key=access-denied -a always,exit -F arch=b64 -S open,openat -F exit=-EPERM -F key=access-denied # Credential file access -w /etc/passwd -p wa -k credential-files -w /etc/shadow -p wa -k credential-files -w /etc/gshadow -p wa -k credential-files -w /etc/sudoers -p wa -k credential-files -w /etc/sudoers.d -p wa -k credential-files # SSH key access -w /root/.ssh -p wa -k ssh-keys -w /home -p wa -k ssh-keys # Privilege escalation -a always,exit -F arch=b64 -S setuid,setgid,setreuid,setregid -F key=priv-escalation -w /usr/bin/sudo -p x -k priv-escalation -w /usr/bin/su -p x -k priv-escalation # Process injection / debugging -a always,exit -F arch=b64 -S ptrace -F key=process-injection # Suspicious process execution -a always,exit -F arch=b64 -S execve -F euid=0 -F key=root-exec -w /tmp -p x -k exec-from-tmp -w /var/tmp -p x -k exec-from-tmp -w /dev/shm -p x -k exec-from-shm # Network connections from unexpected processes -a always,exit -F arch=b64 -S connect -F key=network-connect # Kernel module loading -a always,exit -F arch=b64 -S init_module,finit_module -F key=kernel-modules # Audit log tampering (high priority) -w /var/log/audit -p wa -k audit-tampering -w /etc/audit -p wa -k audit-tampering # Cron/scheduled task modification -w /etc/crontab -p wa -k persistence -w /etc/cron.d -p wa -k persistence -w /var/spool/cron -p wa -k persistence # Systemd service creation (persistence mechanism) -w /etc/systemd/system -p wa -k persistence -w /usr/lib/systemd/system -p wa -k persistence # Make config immutable (remove -e 2 while tuning) # -e 2 ``` Load the rules: ```bash sudo augenrules --load sudo systemctl restart auditd ``` ### Shipping to Loki **Promtail config snippet:** ```yaml scrape_configs: - job_name: laurel static_configs: - targets: - localhost labels: job: auditd host: your-hostname __path__: /var/log/laurel/audit.json pipeline_stages: - json: expressions: event_type: SYSCALL.SYSCALL key: SYSCALL.key exe: SYSCALL.exe uid: SYSCALL.UID success: SYSCALL.success - labels: event_type: key: ``` ### Grafana Alerting Examples Once in Loki, create alerts for the high-value events: ```logql # Credential file tampering {job="auditd"} |= `credential-files` | json | success = "yes" # Execution from /tmp (classic attack pattern) {job="auditd"} |= `exec-from-tmp` | json # Root execution by non-root user (priv esc) {job="auditd"} |= `priv-escalation` | json # Kernel module loading (rootkit indicator) {job="auditd"} |= `kernel-modules` | json # Audit log tampering (covering tracks) {job="auditd"} |= `audit-tampering` | json ``` ### Performance Tuning If ye see performance impact: 1. **Add exclusions** for known-noisy processes: ```bash -a never,exit -F exe=/usr/bin/prometheus -F key=exclude-noise ``` 2. **Reduce network logging** — the `connect` syscall is high-volume; consider removing or filtering 3. **Increase buffer** if you see `audit: backlog limit exceeded` ### What You'll Catch With this setup, you'll detect: - Credential harvesting attempts - Privilege escalation (successful and attempted) - Persistence mechanisms (cron, systemd services) - Execution from world-writable directories - Process injection/debugging - Rootkit installation attempts - Evidence tampering All with structured JSON flowing into your existing Loki/Grafana stack. No Suricata noise, just host-level events that actually matter. Want me to help tune rules for specific services you're running, or set up the Grafana alert rules?