An intrusion that installs a backdoor, replaces a binary or adds a cron job changes files, and the changed files are evidence that outlives the attacker's footprints in the logs. AIDE, the Advanced Intrusion Detection Environment, turns that evidence into an instrument: it builds a cryptographic fingerprint of the filesystem at a trusted moment and then compares reality against the fingerprint on a schedule, reporting every file that was added, removed or altered since the baseline. This article builds the complete setup on a production server: the honest threat model first, a rules file tuned to a real system rather than the stock default, the baseline database and where it must live, reading and acting on check reports, the cron scheduling that turns checks into a rhythm, and the baseline-update procedure that keeps the tool truthful through legitimate change.

What AIDE catches and the model it lives in

AIDE is a host-based integrity checker, a file-system auditor with no realtime component and no self-defense. It detects the aftereffects of compromise: the replaced ls that hides a directory, the added setuid binary, the modified systemd unit that starts a backdoor. It does not prevent anything, it does not watch continuously, and it cannot notice a change that happened and was reverted before a scheduled check, which is the honest boundary of the design and the reason it pairs with, rather than replaces, the auditd rules from earlier in this series.

The model that makes it valuable has two planks. First, the baseline database is a compact cryptographic summary, and if it is stored where the running system cannot write to it, an attacker with root on the box can modify files but cannot make the comparison lie, they can delete the database, which is itself a loud signal, but they cannot forge a clean report against tampered files. Second, the comparison is byte-level and hash-based, so even a change that preserves timestamps and sizes, the classic tricks against naive ls-based checks, still surfaces because the hash differs. The tool's power is exactly the power of a stored, verifiable statement about how the system looked on a day nobody was lying.

The choice of attributes to monitor is the configuration's substance, and the letters map to concrete observations: p tracks permissions, i the inode, u and g the owning user and group, s the size, m and c the modification and change times, and the hash family, sha256 being the current standard choice, the file's content fingerprint. A rule string like p+i+n+u+g+s+m+c+sha256 says that any of those properties changing constitutes a report-worthy change, and the art of configuring AIDE is choosing, per directory, which properties matter.

The rules file for a real server

The stock configuration ships broad and noisy, and the first production hour goes into shaping it. The Debian-family layout puts the file at /etc/aide/aide.conf with the database paths and rules together; the RHEL-family convention is /etc/aide.conf with supporting files under /etc/aide/aide.conf.d/. The shape of a tuned file, minus the standard header of database paths, looks like this:

High-value, rarely-changing trees /etc/ p+i+u+g+s+m+c+sha256 /boot/ p+i+u+g+s+m+c+sha256 /usr/bin/ p+i+u+g+s+m+c+sha256 /usr/sbin/ p+i+u+g+s+m+c+sha256 /usr/local/bin/ p+i+u+g+s+m+c+sha256

Directories with churn, size-only watch /var/log/ p+u+g+s

Explicit exclusions !/var/log/audit/ !/var/lib/

The philosophy is a three-way split. The system's executable and configuration trees get the full rule, because a change there is either an administrator or an attacker, and both deserve to be visible in the morning report. The high-churn directories get a reduced rule, size and ownership only, or are excluded entirely, because log files grow every minute and a full hash on gigabytes of log noise drowns the signal and stretches the check into an hour. And the exclusion list is written as an explicit statement of what the site accepts as unverifiable, which is the difference between a tuned configuration and a lazy one: every ! line is a documented decision, visible to the next administrator and to any auditor who reads the file.

The recurring tuning pass after the first weeks of reports is part of the setup rather than a chore: each report that contains only noise from a directory, mail spool growth, package cache churn, earns that directory a reduced rule or an exclusion, and each rule that catches a genuine change earns a comment. The file converges within a month or two into a configuration whose reports are almost always signal, which is the property that determines whether anyone reads them.

Building the baseline and storing it honestly

The baseline database is created in one command, run on a system that is trusted at that moment:

aide --init

which walks every rule, hashes what the rules demand, and writes the database to the configured new-database path, /var/lib/aide/aide.db.new on Debian-family. The file then becomes the working baseline under its final name, and the Debian packaging wraps the whole ceremony into aideinit, which initializes, moves and sets permissions in one go:

aideinit -y -f

The moment the database exists is the moment its custody becomes the design question. On the same filesystem as the files it describes, an attacker with root can replace both the files and the database, so the production pattern stores a copy off-box: a read-only location, another server's readonly export, an object store, write-once media, and the check procedure compares against a copy fetched from that custody rather than trusting the local file unconditionally. The local database stays for convenience, the remote copy stays for truth, and the runbook names both paths so the distinction survives staff turnover.

The database should also be stored read-only at the filesystem level where the platform allows it, and the rebuild after a legitimate large change is the scheduled moment to refresh the custody copy. The theme from the threat-model section repeats here deliberately: AIDE's integrity is the integrity of its baseline, and the custody of a small binary file is a much easier property to secure than the integrity of an entire filesystem.

Running checks and reading the report

The verification pass is one command against the live filesystem:

aide --check

and the output falls into three sections that read like a grammar of system change. Added files list every path that exists now and did not at baseline, and each entry deserves the question of which installation or update created it. Removed files name the deletions, rarer on a stable server and correspondingly louder. Changed files, the heart of the report, list each with the attributes that differ, a permissions line, a size delta, a hash mismatch, and the specific deltas tell the story: a hash change with the same size is the replaced-binary pattern, a permissions-only change is usually an administrator, and an ownership change on a setuid binary is a page-the-on-call event.

The two-run discipline turns the report into an actionable artifact: the first run identifies the candidates, and a second run minutes later, after nothing was done, confirms stability, a report that grows between two runs with no administrative action in between is a live system under active change and escalates from audit to incident immediately. The comparison tool for benign-looking changes is the package manager, rpm -Va on RHEL-family or debsums on Debian-family, which verifies installed package files against their recorded checksums and answers whether the changed file belongs to a package and whether the package itself validates. A file that the package manager also flags, on a system where updates were not in progress, is the finding that AIDE exists to surface.

Scheduling with cron and handling the noise

The Debian package ships a daily run out of the box, /etc/cron.daily/aide, mailing the report to root and any configured address through the MAILTO directive in the configuration. On distributions without the wrapper, the cron entry is three lines of shell in /etc/cron.d/aide:

0 4 * root /usr/sbin/aide --check | /usr/bin/mail -s "AIDE report $HOSTNAME" Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.

running at four in the morning, when the report lands in an inbox with the whole working day ahead of it. The choice of frequency is a policy statement: daily catches intrusions within a day, weekly trades detection latency for less mail on systems with large trees, and the right answer for most servers is daily with the tuned rules from earlier, because a tuned report is a page long and readable, while an untuned daily report trains its readers to delete it unread within a fortnight, the failure mode of every integrity tool ever deployed.

The monitoring integration belongs in the same section because the email-only pattern decays the moment the mailbox does. The check exits nonzero when changes are found, which turns it into a monitoring probe: the scheduled script captures the exit code, reports zero on clean and the change count on dirty, and the monitoring system alerts on any nonzero the way it alerts on any other threshold. The alert text carries the summary line from the report, added, removed, changed counts, so the on-call sees the shape of the finding before opening the full artifact.

Updating the baseline after legitimate change

Every package update changes files, and the baseline-update procedure is the discipline that keeps the tool honest without silencing it. After a change window, an update, a deployment, the sequence is: run the check and read the report, confirm that every entry maps to the deliberate change, then rebuild:

aide --update

which writes a new database incorporating the current state, replacing the old baseline after the same verification-then-move ceremony as the original. The anti-pattern that the procedure exists to prevent is the reflexive update on any noisy report, because an update accepts every change in it, and an attacker's file modification hidden among fifty legitimate package updates sails through the reflexive rebuild. The rule worth printing in the runbook: the baseline is updated on a schedule the team controls, after a report has been read, never as a reflex to make a report quiet.

For fleet operators, the update procedure also defines the release cadence: weekly patch windows end with a check, a read and an update on every host, and the discipline is identical at every scale, one article of procedure, applied with the same rigor whether the fleet is two machines or two hundred.

The response plan and the working checklist

The check that finds something real is the moment the tool hands over to procedure, and the response plan written in advance turns that moment from improvisation into execution. The short version: preserve evidence first, copy the report and the changed files off-box, snapshot where the platform allows. Verify against the package manager. Check the auditd trail from the earlier article for the access that made the change. From there the path forks on the verdict, a package inconsistency that matches a known update closes the ticket, and an unexplained modification to a binary escalates as an incident with the host treated as untrusted, because on a compromised machine the only clean rebuild is a rebuild.

The checklist that closes the article mirrors the working order. Install, tune the rules against a week of real reports, build the baseline, and place its copy in custody. Schedule the check through cron or the packaging's daily entry, wire the exit code into monitoring, and read the first ten reports personally, because the tuning that makes them short is the work of those first two weeks. Update the baseline only after read reports, on the controlled cadence. Store the procedure, the evidence copy and the escalation fork in the runbook, and rehearse the response once a year on a test box. The result is a server whose morning report is short, whose baseline lives where an attacker cannot reach it, and whose files cannot change, legitimately or otherwise, without someone seeing the change named in print the next morning.