Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsTraining
StudyProjectsNewsletterHire MeAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Training
Study
Projects
Newsletter
Hire Me
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

2184+ Articles
157+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Checklists
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. AIDE File Integrity Monitoring: Detect Unauthorized Changes on Linux
AIDE File Integrity Monitoring: Detect Unauthorized Changes on Linux
HOWTOIntermediate

AIDE File Integrity Monitoring: Detect Unauthorized Changes on Linux

Deploy AIDE (Advanced Intrusion Detection Environment) to build a cryptographic baseline of your Linux filesystem and automatically alert on unauthorized modifications — a core control for compliance and breach detection.

Dylan H.

Tutorials

August 3, 2026
9 min read

Prerequisites

  • Linux server running Ubuntu 22.04/24.04, Debian 12, or RHEL/Rocky 9
  • Root or sudo access
  • Basic familiarity with the Linux command line
  • Optional — a mail relay or SMTP server for alert emails

Introduction

One of the quietest signs of a breach is a modified system file. An attacker who has gained a foothold will often alter binaries, add cron jobs, plant SSH keys, or tamper with /etc/passwd — all without triggering firewall rules or noisy network events. File Integrity Monitoring (FIM) catches exactly this class of activity.

AIDE (Advanced Intrusion Detection Environment) is a mature, open-source FIM tool that builds a cryptographic database of your filesystem at a known-good point in time. On every subsequent check, it compares the live filesystem against that baseline and reports every change — added files, deleted files, and altered attributes like permissions, ownership, size, and hash values.

This guide walks through installing and configuring AIDE on a Linux server, automating daily integrity checks, sending email alerts on findings, and integrating the output with a central log pipeline. It is directly applicable to CIS Controls v8 (Control 3.14 — Log Sensitive Data Access) and PCI DSS requirement 11.5.


Prerequisites

Before starting, ensure you have:

  • A freshly patched Linux server (Ubuntu 22.04/24.04, Debian 12, or RHEL/Rocky 9)
  • Root or sudo access
  • postfix or sendmail installed if you want email alerts (optional but recommended)
  • Enough disk space for the AIDE database — typically 50–200 MB depending on filesystem size

Tip: Run the initial AIDE database build immediately after a clean OS installation and before installing any applications. This gives you the cleanest possible baseline.


Step 1 — Install AIDE

Ubuntu / Debian

sudo apt update
sudo apt install -y aide aide-common

RHEL / Rocky / AlmaLinux

sudo dnf install -y aide

Verify the installation:

aide --version

The output should show something like Aide 0.18.x or newer.


Step 2 — Review and Customize the Configuration

AIDE's configuration lives at /etc/aide/aide.conf (Debian/Ubuntu) or /etc/aide.conf (RHEL). It defines which directories to monitor and what attributes to check.

Open the config file:

sudo nano /etc/aide/aide.conf

Understanding Rule Groups

AIDE uses named rule groups that combine attribute checks. The default installation ships sensible defaults, but review the key directives:

# Default rule groups (common built-ins)
FIPSR = p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512
CONTENT = sha256+ftype
CONTENT_EX = sha256+ftype+p+u+g+n+acl+selinux+xattrs
DATAONLY = p+n+u+g+s+acl+selinux+xattrs+sha256
  • p = permissions, i = inode, n = number of links
  • u = user, g = group, s = size, m = mtime, c = ctime
  • sha256 / sha512 = cryptographic hash of file content

Key Directories to Monitor

A minimal high-value configuration watches:

# Critical binaries and libraries
/bin    CONTENT_EX
/sbin   CONTENT_EX
/lib    CONTENT_EX
/lib64  CONTENT_EX
/usr/bin  CONTENT_EX
/usr/sbin CONTENT_EX
/usr/lib  CONTENT_EX

# Configuration files
/etc    CONTENT_EX

# Boot files
/boot   CONTENT_EX

# Root home directory
/root   CONTENT_EX

# Exclude frequently-changing directories
!/etc/mtab
!/var/log
!/var/cache
!/tmp
!/proc
!/sys
!/run

Add a Custom Config Drop-In (Recommended)

Rather than editing the main config, create a drop-in file that overrides specific paths:

sudo nano /etc/aide/aide.conf.d/99-local.conf
# Watch cron directories closely
/var/spool/cron   CONTENT_EX
/etc/cron.d       CONTENT_EX
/etc/cron.daily   CONTENT_EX
/etc/cron.hourly  CONTENT_EX
/etc/cron.weekly  CONTENT_EX
/etc/cron.monthly CONTENT_EX

# Monitor SSH authorized keys for all users
/home   CONTENT_EX
!/home/.*/\.cache
!/home/.*/.local/share/Trash

# Exclude AIDE's own database file from checks
!/var/lib/aide

Save and close the file.


Step 3 — Build the Initial Baseline Database

This is the most important step. Run it on a known-good, clean system:

sudo aideinit

On Debian/Ubuntu, aideinit is a wrapper that calls aide --init and then copies the generated database to the active location:

AIDE, version 0.18.x

### AIDE database at /var/lib/aide/aide.db.new initialized.

The new database is written to /var/lib/aide/aide.db.new. Promote it to the active database:

sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Security note: Store an offline copy of this database. If an attacker can modify aide.db itself, they can cover their tracks. Consider copying it to read-only storage or a remote server:

scp /var/lib/aide/aide.db backups@192.168.1.50:/backups/aide/$(hostname)-$(date +%F).db

Step 4 — Run Your First Integrity Check

With the baseline in place, run a manual check:

sudo aide --check

On a freshly initialized system, the output should show no changes:

AIDE, version 0.18.x

### All files match AIDE database. Looks okay!

If you have recently updated packages or changed config files since the aideinit, you may see legitimate changes. Review them and — once confirmed safe — update the baseline (covered in Step 7).


Step 5 — Automate Daily Checks with Cron

Create a daily cron job that runs AIDE and emails the output:

sudo nano /etc/cron.d/aide-check
# Run AIDE integrity check daily at 03:15 and mail results to root
15 3 * * * root /usr/bin/aide --check 2>&1 | /usr/bin/mail -s "AIDE Integrity Check: $(hostname) $(date +%F)" root

If you prefer a dedicated script that filters output and only sends mail when changes are detected:

sudo nano /usr/local/sbin/aide-check.sh
#!/usr/bin/env bash
# AIDE integrity check — only alert on actual findings
set -euo pipefail
 
AIDE_BIN="/usr/bin/aide"
ALERT_EMAIL="security@example.com"
HOSTNAME="$(hostname -f)"
DATE="$(date +%F)"
LOGFILE="/var/log/aide/aide-$(date +%Y%m%d).log"
 
mkdir -p /var/log/aide
 
OUTPUT="$($AIDE_BIN --check 2>&1)"
EXIT_CODE=$?
 
echo "$OUTPUT" >> "$LOGFILE"
 
# AIDE exits 0 if no changes, non-zero if there are changes or errors
if [[ $EXIT_CODE -ne 0 ]]; then
    echo "$OUTPUT" | mail \
        -s "[ALERT] AIDE found changes on $HOSTNAME ($DATE)" \
        -a "From: aide-monitor@$HOSTNAME" \
        "$ALERT_EMAIL"
    echo "[$(date)] Changes detected — alert sent to $ALERT_EMAIL" >> "$LOGFILE"
else
    echo "[$(date)] No changes detected." >> "$LOGFILE"
fi

Make it executable and add the cron entry:

sudo chmod +x /usr/local/sbin/aide-check.sh
sudo nano /etc/cron.d/aide-check
15 3 * * * root /usr/local/sbin/aide-check.sh

Step 6 — Forward AIDE Logs to Syslog / SIEM

To feed AIDE output into a centralized log platform (Graylog, Splunk, Wazuh, Loki), pipe the output through the system logger:

sudo nano /usr/local/sbin/aide-check.sh

Update the script to also log to syslog:

OUTPUT="$($AIDE_BIN --check 2>&1)"
EXIT_CODE=$?
 
# Log a structured summary line to syslog
if [[ $EXIT_CODE -ne 0 ]]; then
    logger -t aide -p security.warning "INTEGRITY_VIOLATION host=$HOSTNAME date=$DATE exit_code=$EXIT_CODE"
else
    logger -t aide -p security.info "INTEGRITY_OK host=$HOSTNAME date=$DATE"
fi

If you are running Wazuh, it has native AIDE integration. Add this to your agent's ossec.conf:

<localfile>
  <log_format>syslog</log_format>
  <location>/var/log/aide/aide-*.log</location>
</localfile>

Wazuh ships built-in rules for AIDE log events (rule IDs 550–552).


Step 7 — Update the Baseline After Legitimate Changes

After system updates or intentional config changes, update the AIDE database to avoid false positives on the next check:

# After an apt upgrade or intentional file changes:
sudo apt upgrade -y
 
# Rebuild the database
sudo aide --update
 
# Promote the new database
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Workflow tip: Always run aide --update after patch maintenance windows, not before. This records the post-patch state as your new clean baseline.


Step 8 — Protect the AIDE Binary and Database

An attacker who can replace aide itself or tamper with aide.db can make changes invisible. Harden the tooling:

Immutable Flags (Linux ext4/xfs)

# Make the AIDE database immutable — must be removed before updates
sudo chattr +i /var/lib/aide/aide.db
 
# Remove before baseline update, then re-apply
sudo chattr -i /var/lib/aide/aide.db
sudo aide --update
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
sudo chattr +i /var/lib/aide/aide.db

Verify the AIDE Binary Hash Manually

sha256sum /usr/bin/aide
# Store this output offline for manual verification

Consider AIDE Over SSH (Remote Execution)

For high-security environments, run AIDE from a trusted jump host over SSH so local root cannot tamper with results:

# From a remote admin host
ssh -i ~/.ssh/admin-key admin@target-server "sudo aide --check" 2>&1 | tee aide-$(date +%F)-remote.log

Verification and Testing

Test That AIDE Detects Changes

Create a test scenario to confirm AIDE is working:

# 1. Create a test file in a monitored path
sudo touch /etc/aide-test-file.txt
 
# 2. Run AIDE check — it should report the new file
sudo aide --check
 
# Expected output includes something like:
# f++++++++++++++++: /etc/aide-test-file.txt
 
# 3. Clean up
sudo rm /etc/aide-test-file.txt
sudo aide --update
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Interpret AIDE Output

The change codes in AIDE output follow this format:

f+++++++++++++++++: /path/to/file   <- new file added
f-----------------: /path/to/file   <- file removed
f...5.....S.......: /path/to/file   <- sha256 changed + size changed

Key change indicators:

SymbolMeaning
fregular file
ddirectory
+attribute added (new)
-attribute removed (deleted)
.no change
ppermissions changed
u / guser / group changed
ssize changed
5SHA-256 hash changed
SSHA-512 hash changed

Troubleshooting

AIDE Takes Too Long to Run

Large filesystems can make AIDE checks slow. Reduce scope by excluding high-churn directories more aggressively:

!/var
!/tmp
!/home/.*/.mozilla
!/home/.*/.config/google-chrome
!/home/.*/.cache

You can also run AIDE in parallel across filesystem mounts, or switch to using aide --compare with separate databases per mount point.

"No such file or directory" for aide.db

The active database has not been initialized or promoted:

sudo aideinit
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Too Many False Positives After Package Updates

Always run aide --update after a package manager upgrade. If false positives persist, identify the noisy paths:

sudo aide --check 2>&1 | grep '^f' | awk '{print $2}' | sort | uniq -c | sort -rn | head -20

Add the top offenders to your exclusion list in /etc/aide/aide.conf.d/99-local.conf.

AIDE Reports Changes in /proc or /sys

These virtual filesystems change constantly. Ensure they are excluded:

!/proc
!/sys
!/run
!/dev

Mail Alerts Not Sending

Confirm mailutils is installed and your MTA is configured:

sudo apt install -y mailutils
echo "Test" | mail -s "AIDE test" your@email.com

Check /var/log/mail.log for delivery errors.


Summary

You now have a working AIDE file integrity monitoring setup that:

  • Builds a cryptographic baseline of your Linux filesystem's known-good state
  • Detects unauthorized file additions, removals, and modifications — including hash changes, permission changes, and ownership changes
  • Runs daily checks automatically via cron and only alerts when genuine changes are found
  • Forwards findings to syslog for SIEM ingestion (Wazuh, Graylog, Loki)
  • Protects the AIDE database from tampering using immutable file attributes

AIDE directly satisfies several compliance requirements: CIS Controls v8 Control 3.14 (log sensitive data access), PCI DSS 11.5 (deploy a change detection mechanism), and NIST 800-53 SI-7 (software, firmware, and information integrity).

The next recommended layer to add is centralizing these logs in a SIEM — check out the Wazuh SIEM/XDR Deployment guide and Linux Auditd Security Monitoring guide for complementary coverage.

#linux#file-integrity#intrusion-detection#compliance#hardening#monitoring

Related Articles

WireGuard VPN: Secure Remote Access for IT Professionals

Deploy a modern, high-performance WireGuard VPN server on Linux for secure remote access. Covers server setup, client configuration, multi-peer management, and firewall rules.

9 min read

Deploy OpenCanary to Catch Attackers Inside Your Network

Set up OpenCanary honeypot services on a Raspberry Pi or VM to detect lateral movement, credential stuffing, and unauthorized access before attackers...

9 min read

Suricata IDS/IPS Deployment: From Install to Active Threat

Deploy Suricata as a full-featured Network Intrusion Detection and Prevention System on Ubuntu. Covers installation, interface capture, Emerging Threats...

10 min read
Back to all HOWTOs