Surveiller l’intégrité de son système avec AIDE

Dans la série des articles consacrés à la sécurisation de mon VPS, j’ai déjà couvert Fail2ban pour bloquer les attaques par force brute, les en-têtes HTTP pour durcir nginx, ou encore les mises à jour automatiques pour colmater les failles connues. Ces mesures sont essentiellement réactives ou préventives. Mais comment détecter qu’un attaquant a quand même réussi à passer, et qu’il a modifié des fichiers système pour maintenir un accès discret ?

C’est le rôle d’AIDE: Advanced Intrusion Detection Environment, un outil de surveillance de l’intégrité du système de fichiers.

AIDE prend une photo de l’état de référence de votre système (hachages cryptographiques, permissions, propriétaires, tailles…), et détecte toute modification ultérieure. Un fichier système qui change sans raison légitime est un signal d’alarme.

Comment fonctionne AIDE ?

AIDE repose sur un principe simple :

  1. Initialisation : on génère une base de données de référence (aide --init) contenant les attributs de chaque fichier surveillé (SHA-256/SHA-512, MD5, taille, inode, permissions, propriétaire, date de modification…).
  2. Vérification : on compare périodiquement l’état actuel du système à cette base de référence (aide --check). Toute divergence est signalée.
  3. Mise à jour : après une opération légitime (mise à jour de paquets, modification de configuration volontaire), on régénère la base de référence.

La base de données doit idéalement être stockée hors ligne ou sur un support en lecture seule, sinon un attaquant suffisamment habile pourrait la modifier pour masquer ses traces. Dans notre contexte, nous allons au minimum la stocker dans un emplacement séparé du système surveillé.


Installation

AIDE est dans les dépôts officiels Ubuntu :

sudo apt update
sudo apt install aide aide-common

La configuration principale se trouve dans /etc/aide/aide.conf, et les règles par défaut dans /etc/aide/aide.conf.d/. Ces fichiers définissent quels répertoires surveiller et avec quels attributs.


Comprendre la configuration par défaut

Avant d’initialiser la base, un coup d’œil à la configuration s’impose :

cat /etc/aide/aide.conf

Vous y trouverez notamment la configuration de la base de données :

database_in=file:/var/lib/aide/aide.db
database_out=file:/var/lib/aide/aide.db.new
database_new=file:/var/lib/aide/aide.db.new
gzip_dbout=yes

Les macros de règles définissent les groupes d’attributs à vérifier :

# Surveille : permissions, inode, propriétaire, groupe, taille, liens, mtime, ctime, SHA256, SHA512
FIPSR = p+i+n+u+g+s+m+c+sha256+sha512
# Idem sans mtime (utile pour les fichiers légitimement mis à jour fréquemment)
NORMAL = sha256+sha512+p+i+n+u+g+s

Les répertoires surveillés par défaut incluent typiquement /bin, /sbin, /usr/bin, /usr/sbin, /etc, /boot, /lib, /usr/lib, et bien d’autres.

Pour voir la configuration assemblée :

aide --config-check

Exclure les répertoires dynamiques

Certains répertoires changent légitimement et très fréquemment, les inclure dans la surveillance générerait un bruit constant. Vérifiez que les exclusions suivantes sont bien présentes dans votre configuration (généralement déjà gérées par les fichiers dans /etc/aide/aide.conf.d/) :

!/proc
!/sys
!/dev
!/run
!/tmp
!/var/log
!/var/cache
!/var/tmp

Sur un VPS hébergeant WordPress, vous pouvez exclure les répertoires d’upload (qui changent légitimement) tout en surveillant le cœur de WordPress :

sudo nano /etc/aide/aide.conf.d/31_aide_wordpress
# Exclure les uploads WordPress (contenu utilisateur légitime)
!/var/www/aaa.monsite.fr/wp-content/uploads
!/var/www/bbb.monsite.fr/wp-content/uploads

# Surveiller le reste de WordPress avec des règles strictes
/var/www/aaa.monsite.fr/wp-admin    FIPSR
/var/www/aaa.monsite.fr/wp-includes FIPSR
/var/www/aaa.monsite.fr/wp-content/plugins FIPSR
/var/www/aaa.monsite.fr/wp-content/themes  FIPSR

Pourquoi surveiller wp-admin et wp-includes ? Ce sont les cibles privilégiées des attaquants cherchant à déposer des webshells ou à modifier des fichiers PHP pour maintenir un accès persistant.


Initialisation de la base de référence

Une fois la configuration satisfaisante, on génère la base initiale :

sudo aideinit

Cette commande peut prendre plusieurs minutes selon le nombre de fichiers surveillés — c’est normal. Elle génère la base dans /var/lib/aide/aide.db.new.

Sur Ubuntu, aideinit est un wrapper qui gère automatiquement la copie de la base :

# Si aideinit ne la copie pas automatiquement :
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Vérifiez que la base est bien en place :

ls -lh /var/lib/aide/aide.db

Bonne pratique : copiez cette base de référence vers un emplacement externe immédiatement après l’initialisation.


Premier test de vérification manuelle

Avant d’automatiser, testons une vérification manuelle :

sudo aide --check

Sur un système fraîchement initialisé, la sortie devrait être propre :

Start timestamp: 2024-01-15 10:23:45 +0100 (AIDE 0.18.6)
AIDE found NO differences between database and filesystem. Looks okay!!

Si des différences apparaissent immédiatement, c’est souvent dû à des fichiers qui ont changé entre l’initialisation et le premier check (logs, caches…). Il faudra ajuster les exclusions ou réinitialiser la base.


Automatisation avec cron

On planifie une vérification quotidienne à 5h du matin:

sudo crontab -e

Ajoutez :

# AIDE - vérification d'intégrité quotidienne à 5h00
0 5 * * * /usr/bin/aide --check 2>&1 | /usr/bin/mail -s "[VPS] AIDE integrity check - $(hostname) - $(date +\%Y-\%m-\%d)" votre@email.fr

Note : le caractère % doit être échappé en \% dans les crontabs.

Alternativement, voici un script plus intelligent qui n’envoie un email qu’en cas d’anomalie :

sudo nano /usr/local/bin/aide-check.sh
#!/bin/bash

LOGFILE="/var/log/aide/aide-check-$(date +%Y%m%d).log"
EMAIL="votre@email.fr"
HOSTNAME=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')

mkdir -p /var/log/aide

echo "=== AIDE Check - $DATE ===" > "$LOGFILE"
/usr/bin/aide --check >> "$LOGFILE" 2>&1
EXIT_CODE=$?

# Exit code 0 = pas de différences, 1 = différences trouvées, >1 = erreur
if [ $EXIT_CODE -ne 0 ]; then
    mail -s "[ALERTE] AIDE - Modifications détectées sur $HOSTNAME" "$EMAIL" < "$LOGFILE"
fi

# Rotation : conserver 30 jours de logs
find /var/log/aide/ -name "aide-check-*.log" -mtime +30 -delete
sudo chmod +x /usr/local/bin/aide-check.sh
sudo mkdir -p /var/log/aide

Puis dans la crontab :

0 5 * * * /usr/local/bin/aide-check.sh

Interpréter les alertes AIDE

Quand AIDE détecte des modifications, la sortie ressemble à ceci :

AIDE found differences between database and filesystem!!
Start timestamp: 2024-01-16 05:00:12 +0100 (AIDE 0.18.6)

Summary:
  Total number of entries:      42847
  Added entries:                    2
  Removed entries:                  0
  Changed entries:                  8

---------------------------------------------------
Added entries:
---------------------------------------------------

f++++++++++++++++: /etc/nginx/conf.d/nouveau-site.conf

---------------------------------------------------
Changed entries:
---------------------------------------------------

f =.... mc.. SHA256: /etc/passwd
f =.... mc.. SHA256: /etc/shadow
f =.... mc.. SHA256: /etc/group

Décoder les codes de modification

Les lettres et symboles indiquent ce qui a changé :

CodeSignification
pPermissions
iInode
nNombre de liens
uPropriétaire (uid)
gGroupe (gid)
sTaille
mHeure de modification (mtime)
cHeure de changement d’état (ctime)
SHA256Hachage SHA-256 modifié
.Attribut inchangé
+Attribut ajouté (nouveau fichier)
-Attribut supprimé (fichier retiré)

Dans l’exemple ci-dessus, /etc/passwd, /etc/shadow et /etc/group ont vu leur mtime, ctime et hachage SHA-256 changer — ce qui est attendu après l’ajout d’un utilisateur système par un paquet.

Distinguer les faux positifs des vraies alertes

Modifications légitimes courantes :

  • /etc/passwd, /etc/shadow, /etc/group → installation d’un paquet créant un utilisateur système
  • /etc/ssl/certs/ → renouvellement du certificat Let’s Encrypt
  • /var/www/*/wp-content/plugins/ → mise à jour d’un plugin WordPress
  • /usr/bin/, /usr/lib/ → mise à jour de paquets système

Signaux d’alarme :

  • Modification de /bin/bash, /bin/sh, /usr/bin/sudo, /usr/sbin/sshd → remplacement possible par un rootkit
  • Nouveau fichier .php dans wp-admin/ ou wp-includes/ → webshell probable
  • Modification de /etc/crontab, /etc/cron.d/, /etc/rc.local → persistance malveillante
  • Changement dans /etc/ssh/sshd_config → backdoor SSH possible
  • Nouveau fichier dans /tmp/ ou /dev/shm/ avec un hachage inconnu

Règle de base : toute modification d’un binaire système ou d’un fichier de configuration critique qui ne correspond pas à une opération de maintenance planifiée doit être considérée comme suspecte jusqu’à preuve du contraire.


Mettre à jour la base après une maintenance légitime

Après une opération de maintenance planifiée, il faut régénérer la base de référence pour que les nouvelles modifications deviennent la nouvelle « normale ».

Workflow recommandé :

# 1. Vérifier l'état avant maintenance (archiver le rapport)
sudo aide --check > /root/aide-avant-maintenance-$(date +%Y%m%d).log 2>&1

# 2. Effectuer la maintenance
sudo apt upgrade
# ... autres opérations ...

# 3. Générer la nouvelle base
sudo aide --update

# 4. Remplacer l'ancienne base par la nouvelle
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# 5. Vérification de sanité : le check suivant doit être propre
sudo aide --check

Important : aide --update génère une nouvelle base dans aide.db.new mais ne remplace pas automatiquement aide.db. C’est volontaire — vous devez valider manuellement la transition.

Automatiser la mise à jour post-apt (optionnel)

On peut intégrer la mise à jour AIDE dans un hook apt pour qu’elle soit déclenchée automatiquement après chaque apt upgrade :

sudo nano /etc/apt/apt.conf.d/99aide-update
DPkg::Post-Invoke {"if [ -x /usr/bin/aide ]; then /usr/bin/aide --update && mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db; fi";};

Attention : cette automatisation est pratique mais supprime le moment de validation manuelle. À utiliser avec discernement, personnellement, je préfère garder la mise à jour manuelle pour les systèmes exposés sur Internet.


Protéger la base de données AIDE

La base de référence est le talon d’Achille du système : si un attaquant peut la modifier, il peut masquer ses traces. Quelques précautions :

Restreindre les permissions :

sudo chown root:root /var/lib/aide/aide.db
sudo chmod 600 /var/lib/aide/aide.db

Copier la base hors du serveur après chaque initialisation/mise à jour :

# Ajouter au script rsync de sauvegarde
rsync -avz /var/lib/aide/aide.db backup-user@192.168.x.x:/backup/vps/aide/aide.db.$(date +%Y%m%d)

Vérifier l’intégrité de la base elle-même :

# Générer un hachage de la base à conserver hors ligne
sha256sum /var/lib/aide/aide.db | sudo tee /root/aide.db.sha256

Vérification que tout fonctionne

# Tester une modification détectable
echo "test" | sudo tee /tmp/test-aide.txt > /dev/null
sudo touch /etc/aide-test-$(date +%s)

# Lancer une vérification
sudo aide --check

# Vous devriez voir les nouveaux fichiers dans "Added entries"
# Nettoyer
sudo rm /etc/aide-test-*

Conclusion

AIDE complète efficacement les autres couches de sécurité déjà en place sur ce VPS. Là où Fail2ban bloque les tentatives d’intrusion avant qu’elles aboutissent, AIDE détecte les modifications après une compromission éventuelle — c’est de la détection post-incident. Utilisé conjointement avec Logwatch pour la corrélation des logs, il forme un filet de sécurité cohérent.

Les trois actions clés à retenir :

  1. Initialiser la base sur un système propre et la stocker hors ligne.
  2. Surveiller les alertes quotidiennes en distinguant faux positifs et vraies anomalies.
  3. Mettre à jour la base après toute maintenance légitime, de manière contrôlée.

La prochaine étape logique dans cette série sera de centraliser ces alertes:AIDE, Fail2ban, auth.log dans un SIEM léger, mais ça, c’est pour un prochain article.


Cet article fait partie d’une série sur la sécurisation d’un VPS Ubuntu 24.04 hébergeant des sites WordPress. Les articles précédents couvrent l’installation de la stack LEMP, la configuration SSH, Fail2ban, Logwatch et les en-têtes HTTP nginx.

Commentaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *