If you only scan for CVEs and ignore file integrity, you can still miss real compromises.
A vulnerable package is a risk. A modified binary in /usr/bin is an event.
This guide gives you a practical AIDE-based file integrity monitoring setup you can run on a real Linux host, with:
- a clear baseline workflow
- daily automated checks via
systemdtimer - auditable reports in
journald - a safe process for accepting legitimate changes
What AIDE does (and does not do)
AIDE (Advanced Intrusion Detection Environment) stores a cryptographic snapshot of selected files and later compares current state against that snapshot.
It is great for answering:
- “Did this sensitive file change?”
- “Were permissions/ownership altered?”
- “Did an executable hash drift unexpectedly?”
It does not replace:
- vulnerability management
- EDR
- central log detection
Think of AIDE as a high-signal integrity tripwire for critical paths.
1) Install AIDE and create an initial baseline
Debian / Ubuntu
sudo apt update
sudo apt install -y aide
RHEL / Fedora
sudo dnf install -y aide
Initialize the baseline database (command path can differ by distro):
# Common upstream style
sudo aide --init
# If your distro stores output as aide.db.new*:
sudo ls -l /var/lib/aide
Promote the generated database to active (adjust filenames to match your distro):
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# or for gzip variants:
# sudo cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
Run your first check:
sudo aide --check
If baseline and filesystem are aligned, you should see no unexpected drift.
2) Tune scope to reduce noise and increase signal
The exact config location is distro-dependent (/etc/aide.conf or includes under /etc/aide/).
Start by monitoring high-value paths:
-
/bin,/sbin,/usr/bin,/usr/sbin /etc- boot-related files
- package manager metadata
Avoid high-churn paths in strict rules unless required:
/var/log- temp/cache/runtime directories
- container writable layers
Example rule snippets (adapt to your distro syntax):
# Example concept only — verify against your distro's shipped aide.conf macros
/usr/bin NORMAL
/usr/sbin NORMAL
/etc NORMAL
!/var/log/.*
!/var/tmp/.*
!/tmp/.*
After config changes, re-initialize and promote a fresh trusted baseline.
3) Automate daily checks with a dedicated systemd unit
Even if your distro ships cron integration, explicit systemd units are easier to audit and standardize.
Create /etc/systemd/system/aide-check.service:
[Unit]
Description=AIDE integrity check
Documentation=man:aide(1)
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/aide --check
# Keep output in journald for auditability
StandardOutput=journal
StandardError=journal
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
Create /etc/systemd/system/aide-check.timer:
[Unit]
Description=Daily AIDE integrity check timer
[Timer]
OnCalendar=*-*-* 03:15:00
Persistent=true
RandomizedDelaySec=15m
[Install]
WantedBy=timers.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now aide-check.timer
sudo systemctl list-timers --all | grep aide-check
Why these options matter:
-
Persistent=true: missed runs execute after boot -
RandomizedDelaySec: avoids synchronized spikes across many hosts
4) Add a practical alert path
For a single host, journald + optional mail is enough.
Create /usr/local/sbin/aide-check-wrapper.sh:
#!/usr/bin/env bash
set -euo pipefail
OUTFILE="/var/log/aide-check-$(date +%F).log"
if /usr/bin/aide --check >"$OUTFILE" 2>&1; then
logger -t aide-check "AIDE check OK"
exit 0
else
logger -p authpriv.warning -t aide-check "AIDE detected changes; report: $OUTFILE"
# Optional: mail/report hook here
exit 1
fi
sudo install -m 0750 -o root -g root /usr/local/sbin/aide-check-wrapper.sh /usr/local/sbin/aide-check-wrapper.sh
Then switch the service to:
ExecStart=/usr/local/sbin/aide-check-wrapper.sh
Now alerts are visible via:
journalctl -t aide-check --since "24 hours ago"
5) Safe baseline update workflow (critical)
Never auto-accept AIDE changes. Use a change-control flow:
-
Detect drift (
aide --checkfails) -
Triage:
- Was this from a known patch/deploy?
- Do package manager logs match?
- Are changed files expected for that maintenance window?
- Approve change only if legitimate
- Rebuild baseline
- Promote new baseline
- Record why (ticket, commit, maintenance note)
Example post-patch update:
# after verified legitimate updates
sudo aide --init
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
sudo aide --check
If drift is suspicious, do incident response first; do not refresh baseline.
6) Validation checklist (copy/paste)
# timer is active
systemctl is-active aide-check.timer
# next trigger visible
systemctl list-timers aide-check.timer
# service logs are present
journalctl -u aide-check.service -n 50 --no-pager
# manual integrity run works
sudo aide --check
Final notes
AIDE is old-school in the best way: deterministic, auditable, and easy to reason about.
If you already run backups, patching, and vulnerability scans, this adds one missing layer: proof that critical files stayed the way you intended.
That layer is often the difference between “we think we’re fine” and “we can prove what changed, when, and where.”
Sources and references
- AIDE project homepage: https://aide.github.io/
- AIDE manual: https://aide.github.io/doc/
-
systemd.timer(5)manual (OnCalendar,Persistent,RandomizedDelaySec): https://www.freedesktop.org/software/systemd/man/systemd.timer.html -
systemd.path(5)manual (path-trigger semantics): https://www.freedesktop.org/software/systemd/man/systemd.path.html - Red Hat Security Hardening — Checking integrity with AIDE: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/security_hardening/checking-integrity-with-aide_security-hardening
Top comments (0)