Créer une blacklist IP en fonction des logs serveurs récupérés dans un fichier
Objectif : rejeter les requêtes des clients qui génèrent des erreurs 404 et 500 trop fréquemment en les ajoutant à une blacklist. En général, cela signifie que le client scanne le serveur à la recherche de failles de sécurité ou fait du scraping de données. C’est un premier niveau de protection contre les attaques type DDoS ou reconnaissance.
Prérequis
Installer les outils suivants :
sudo apt update && sudo apt install -y jq iptablesVérifier l’installation :
jq --version
iptables --versionFichier de logs attendu
Caddy doit être configuré pour écrire des logs JSON dans :
/var/log/caddy/requests.jsonCe fichier doit contenir des champs .ts (timestamp) et .request.client_ip.
Créer le script monitor_blacklist.sh
sudo nano /usr/local/bin/monitor_blacklist.shContenu du script :
#!/bin/bash
LOG_DIR="/var/log/caddy"
LOG_FILES="$LOG_DIR/requests*.json"
BLACKLIST_FILE="/etc/caddy/blacklist.txt"
FAIL2BAN_JAIL="/etc/fail2ban/jail.local" # On récupère la whitelist Fail2Ban pour les IP à ne jamais bloquer
THRESHOLD=5
DELAY=180
cleanup() {
echo "Arrêt du script monitor_blacklist.sh"
pkill -f "sleep"
exit 0
}
trap cleanup SIGINT SIGTERM
# Vérification des dépendances
for cmd in iptables jq; do
if ! command -v $cmd &>/dev/null; then
echo "Erreur : $cmd non installé"
exit 1
fi
done
echo "Démarrage de la surveillance des logs..."
# Récupération dynamique des IP whitelists à partir du jail.local
readarray -t WHITELIST < <(grep -E '^ignoreip\s*=' "$FAIL2BAN_JAIL" \
| sed 's/.*=\s*//' \
| tr -s ' ' '\n' \
| grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}')
echo "IPs en liste blanche (issues de Fail2Ban) : ${WHITELIST[*]}"
# Création de la chaîne BLOCKED si absente
if ! sudo iptables -L BLOCKED &>/dev/null; then
sudo iptables -N BLOCKED && echo "Chaîne BLOCKED créée."
fi
# Boucle principale
while true; do
echo "-------------------------------------"
echo "Analyse des logs à $(date)"
TMP_FILE=$(mktemp)
> "$BLACKLIST_FILE"
# Extraction des IP à bannir
for file in $LOG_FILES; do
if [ -r "$file" ] && jq empty "$file" 2>/dev/null; then
jq -r '. | [.ts, .request.client_ip] | @tsv' "$file" >> "$TMP_FILE"
else
echo "Fichier ignoré (illisible ou invalide JSON) : $file"
fi
done
# Calcul des IP à bloquer selon le seuil et filtrage par la whitelist
awk -F'\t' '{ ipcount[int($1)" "$2]++ } END {
for (key in ipcount) {
split(key, parts, " ")
if (ipcount[key] >= '"$THRESHOLD"') {
print parts[2]
}
}
}' "$TMP_FILE" | sort -u | grep -v -F -f <(printf "%s\n" "${WHITELIST[@]}") > "$BLACKLIST_FILE"
rm "$TMP_FILE"
if [ -s "$BLACKLIST_FILE" ]; then
echo "IPs à bloquer :"
cat "$BLACKLIST_FILE"
while read -r ip; do
if [ -n "$ip" ]; then
if ! sudo iptables -C BLOCKED -s "$ip" -j REJECT 2>/dev/null; then
sudo iptables -A BLOCKED -s "$ip" -j REJECT
echo "→ IP bannie : $ip"
else
echo "→ IP déjà bannie : $ip"
fi
fi
done < "$BLACKLIST_FILE"
if ! sudo iptables -L INPUT -n | grep -q 'BLOCKED'; then
sudo iptables -A INPUT -j BLOCKED
echo "Chaîne BLOCKED ajoutée à INPUT."
fi
> "$BLACKLIST_FILE"
echo "Fichier blacklist.txt réinitialisé."
else
echo "Aucune IP à blacklister."
fi
sleep "$DELAY"
doneRendre le script exécutable
sudo chmod +x /usr/local/bin/monitor_blacklist.shLancer le script manuellement (test)
sudo nohup /usr/local/bin/monitor_blacklist.sh &Vérification
Vérifier que le script tourne :
ps aux | grep monitor_blacklist.shLister les IP bloquées :
sudo iptables -L BLOCKED -v -nVérifier si une IP spécifique est bloquée :
sudo iptables -L BLOCKED -v -n | grep 185.177.72.104Lister les appels de la règle BLOCKED dans INPUT :
sudo iptables -L INPUT -v -nCréer un service systemd
sudo nano /etc/systemd/system/monitor_blacklist.serviceContenu :
[Unit]
Description=Surveillance automatique des logs HTTP et blacklisting IP
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/monitor_blacklist.sh
Restart=always
RestartSec=10
User=root
WorkingDirectory=/var/www/html
StandardOutput=append:/var/log/monitor_blacklist.log
StandardError=append:/var/log/monitor_blacklist.log
[Install]
WantedBy=multi-user.targetActiver et démarrer le service :
sudo systemctl daemon-reload
sudo systemctl enable monitor_blacklist.service
sudo systemctl start monitor_blacklist.serviceVérifier son statut :
sudo systemctl status monitor_blacklist.serviceVérifier les logs :
sudo tail -f /var/log/monitor_blacklist.logSupprimer proprement le service
sudo systemctl stop monitor_blacklist.service
sudo systemctl disable monitor_blacklist.service
sudo rm /etc/systemd/system/monitor_blacklist.service
sudo systemctl daemon-reloadCe script offre une solution autonome et robuste pour réagir automatiquement aux comportements suspects détectés dans les logs HTTP générés par Caddy.