Skip to content

Module 11 — Host & Boot Integrity

Type 4 · Audit→Build→Verify — build an AIDE file-integrity baseline, plant three realistic tampers (modified binary, new SUID-root file, rogue cron job), and prove AIDE flags every one with the right change attributes, then harden the baseline database itself and map what FIM catches versus what only measured boot, Secure Boot, and FDE cover. (Secondary: Detonate & Detect — the planted tampers are the detonation the integrity control must catch.) Go to the hands-on lab →

Last reviewed: 2026-06

Endpoint & Host Hardeninghardening makes the host expensive to attack; integrity tells you when something changed anyway — from a planted binary on disk all the way down to the boot chain.

Difficulty: Intermediate  ·  Estimated time: ~4–6 hrs (study + lab)  ·  Prerequisites: Foundations

In 60 seconds

Every other control in this track raises the cost of getting in; integrity answers the question an incident responder asks first — has this host changed from how we shipped it? This module builds an AIDE file-integrity baseline, plants three realistic tampers, and proves AIDE flags each one — then hardens the control itself, because an attacker who can rewrite the baseline defeats it silently. Finally it maps what file integrity catches versus what only measured boot, Secure Boot, and full-disk encryption cover in the boot chain that runs before any file checker exists.

Why this matters

Every other module in this track raises the cost of getting in — a CIS baseline, an AppArmor profile, a patched kernel, an allowlist. None of them answers the question an incident responder asks first: has this host been changed from how we shipped it? When an attacker lands a persistence mechanism — a trojaned sshd, a new SUID-root binary, a cron job that re-establishes a foothold — the hardening you applied last week says nothing about it, because hardening is a state you set and integrity is a change you detect. This is the missing pillar: the controls that establish a known-good and prove, on demand, whether the live host still matches it. It is the host-level counterpart to the detection work in Modules 05 and 10 — telemetry watches events, integrity watches state — and it is the first thing a forensic timeline leans on when "we think the box was touched in March" needs to become "these eleven files changed on March 14th."

Objective

Build an AIDE baseline of a watched filesystem, confirm a clean check reports no changes, then plant three realistic tampers — modify a watched binary, drop a new SUID-root file, and add a cron job — and prove AIDE flags every one with the right change attributes. Then harden the control itself: reason about why the baseline database is the real target, move it out of the attacker's reach, and re-baseline cleanly. Finally, map what file-integrity catches versus what it can't — and where measured boot, Secure Boot, and full-disk encryption pick up the boot chain that runs before any file checker exists.

The core idea

The mental model

Integrity is one question asked on a loop: has this changed from known-good? Fingerprint a set of files into a baseline, recompute and diff on every check. Hardening is a state you set; integrity is a change you detect — the host-level counterpart to telemetry, which watches events while integrity watches state.

Integrity monitoring is one question asked repeatedly: "has this changed from known-good?" The mechanism is almost embarrassingly simple — walk a set of files, record an attribute fingerprint for each (a content hash plus permissions, owner, size, inode, mtime/ctime), store that as a baseline database, and on every later check recompute the fingerprints and diff them against the baseline. AIDE (Advanced Intrusion Detection Environment) is the canonical open-source implementation, and the whole craft is in what you fingerprint and which attributes you compare. Watch /bin, /sbin, /usr, /etc, the cron directories, and the SUID/SGID set with strong hashes and you'll catch a swapped binary or a planted backdoor; watch /var/log or /tmp with the same strictness and you'll drown in false positives because those are supposed to change. The baseline-and-compare model is only as good as a config that knows the difference between "this file is immutable, alarm on any change" and "this directory churns, only watch its permissions."

The gotcha

An attacker who can rewrite the baseline defeats FIM silently — tamper the binary, re-run aide --init, and the next check is clean. A burglar alarm whose off-switch is in the room it guards is no alarm. The real control isn't "do we run AIDE," it's baseline integrity: the database (and ideally the binary and config) must live where a compromised host can't write it.

The gotcha that turns this from a checkbox into a real control is that an attacker who can rewrite the baseline defeats the whole thing silently. If the AIDE database sits on the same disk the attacker just rooted, they tamper the binary and re-run aide --init (or just overwrite aide.db), and the next check is clean — you've built a burglar alarm whose off-switch is in the room it's guarding. So the security boundary isn't "do we run AIDE," it's baseline integrity: the database (and ideally the AIDE binary and config) must live somewhere the monitored host can't write to in the course of being compromised — read-only media, a separate hardened host that pulls and checks, or at minimum an off-box copy whose hash you verify before trusting a check. This is the same lesson as Module 17's "the key policy is the real off-switch" one layer down: the comparison is trivial; protecting the thing you compare against is the job. A FIM result you can't trust the baseline of is theater.

File integrity stops where the running OS stops, though, and that's the boundary worth holding clearly. AIDE can only fingerprint files once a filesystem is mounted and a userspace process is running — it is blind to everything that executes before that: the firmware, the bootloader, the kernel and initramfs. Defending that earlier chain is a different set of tools that you should be able to place precisely. Secure Boot is prevention — UEFI firmware verifies a cryptographic signature on each component it loads (bootloader, then kernel) against keys in its signature database, and refuses to run anything unsigned or tampered; it stops an evil bootloader from launching at all. Measured boot is detection — each stage hashes the next and extends that measurement into a TPM Platform Configuration Register (PCR), a write-only-by-extension register, building a tamper-evident log of exactly what ran; nothing is blocked, but a later attestation can compare the PCR values against known-good and prove whether the boot chain was modified. And full-disk encryption (LUKS/cryptsetup on Linux) is confidentiality at rest — it doesn't detect tampering, it makes the data unreadable to someone who steals the disk or boots it elsewhere, and the practitioner move is to seal the LUKS key to a TPM PCR state so the volume only unlocks if the measured boot chain is the expected one. Prevent, detect, protect — three different jobs on the same chain.

The synthesis a practitioner carries is a layered "known-good" stack: Secure Boot gates what runs before the OS, measured boot/TPM attests that the pre-OS chain was untouched, FDE protects the data while powered off, and AIDE watches the files once the system is live. Each layer covers a window the others can't see, and each has the same Achilles' heel — the reference it compares against (the signature DB, the expected PCR values, the AIDE baseline) is the actual asset. Get the reference right and protected, and you can answer "was this host tampered with?" from the silicon up. Lose control of the reference and every green checkmark above it is meaningless.

flowchart LR
    FW["UEFI firmware"] --> BL["Bootloader"] --> K["Kernel + initramfs"] --> OS["Running OS<br/>(files mounted)"]
    SB["Secure Boot<br/>— <b>prevent</b>: verify signature"] -.-> BL
    SB -.-> K
    MB["Measured boot → TPM PCRs<br/>— <b>detect</b>: attest the chain"] -.-> BL
    MB -.-> K
    FDE["FDE / LUKS<br/>— <b>protect at rest</b>"] -.-> OS
    AIDE["AIDE baseline<br/>— <b>detect</b>: file integrity"] -.-> OS
Go deeper: three boot-chain jobs, not one

File integrity is blind before the OS mounts, and the pre-OS chain has three distinct jobs you should be able to place precisely. Secure Boot is prevention — UEFI verifies a signature on each component and refuses unsigned/tampered ones. Measured boot is detection — each stage hashes the next into a TPM PCR, building a tamper-evident log you can later attest against known-good. Full-disk encryption (LUKS) is confidentiality at rest — it doesn't detect tampering, it makes a stolen disk unreadable; seal the LUKS key to a PCR state and the volume only unlocks if the measured chain is the expected one, tying FDE to boot integrity.

AI caveat

A model drafts an AIDE config fluently and triages a 200-line diff into "expected vs suspicious" well — real leverage. But the excludes are a security decision it gets subtly wrong (it will silence a directory that also holds things you must watch), and it cannot tell you whether your baseline is trustworthy — it reads the report without ever questioning whether the database was itself tampered. That judgment, and protecting the baseline off-box, is yours.

Learn (~3.5 hrs)

File-integrity monitoring with AIDE (~1.5 hrs) - AIDE — official manual — the authoritative reference; read the configuration, rules/groups, and database sections. This is the syntax the lab's aide.conf is written in — the attribute groups (p+i+n+u+g+s+sha256+…) and the selection lines are exactly what you'll tune to separate "immutable, alarm on any change" from "churns, ignore." - ArchWiki — AIDE — a concise, practical walkthrough of install → write aide.confaide --initaide --check → update the database, plus the real-world note on where to keep the database. Read this once before make up so the lab's init/check loop is familiar.

Boot integrity — Secure Boot & measured boot (~1.5 hrs) - Debian Wiki — SecureBoot — a clear, distro-grounded explanation of how UEFI Secure Boot verifies signatures on the bootloader and kernel, what the shim/MOK machinery does, and how to check Secure Boot state on a running system. Read "How UEFI Secure Boot works" and the verification section — skip the deep signing-your-own-kernel howto unless you do the VM stretch. - Opensource.com — What measured boot and trusted boot means for Linux — a short (~10-min) essay that nails the distinction the core idea draws: measured boot records into the TPM PCRs and lets you attest later, trusted boot also checks against expected values inline. The cleanest mental model for "what does the TPM actually buy me at boot."

Disk encryption at rest (~0.5 hr) - cryptsetup(8) — Linux manual page — the LUKS reference; read the LUKS extension overview and the luksFormat / luksOpen / luksAddKey actions to understand the header-plus-keyslots model (multiple revocable passphrases protected by PBKDF). This is what the optional VM stretch uses; for the container lab it's context for "FDE protects at rest, it doesn't detect tampering."

Key concepts

  • Integrity = "has this changed from known-good?" — fingerprint files into a baseline, recompute and diff on every check.
  • Config is the craft: watch immutable paths (/bin, /sbin, /etc, SUID set, cron) strictly; relax or exclude churn (/var/log, /tmp) or you drown in false positives.
  • Baseline integrity is the real control — an attacker who can rewrite the AIDE database defeats FIM silently; the database/binary/config must live where a compromised host can't write to it (read-only media, off-box, hash-verified).
  • Three different boot-chain jobs: Secure Boot prevents (signature-verifies each component), measured boot/TPM PCRs detect (tamper-evident log you can attest), FDE/LUKS protects at rest (confidentiality, not detection).
  • Seal the LUKS key to a TPM PCR state so the disk only unlocks if the measured boot chain is the expected one — that ties FDE to boot integrity.
  • File integrity is blind before the OS mounts; the boot-chain controls cover that window. Every layer's weak point is the reference it compares against.

AI acceleration

A model is a fast, fluent author of an AIDE config — hand it your watch list and it will draft the selection lines and attribute groups, suggest sensible excludes for /var and /proc, and explain a cryptic change report. Use it for that, and to triage an AIDE diff: paste a 200-line check output and ask it to group the changes into "expected (package update)" versus "suspicious (new SUID, modified /etc/passwd, unexpected cron)." Where you own the judgment is twofold. First, the excludes are a security decision the model will get subtly wrong — ask it to silence the noise and it will happily exclude a directory that also contains things you must watch (it doesn't know that /etc/cron.d matters and /etc/mtab doesn't in your environment), the file-integrity equivalent of an over-broad firewall rule. Second, and non-negotiable, the model cannot tell you whether your baseline is trustworthy — it will validate the config and read the report without ever questioning whether the database it's comparing against was itself tampered. That's the actual control, and it's yours: AI drafts the config and explains the diff; you decide what's watched, protect the baseline off-box, and prove the planted tamper is caught the way the lab does.

Check yourself

  • Why is baseline integrity — not "do we run AIDE" — the real security boundary for file-integrity monitoring?
  • Place Secure Boot, measured boot, and FDE on the prevent/detect/protect spectrum, and say which window each covers.
  • Why is asking a model to "silence the noise" in an AIDE config a security decision you can't fully delegate?

Comments

Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).