AIDE
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, so you know exactly what the appliance does and what it does not do.
What AIDE is good at. AIDE answers one question: has anything on this machine been tampered with? It detects a backdoored system binary, an altered configuration file, an unexpected new file in 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: it cannot tell 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 change is expected (a package update you ran) or hostile (a file you never touched) is your judgement. Section 8 shows 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. Every deployed instance would then report thousands of false changes on its first check and would leak the build machine's state.
So no baseline ships. Every virtual machine deployed from this image builds a fresh baseline of its own filesystem on first boot, and the 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 this on every run, not only the first. An instance that has not finished first boot therefore cannot present an integrity check that silently checks nothing.
Exactly one scheduled check is already wired. 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. Two checks therefore 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. Section 8 describes how to review and accept expected changes.
There is no login and no password. AIDE has no user database, no network service and no credential of any kind. There is nothing to rotate and nothing to leak. You administer the machine over SSH with your own key.
1. Deploy the virtual machine
Deploy the image from the Azure Marketplace. This guide assumes the following defaults:
- Size:
Standard_B2s(2 vCPU, 4 GB) is sufficient and is what this image is validated on. AIDE is a lightweight command-line tool, so 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 AIDE package pulls in a local mail transport (Postfix, for local report mail) that 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
Connect over SSH:
ssh azureuser@<vm-ip>On first boot the machine builds its per-machine baseline database before the scheduled check is armed. This takes under a minute on a new machine. If you connect immediately and the baseline is not ready yet, first boot is still running. Section 10 shows how to watch it.
3. Confirm AIDE is installed and the baseline is built
Run these checks to confirm the AIDE version, the baseline database and the first-boot service:
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/sac/data/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.
4. See what is being monitored
The appliance ships a focused, hardened configuration. It 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.
Print the active configuration:
grep -vE '^\s*#|^\s*$' /etc/aide/aide.conf | sed -n '1,40p'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
Run a check by hand at any time. Right after first boot the report is short. It can list the few files that 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 those files and accept them with the baseline update in section 8. After that, 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.outAIDE's exit code encodes what it found. 0 means no changes. 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. Review the report to decide whether the change was expected.
6. Prove it actually detects a change
A check that ran is not proof that detection works, so test it. The commands below plant a harmless marker file in a monitored directory, run a check and confirm that AIDE reports the new file. They then remove 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"The check exits non-zero, and the report names /usr/local/sbin/aide-demo-intruder as an added entry. A file appeared in a watched directory and AIDE caught it.
7. The scheduled check
A systemd timer runs the same integrity check daily and appends its report to /var/log/aide/aide.log. You get 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"This is the only scheduled AIDE check on the machine. The Ubuntu package also ships its own daily check (dailyaidecheck.timer). That check 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. Verify the state:
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.
To run the scheduled check immediately instead of 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
This workflow turns AIDE from a noisy tool into a useful one. When a check reports changes, decide whether each change was expected.
If you ran a package update or edited a configuration file yourself, the changes are expected. 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 || trueUpdate the baseline only after you have reviewed the changes and confirmed they are yours. Updating it blindly defeats the 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 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.dbKeep the scope purposeful. Watch code and configuration, not high-churn data directories, log directories or caches. Those would fill every report with expected noise and hide the change that matters.
10. First boot and troubleshooting
aide-firstboot.service builds the per-machine baseline on first boot. To inspect it:
systemctl is-enabled aide-firstboot.service
systemctl status aide-firstboot.service --no-pager | sed -n '1,8p' || trueThe 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 confirms that it is wired in.
If the baseline was not built, for example because the machine lost power during first boot, re-run the unit:
# Re-run the first-boot baseline build if it did not complete.
sudo systemctl restart aide-firstboot.serviceThe scheduled check refuses to run until a valid baseline exists. A machine that has not finished first boot therefore never presents 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-sac.conf. Password sign-in stays as you configured it when you deployed the machine. - Root account: it is locked with no password hash, and
/rootis 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.
- Firmware refresh:
fwupd-refresh.timeris masked. Azure virtual machines have no firmware that the Linux Vendor Firmware Service can update, so the timer only added a failing outbound call. - Updates: 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. A written offer for the source is shipped on the image at /usr/share/doc/sac/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 SecureAnyCloud deployment is backed by 24/7 support. If you have any questions about this image, contact us at sales@secureanycloud.com.
Deploy on Azure
Launch AIDE on Ubuntu 24.04 LTS by SecureAnyCloud with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
AIDE (Advanced Intrusion Detection Environment) is an open-source, GPL-2.0 licensed, host-based file and directory integrity checker. It builds a cryptographic baseline database of the attributes of the files it watches (permissions, ownership, inode, size, timestamps and content hashes). On every later run it reports exactly what has been added, removed or changed against that baseline.
This SecureAnyCloud image runs AIDE on AWS as a headless command-line appliance. You drive the aide command over SSH using your own key. AIDE is a purely local tool: it opens no network socket and runs no daemon. AIDE is a host intrusion detection staple and a direct answer to compliance controls that mandate file-integrity monitoring, such as PCI-DSS requirement 11.5 and the CIS Benchmarks.
What you get:
- A baseline database that is never baked into the AMI. An AIDE baseline fingerprints one specific machine's filesystem, and a baseline computed on the build server would describe the wrong machine. The first check on your instance would then report thousands of spurious differences. Instead, the baseline is generated on your instance at first boot.
- A systemd timer that runs a daily integrity check and writes the report to
/var/log/aide/aide.log - A fail-closed check that refuses to run unless a valid per-instance baseline is present
- No web interface, no service to log into and no credentials
Prerequisites
To deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Connecting to Your Instance
This listing may offer more than one operating system variant. Connect over SSH on port 22 as the default login user for the variant you launched.
OS variant: Ubuntu 24.04 LTS | SSH login user: ubuntu
Use your EC2 key pair, for example:
ssh -i /path/to/your-key.pem ubuntu@<vm-ip>Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for AIDE. Select the SecureAnyCloud listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or another size that suits your workload. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet. Then create or select a security group that opens port 22 from your management network. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialization, during which AIDE builds the per-instance baseline database, takes a minute or two after the instance state becomes Running and the status checks pass.
Launch the Instance from the AWS CLI
Run the command below to launch an instance from the SecureAnyCloud AIDE Marketplace AMI into an existing subnet and security group. Replace these values first:
- <ami-id> with the AMI ID shown on the Marketplace listing
- <key-name> with your EC2 key pair name
- <subnet-id> with your subnet ID
- <security-group-id> with a security group that opens port 22 from your management network
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=aide}]'Confirm AIDE and the Per-Instance Baseline
Connect over SSH as shown above. Then confirm the AIDE version and that the per-instance baseline database was built at first boot. The first-boot unit stays active after it completes, and the baseline lives at /var/lib/aide/aide.db.
aide --version sudo systemctl is-active aide-firstboot.service
sudo test -s /var/lib/aide/aide.db && echo "per-instance baseline present at /var/lib/aide/aide.db"First boot also writes a per-instance note that describes the appliance. It contains no secrets, because AIDE has no login or credential of any kind.
sudo cat /root/aide-instance.txtUnderstand the Monitored Scope
The appliance ships a focused, hardened default configuration at /etc/aide/aide.conf. It watches the paths that matter for tamper detection: executables, libraries, boot, kernel modules and /etc. It excludes volatile, high-churn paths so the report stays signal rather than noise. Review the monitored paths and exclusions:
sudo grep -E '^/|^!/|^FULL|^DIRS' /etc/aide/aide.confTo watch additional paths, add a line such as /opt/myapp FULL to /etc/aide/aide.conf, then rebuild the baseline (Step 8).
The Scheduled Daily Integrity Check
The systemd timer aidecheck.timer runs an integrity check once a day, with a randomized delay, and appends the report to /var/log/aide/aide.log. Confirm that it is enabled and see when it runs next:
systemctl is-enabled aidecheck.timer
systemctl list-timers aidecheck.timer --no-pager || trueAfter the first scheduled run, review the report at any time:
sudo test -f /var/log/aide/aide.log && sudo tail -n 20 /var/log/aide/aide.log || echo "no scheduled report yet - the daily timer has not fired since first boot"A report that lists added, removed or changed files is AIDE working as designed, not a failure. Review it. If the changes were expected, update the baseline as shown in Step 8.
Run an Integrity Check on Demand
Run a check against the per-instance baseline whenever you want. On a freshly booted instance it reports no differences. After any change to a monitored path, it reports exactly what changed.
The command below never leaves your shell in an error state. If differences are found, it prints a short note instead.
sudo aide --check --config=/etc/aide/aide.conf | tail -n 12 || echo "AIDE reported differences (review the report above). A diff is normal after intentional changes - update the baseline as shown in Step 8."Prove Change Detection with a Controlled Test
This self-contained test proves the detector end to end without touching any real system path. It builds a small baseline over a temporary directory and verifies that a clean check passes. It then adds and modifies a file, and shows that AIDE names exactly those files in its report.
WORK="$(mktemp -d)"; MON="$WORK/watched"; mkdir -p "$MON" printf 'original\n' > "$MON/file-a.txt" cat > "$WORK/aide.conf" <<CONF database_in=file:$WORK/db database_out=file:$WORK/db.new gzip_dbout=no DEMO = p+i+n+u+g+s+b+m+c+sha256 $MON DEMO CONF aide --init -c "$WORK/aide.conf" >/dev/null 2>&1 mv "$WORK/db.new" "$WORK/db" echo "-- unchanged baseline (expect clean) --" if aide --check -c "$WORK/aide.conf" >/dev/null 2>&1; then echo "CLEAN: no differences"; else echo "unexpected diff"; fi echo "-- add and modify a file, then re-check --" printf 'planted\n' > "$MON/intruder.txt" printf 'modified\n' > "$MON/file-a.txt" aide --check -c "$WORK/aide.conf" 2>&1 | grep -E 'Added entries|Changed entries|intruder\.txt|file-a\.txt' | head -8 rm -rf "$WORK" echo "DETECTED: AIDE named the added and changed files above"Update the Baseline After Intentional Changes
After you make deliberate, reviewed changes to the system, such as a package update, a configuration edit or a new application deployment, the next check reports those changes. Once you have confirmed they are expected, refresh the baseline so future checks compare against the new known-good state.
sudo aide --update --config=/etc/aide/aide.conf > /tmp/aide-update.log 2>&1 || true
sudo mv -f /var/lib/aide/aide.db.new /var/lib/aide/aide.db 2>/dev/null || true
sudo chmod 0600 /var/lib/aide/aide.db echo "baseline refreshed - future checks compare against the current state"The single-command equivalent shipped with AIDE on this image is sudo aideinit. It builds a fresh baseline into /var/lib/aide/aide.db.new. Move it into place with sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db.
Hardening the Baseline for Real Assurance
The baseline database is stored with restricted read access at /var/lib/aide/aide.db. An attacker who can rewrite both the filesystem and the baseline could hide their tracks.
For high-value systems, copy the baseline off the instance (or onto read-only media) after each intentional update, and compare against that trusted copy. AIDE is installed unmodified from the operating system's official package archive, so it continues to receive standard unattended security updates.
Support
SecureAnyCloud provides 24/7 technical support for this product by email and live chat at sales@secureanycloud.com. Support covers:
- Baseline initialization and updates
- Tuning the monitored scope
- Interpreting integrity reports
- Wiring the schedule and reports into a log or SIEM pipeline
- Moving the baseline off the box for stronger assurance
- Compliance mapping (PCI-DSS 11.5, CIS Benchmarks)
Critical issues receive a one-hour average response.
Deploy on AWS
Launch AIDE on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com