Ai
Security Azure

AIDE on Ubuntu 24.04 LTS on Azure

| Product: AIDE on Ubuntu 24.04 LTS by cloudimg

This image ships AIDE (Advanced Intrusion Detection Environment) on Ubuntu 24.04 LTS, ready to detect tampering from the first boot of every deployed virtual machine. AIDE is installed unmodified from Ubuntu's own archive, so it stays patchable through the normal apt path for the life of the release.

AIDE is an open source host based file and directory integrity checker. It builds a cryptographic baseline database of the files it is told to watch, recording their permissions, ownership, size, timestamps and content hashes, and on every later run it compares the live filesystem against that baseline and reports exactly what has been added, removed or changed.

What this appliance does and does not do

Read this section before you deploy. It is the difference between an appliance that does what you think it does and one that quietly does not.

What AIDE is good at. AIDE answers one question with authority: has anything on this machine been tampered with. It detects a backdoored system binary, an altered configuration file, an unexpected new file dropped into a system directory, or a change to the boot files. It is a foundational control for security hardening and a direct answer to compliance regimes that mandate file integrity monitoring, including PCI DSS requirement 11.5 and the CIS Benchmarks.

What AIDE is not. AIDE is a local, on demand integrity checker. This image does not include, and AIDE itself is not:

  • a real time monitor: it checks when it runs, on a schedule, not continuously as files change,
  • an antivirus or malware scanner: it detects change, not maliciousness, so it does not know a signature from a backdoor, only that a watched file is now different,
  • a central console, a SIEM or an agent that reports to a server,
  • a web interface of any kind.

AIDE tells you that something changed. Deciding whether a given change is expected (a package update you ran) or hostile (a file you never touched) is your judgement, and this guide shows you the workflow for exactly that.

What makes this image different

The baseline is built per machine, on first boot, not baked in. An integrity baseline is a fingerprint of one specific machine. A baseline captured at image build time would describe the build machine, so every deployed instance would report thousands of false changes on its very first check and would leak the build machine's state. Instead, no baseline ships. Every virtual machine deployed from this image builds a fresh baseline of its own real filesystem on first boot, so the very first check you run is meaningful.

The image fails closed. The scheduled check will not run against a missing or incomplete baseline. Two independent safeguards enforce that on every run, not merely the first, so an instance that has not finished first boot cannot present an integrity check that silently checks nothing.

A scheduled check is already wired, and exactly one of them. A systemd timer runs a daily integrity check against the appliance configuration and logs its findings, so you get continuous coverage without configuring anything. The Ubuntu package's own daily check (dailyaidecheck.timer, its service and its cron job) is disabled and masked, so two checks never run against two different configurations and the machine stays in the healthy running state after every check. Reporting changes is the tool working as designed, not a fault, and the workflow for reviewing and accepting expected changes is in section 8.

There is no login and no password. AIDE has no user database, no network service and no credential of any kind. There is nothing here to rotate and nothing to leak. Administration is over SSH with your own key.

1. Deploy the virtual machine

Deploy the image from the Azure Marketplace. The defaults in this guide assume:

  • Size: Standard_B2s (2 vCPU, 4 GB) is sufficient and is what this image is validated on. AIDE is a lightweight command line tool; size up only if you extend the monitored scope to very large data directories.
  • Inbound ports: SSH (22) only. AIDE opens no network port of its own. The local mail transport the AIDE package pulls in (Postfix, for local report mail) listens on the loopback interface only, so SSH is the only port the machine listens on.
  • Authentication: your own SSH public key.

2. Connect to the virtual machine

ssh azureuser@<vm-ip>

On first boot the machine builds its per machine baseline database before the scheduled check is armed. That takes under a minute on a new machine. If you connect immediately and the baseline is not ready yet, that is first boot still working, and section 10 shows how to watch it.

3. Confirm AIDE is installed and the baseline is built

aide --version | head -1
sudo test -s /var/lib/aide/aide.db && echo "per-VM baseline present" || echo "baseline NOT yet built"
systemctl is-active aide-firstboot.service
sudo test -f /var/lib/cloudimg/aide-firstboot.done && echo "firstboot sentinel present"

You should see the AIDE version, a baseline database that is present, and a first boot service that is active. The baseline at /var/lib/aide/aide.db was built on this machine at first boot.

AIDE version, the per-VM baseline database and the completed first boot service on Ubuntu 24.04

4. See what is being monitored

The appliance ships a focused, hardened configuration that watches the paths that matter for tamper detection: executables, shared libraries, the boot files and the system configuration under /etc. High churn and self referential paths are deliberately excluded so the check does not drown in noise.

grep -vE '^\s*#|^\s*$' /etc/aide/aide.conf | sed -n '1,40p'

The appliance AIDE configuration showing the monitored system paths

The FULL rule records permissions, inode, link count, owner, group, size, block count, modification and change times, and a SHA-256 content hash for every watched file. That is what lets AIDE tell a genuine content change from a harmless timestamp touch.

5. Run an integrity check now

You can run a check by hand at any time. Right after first boot the report is short: it can list the few files first boot finishes after it has built the baseline (the mail identity in /etc/mailname, /etc/postfix/main.cf and /etc/aliases.db) and any file the Azure agent rewrote while the machine was provisioning. Review them and accept them with the baseline update in section 8, after which a check on an unchanged machine is clean.

sudo aide --check --config=/etc/aide/aide.conf > /tmp/aide-check.out 2>&1; echo "aide --check exit code: $?"
sed -n '1,12p' /tmp/aide-check.out

AIDE's exit code encodes what it found: 0 means no changes, and a non-zero code is a bitmask of the change classes it detected (added, removed, changed). A non-zero exit is not an error, it is a finding. Only review the report to decide whether the change was expected.

6. Prove it actually detects a change

Do not take "the check ran" as proof that detection works. Prove it. This plants a harmless marker file in a monitored directory, runs a check, confirms AIDE reports the new file, and then removes the marker so your baseline is clean again.

sudo touch /usr/local/sbin/aide-demo-intruder
sudo aide --check --config=/etc/aide/aide.conf > /tmp/aide-demo.out 2>&1; echo "exit code: $? (non-zero = change detected)"
grep -A1 -i 'added\|aide-demo-intruder' /tmp/aide-demo.out | head -8
sudo rm -f /usr/local/sbin/aide-demo-intruder
echo "marker removed; baseline is clean again"

You should see the check exit non-zero and the report name /usr/local/sbin/aide-demo-intruder as an added entry. That is the whole product in four lines: a file appeared in a watched directory and AIDE caught it.

AIDE detecting a planted file in a monitored directory, naming it as an added entry

7. The scheduled check

A systemd timer runs the same integrity check daily and appends its report to /var/log/aide/aide.log, so you have continuous coverage with nothing to configure.

systemctl is-active aidecheck.timer
systemctl list-timers aidecheck.timer --no-pager | sed -n '1,3p'
echo "reports are appended to /var/log/aide/aide.log"

It is the only scheduled AIDE check on the machine. The Ubuntu package also ships its own daily check (dailyaidecheck.timer), which runs as a separate _aide user against the package's default configuration rather than the appliance configuration. This image disables and masks it, so it can neither double the work nor fail on the shared report log and leave the machine degraded:

for u in dailyaidecheck.timer dailyaidecheck.service; do echo "$u: $(systemctl is-enabled "$u" 2>/dev/null)"; done
echo "system state: $(systemctl is-system-running)"

Both packaged units report masked, and the system state is running.

The daily AIDE integrity check timer and its next scheduled run

To run the scheduled check immediately rather than waiting for the timer, and then read the tail of its log:

sudo systemctl start aidecheck.service
sudo tail -n 15 /var/log/aide/aide.log
echo "system state after the check: $(systemctl is-system-running)"

The log ends with a check complete line, and the system state stays running.

8. Review reports and update the baseline

Here is the workflow that turns AIDE from a noisy tool into a useful one. When a check reports changes, you decide whether each change was expected. If you ran a package update or edited a configuration file yourself, the changes are expected and you accept them by rebuilding the baseline so future checks are quiet again. If you did not make the change, you have a genuine integrity event to investigate.

After you have reviewed a report and confirmed the changes are legitimate, rebuild the baseline:

# Rebuild the per-VM baseline to accept reviewed, expected changes.
# (aideinit builds a new database and moves it into place.)
sudo aideinit --yes --force
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db 2>/dev/null || true

The golden rule: only update the baseline after you have reviewed the changes and confirmed they are yours. Updating it blindly defeats the entire purpose, because it accepts whatever an attacker did along with whatever you did.

9. Monitor additional paths

The shipped configuration covers the system paths that matter most. To also watch an application directory, add a rule to a drop-in and rebuild the baseline. This example watches /opt/myapp:

# Append a monitor rule for your own directory, then rebuild the baseline.
echo '/opt/myapp FULL' | sudo tee -a /etc/aide/aide.conf
sudo aideinit --yes --force
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Keep the scope purposeful: watch code and configuration, not high churn data directories, log directories or caches, which would fill every report with expected noise and hide the change that matters.

10. First boot and troubleshooting

The per machine baseline is built by aide-firstboot.service on first boot. To watch or re-run it:

systemctl is-enabled aide-firstboot.service
systemctl status aide-firstboot.service --no-pager | sed -n '1,8p' || true

The unit is a one shot: once it has built the baseline it stays inactive (dead), which is the healthy resting state — is-enabled returning enabled is what confirms it is wired in.

If the baseline was not built (for example the machine lost power mid first boot), re-run it:

# Re-run the first-boot baseline build if it did not complete.
sudo systemctl restart aide-firstboot.service

The scheduled check refuses to run until a valid baseline exists, so a machine that has not finished first boot will never present an integrity check that silently checks nothing.

11. What else this image changes

  • SSH: root login, empty passwords and X11 forwarding are switched off in /etc/ssh/sshd_config.d/00-cloudimg.conf. Password sign-in stays whatever you chose when you deployed the machine.
  • The root account is locked with no password hash, and /root is readable by root only.
  • Per machine values: the SSH host keys, the machine id, the AIDE baseline, the mail identity and the local mail TLS key pair are all created on this machine at first boot, never copied from the image.
  • fwupd-refresh.timer is masked: Azure virtual machines have no firmware that the Linux Vendor Firmware Service can update, so it only added a failing outbound call.
  • Security updates install automatically through unattended-upgrades, and the image was fully patched when it was captured.

12. Licensing

AIDE is licensed under the GNU General Public License, version 2. It is installed unmodified from Ubuntu's public apt archive, so it remains patchable through the normal unattended-upgrades path for the life of the release. The complete corresponding source for the exact binaries installed is available from that same archive with apt-get source aide, and a written offer for the source is shipped on the image at /usr/share/doc/cloudimg/AIDE-GPL-2-WRITTEN-OFFER.txt.

Unlike a signature based scanner, AIDE ships no third party detection content: the only data it uses is the baseline it builds from your own machine, so there is no external database to license or redistribute.

Support

Every cloudimg deployment is backed by 24/7 support. If you have any questions about this image, contact us at support@cloudimg.co.uk.