Table of Contents
Introduction
Un simple fichier manquant peut déclencher une tempête silencieuse.
C’est ce qui s’est produit dans ce cas concret : une image absente, appelée en boucle par une application, a généré plus de 42 millions de requêtes en 24 heures, saturant le disque du serveur malgré une rotation des logs parfaitement fonctionnelle.
Cet article détaille toute la démarche d’analyse, les commandes exécutées, les mesures de mitigation appliquées, et les bonnes pratiques à retenir pour éviter qu’un incident similaire ne se reproduise.
1️⃣ Constat initial : un disque plein malgré logrotate
Lors d’un contrôle régulier, la commande suivante montre un espace disque critique :
df -h
Résultat :
le volume racine est à 97 % d’utilisation, avec un fichier Apache dépassant les 12 Go.
Vérification des fichiers de logs :
du -sh /var/log/apache2/* | sort -h
ls -lh /var/log/apache2/*.log*
On constate que le fichier access.log.1 est anormalement volumineux.
2️⃣ Analyse des logs Apache
Pour comprendre la cause, on inspecte les dernières lignes :
tail -n 100 /var/log/apache2/site_ssl.access.log.1
Les journaux révèlent des milliers d’erreurs 404 sur une image :/Data/Vente/defaut.gif
On mesure ensuite la volumétrie :
awk '$9 ~ /^404$/{print $7}' /var/log/apache2/site_ssl.access.log.1 \
| sort | uniq -c | sort -nr | head -n 10
👉 Le résultat montre que 99,9 % des requêtes concernent cette même ressource manquante.
3️⃣ Identifier les IP à l’origine du problème
On cherche quelles adresses génèrent le plus de trafic :
awk '{print $1}' /var/log/apache2/site_ssl.access.log.1 \
| sort | uniq -c | sort -nr | head -n 20
Puis on filtre uniquement sur la ressource problématique :
awk '$7=="/Data/Vente/defaut.gif"{print $1}' /var/log/apache2/site_ssl.access.log.1 \
| sort | uniq -c | sort -nr | head -n 10
Une seule IP représente plus de 42 millions de requêtes, confirmant une boucle applicative.
4️⃣ Vérification du débit de requêtes
Pour estimer la charge par minute :
awk '{g=substr($4,2,17); c[g]++} END{for (g in c) print g, c[g]}' /var/log/apache2/site_ssl.access.log.1 \
| sort | tail -n 20
Le résultat montre plusieurs milliers de requêtes par seconde — un déni de service interne auto-généré.
5️⃣ Audit de logrotate
Vérifions la configuration :
cat /etc/logrotate.d/apache2
Extrait typique :
/var/log/apache2/*.log {
daily
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
}
📌 Problème identifié :delaycompress laisse le fichier .log.1 non compressé pendant 24 h, ce qui suffit à saturer le disque si le trafic est excessif.
6️⃣ Diagnostic final
- Disque racine saturé à 97 %
- Fichier d’accès Apache de 12 Go
- 42 millions de requêtes sur 24 h
- Cause : image manquante appelée en boucle par l’application
- Effet : explosion du volume de logs malgré rotation correcte
7️⃣ Solutions possibles
✅ Solution 1 – Correction applicative (durable)
Corriger le code de l’application pour ne plus appeler defaut.gif en boucle.
C’est la seule solution pérenne : tant que la requête est émise, le problème peut revenir.
🧩 Solution 2 – Mesure de contournement Apache
A. Option 1 : Fournir une image valide (1×1 pixel)
Créer une image minimale pour répondre 200 OK et casser la boucle :
mkdir -p /var/www/html/Data/Vente
printf 'R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==' | base64 -d \
> /var/www/html/Data/Vente/defaut.gif
chown www-data:www-data /var/www/html/Data/Vente/defaut.gif
chmod 0644 /var/www/html/Data/Vente/defaut.gif
curl -sI http://127.0.0.1/Data/Vente/defaut.gif
Résultat attendu :
HTTP/1.1 200 OK
L’application cessera alors ses tentatives, stoppant instantanément la croissance des logs.
B. Option 2 : Bloquer proprement et ne pas loguer
Pour une réponse maîtrisée et silencieuse côté serveur :
# /etc/apache2/conf-available/block-missing-image.conf
SetEnvIf Request_URI "^/Data/Vente/defaut.gif$" dontlog
<Location "/Data/Vente/defaut.gif">
Require all granted
Header always set Content-Length "0"
Header always set Content-Type "text/plain; charset=utf-8"
Redirect gone "/Data/Vente/defaut.gif"
</Location>
Adapter ensuite la ligne CustomLog du vhost pour ignorer les entrées marquées :
CustomLog /var/log/apache2/site_ssl.access.log combined env=!dontlog
Appliquer :
apachectl configtest
systemctl reload apache2
Résultat attendu :
HTTP/1.1 410 Gone
8️⃣ Libération immédiate d’espace disque
# Compression du fichier volumineux
gzip /var/log/apache2/site_ssl.access.log.1
# Suppression si plus utile
rm /var/log/apache2/site_ssl.access.log.1
# Vérification
df -h
9️⃣ Ajustement de logrotate
Pour compresser les logs immédiatement après rotation, retirer la directive delaycompress :
sed -i 's/^\(\s*\)delaycompress/# \1delaycompress/' /etc/logrotate.d/apache2
Test de configuration :
logrotate --debug /etc/logrotate.d/apache2
Forcer une rotation :
logrotate -f /etc/logrotate.d/apache2
🔟 Vérification du retour à la normale
Contrôler que la ressource ne provoque plus de 404 :
curl -sI http://127.0.0.1/Data/Vente/defaut.gif
Observer le log en temps réel :
watch -n 2 "ls -lh /var/log/apache2/site_ssl.access.log; tail -n 3 /var/log/apache2/site_ssl.access.log"
Le fichier ne doit plus grossir rapidement.
1️⃣1️⃣ Correctif applicatif (à planifier)
Le problème ne sera définitivement éliminé que lorsque l’application cessera d’appeler en boucle la ressource manquante.
Recommandations :
- livrer une image par défaut intégrée au code,
- ou implémenter une gestion d’erreur avec backoff (temporisation entre tentatives),
- ou ignorer les erreurs de ressource statique manquante.
1️⃣2️⃣ Bonnes pratiques et prévention
- Surveiller la taille des logs Apache quotidiennement.
- Configurer logrotate sans
delaycompresspour compresser sans délai. - Centraliser les logs volumineux sur un serveur externe (ELK, Loki, etc.).
- Créer une alerte sur la taille des fichiers
.log.1:
cat >/usr/local/sbin/check-apache-logsize.sh <<'EOS'
#!/usr/bin/env bash
THRESHOLD=$((1024*1024*1024))
for f in /var/log/apache2/*.log.1; do
[ -f "$f" ] || continue
size=$(stat -c%s "$f")
if [ "$size" -gt "$THRESHOLD" ]; then
echo "ALERTE : $f dépasse $(numfmt --to=iec $size)" | logger -t apache-logwatch
fi
done
EOS
chmod +x /usr/local/sbin/check-apache-logsize.sh
echo '*/15 * * * * root /usr/local/sbin/check-apache-logsize.sh' > /etc/cron.d/apache-logwatch
1️⃣3️⃣ Résumé post-incident
| Élément | Détail |
|---|---|
| Cause | Boucle d’appels sur une image manquante (defaut.gif) |
| Impact | Fichier de log Apache de 12 Go, disque saturé à 97 % |
| Solution temporaire | HTTP 410 + exclusion de log ou image 1×1 px |
| Solution durable | Correction du code applicatif |
| Prévention | Alerte sur taille de logs + logrotate immédiat |
🧠 Conclusion
Cet incident illustre un cas classique où une anomalie applicative minime entraîne un incident d’infrastructure majeur.
Grâce à une analyse structurée, quelques commandes bien ciblées et une mesure de contournement simple, le service a été stabilisé en moins d’une heure.
🔎 À retenir
- Une 404 répétée = un DoS interne.
- Toujours vérifier la rotation ET le volume réel des logs.
- Mettre en place un monitoring préventif.
- La vraie solution reste toujours applicative.
🔖 Mots-clés SEO
apache2, logrotate, erreur 404, boucle de requêtes, image manquante, HTTP 410 Gone, fichier de log saturé, saturation disque, débogage apache, rotation des logs, maintenance serveur, serveur plein, analyse log Apache.


