guides/serveur/analyse-logs-detection-bots.md
2026-02-03 09:48:16 +01:00

16 KiB

Guide d'analyse des logs et détection de bots abusifs

Guide complet pour analyser les logs d'un serveur, identifier les IP problématiques, détecter les bots malveillants et mettre en place des protections automatiques.

Table des matières

  1. Comprendre les logs
  2. Analyser les logs Docker
  3. Identifier les IP problématiques
  4. Analyser le comportement d'une IP
  5. Déterminer le type de bot
  6. Bloquer manuellement une IP
  7. Automatiser avec Fail2ban
  8. Rate limiting
  9. Monitoring continu
  10. Mémo rapide

1. Comprendre les logs

Types de logs sous Linux

Type Emplacement Contenu
Logs système /var/log/syslog Messages généraux du système
Logs d'authentification /var/log/auth.log Connexions SSH, sudo, etc.
Logs Docker /var/lib/docker/containers/.../*.log Logs des conteneurs
Journald journalctl Logs systemd (moderne)
Logs d'applications Variable Nginx, Apache, bases de données...

Format typique d'une ligne de log

2026/02/02 08:17:57 [I] router: completed GET /repo/archive/main.zip for 216.73.216.118:0, 200 OK in 10.8ms
│                   │   │                                              │                       │
│                   │   │                                              └─ IP source           └─ Code HTTP
│                   │   └─ Action (GET, POST...)
│                   └─ Niveau (I=Info, E=Error, W=Warning)
└─ Timestamp

2. Analyser les logs Docker

Voir les logs d'un conteneur

Logs complets :

docker logs nom_conteneur

Dernières lignes :

docker logs nom_conteneur --tail 50

Logs en temps réel (suivi) :

docker logs nom_conteneur -f

Logs depuis un moment spécifique :

# Dernières 24 heures
docker logs nom_conteneur --since 24h

# Dernières 2 heures
docker logs nom_conteneur --since 2h

# Depuis une date précise
docker logs nom_conteneur --since 2026-02-01T00:00:00

Filtrer les logs

Chercher un pattern spécifique :

docker logs nom_conteneur | grep "erreur"
docker logs nom_conteneur | grep "404"
docker logs nom_conteneur | grep -i "archive"  # -i = insensible à la casse

Exclure certaines lignes :

docker logs nom_conteneur | grep -v "health check"  # -v = inverse

Sauvegarder dans un fichier :

docker logs nom_conteneur --since 24h > /tmp/logs.txt

3. Identifier les IP problématiques

Compter toutes les requêtes par IP

Méthode générale (si les IP sont dans les logs) :

docker logs conteneur --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -20

Explication :

  • grep -oP '\d+\.\d+\.\d+\.\d+' : Extrait toutes les adresses IP (regex)
  • sort : Trie les IP
  • uniq -c : Compte les occurrences uniques
  • sort -rn : Trie par nombre décroissant
  • head -20 : Garde les 20 premières

Exemple de résultat :

   2144 216.73.216.118    ← SUSPECT (trop de requêtes)
     42 192.168.1.100
     12 10.0.0.5
      3 172.18.0.1

Filtrer par type de requête

Requêtes d'archives uniquement :

docker logs forgejo --since 24h | grep "archive" > /tmp/archives.log
grep -oP '\d+\.\d+\.\d+\.\d+' /tmp/archives.log | sort | uniq -c | sort -rn

Requêtes avec erreur 500 :

docker logs forgejo --since 24h | grep "500 Internal" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn

Requêtes POST (modifications) :

docker logs forgejo --since 24h | grep "POST" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn

Statistiques par heure

Voir l'activité par heure :

docker logs forgejo --since 24h | grep "archive" | grep -oP '^\d{4}/\d{2}/\d{2} \d{2}' | uniq -c

Exemple :

  12 2026/02/02 08    ← 12 requêtes à 8h
 145 2026/02/02 09    ← 145 requêtes à 9h (SUSPECT)
  18 2026/02/02 10

4. Analyser le comportement d'une IP

Une fois une IP suspecte identifiée (ex: 216.73.216.118), analysons son comportement.

Voir toutes ses requêtes

docker logs forgejo --since 24h | grep "216.73.216.118" > /tmp/ip_suspect.log

Compter ses requêtes

wc -l /tmp/ip_suspect.log

Exemple : 2144 requêtes en 24h = ~90 requêtes/heure = suspect

Voir ce qu'elle télécharge

grep "216.73.216.118" /tmp/ip_suspect.log | head -20

Patterns suspects :

Pattern Signification
/archive/main:vendor/... Scanne les dépendances (recherche de vulnérabilités)
/archive/commit123.zip répété Télécharge tous les commits (crawler)
Requêtes très rapprochées Bot automatisé
500 Internal Server Error Tentatives qui échouent (disque plein, etc.)

Identifier les repos ciblés

grep "216.73.216.118" /tmp/ip_suspect.log | grep -oP '/[^/]+/[^/]+/archive' | sort | uniq -c | sort -rn

Exemple :

   1350 /studio-variable/designtopack/archive    ← Cible principale
    232 /studio-variable/index-shop/archive
     86 /studio-variable/world-game/archive

Analyser la fréquence

Temps entre chaque requête :

grep "216.73.216.118" /tmp/ip_suspect.log | grep -oP '^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}' | head -20

Si les timestamps sont très rapprochés (< 1 seconde) : C'est un bot automatisé.


5. Déterminer le type de bot

Identifier le User-Agent

docker logs forgejo --since 24h | grep "216.73.216.118" | grep -oP 'User-Agent: [^"]*' | sort | uniq -c

User-Agents courants :

User-Agent Type Légitime ?
Googlebot Crawler Google Oui
bingbot Crawler Bing Oui
curl/7.x Script automatisé ⚠️ Dépend
python-requests/2.x Script Python ⚠️ Dépend
Go-http-client Script Go ⚠️ Dépend
Aucun ou vide Bot basique Suspect

Identifier le propriétaire de l'IP (whois)

whois 216.73.216.118 | head -30

Cherche :

  • OrgName: → Propriétaire (AWS, Google, hébergeur...)
  • NetName: → Type de réseau
  • Country: → Pays

Exemples :

OrgName: Amazon.com, Inc.        → Hébergé sur AWS
OrgName: Google LLC              → Infrastructure Google
OrgName: OVH SAS                 → Hébergeur français

Vérifier la réputation de l'IP

Services en ligne :


6. Bloquer manuellement une IP

Dans Forgejo/Gitea

Éditer la configuration :

sudo nano /path/to/forgejo/data/gitea/conf/app.ini

Ajouter la section [security] :

[security]
BANNED_IP_ADDRESSES = 216.73.216.118,192.168.1.50

Redémarrer :

docker restart forgejo

Avec iptables (niveau firewall)

Bloquer une IP :

sudo iptables -A INPUT -s 216.73.216.118 -j DROP

Voir les règles :

sudo iptables -L -n

Sauvegarder (pour que ça persiste au reboot) :

sudo iptables-save > /etc/iptables/rules.v4

Débloquer une IP :

sudo iptables -D INPUT -s 216.73.216.118 -j DROP

Avec UFW (plus simple)

Bloquer une IP :

sudo ufw deny from 216.73.216.118

Voir les règles :

sudo ufw status numbered

Supprimer une règle :

sudo ufw delete NUMÉRO

7. Automatiser avec Fail2ban

Fail2ban surveille les logs et bannit automatiquement les IP abusives.

Installation

sudo apt update
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Configuration pour détecter les requêtes d'archives excessives

Créer un filtre :

sudo nano /etc/fail2ban/filter.d/forgejo-archive.conf

Contenu :

[Definition]
failregex = completed GET .*/archive/.* for <HOST>
ignoreregex =

Créer une jail :

sudo nano /etc/fail2ban/jail.d/forgejo.conf

Contenu :

[forgejo-archive]
enabled = true
filter = forgejo-archive
logpath = /var/lib/docker/containers/CONTAINER_ID/CONTAINER_ID-json.log
maxretry = 50
findtime = 600
bantime = 3600

Remplace CONTAINER_ID par le vrai ID :

docker inspect forgejo --format='{{.LogPath}}'

Redémarrer Fail2ban :

sudo systemctl restart fail2ban

Vérifier le statut

# Statut général
sudo fail2ban-client status

# Statut d'une jail spécifique
sudo fail2ban-client status forgejo-archive

Exemple de sortie :

Status for the jail: forgejo-archive
|- Filter
|  |- Currently failed: 2
|  |- Total failed: 145
|  `- File list: /var/lib/docker/containers/.../...json.log
`- Actions
   |- Currently banned: 1
   |- Total banned: 3
   `- Banned IP list: 216.73.216.118

Commandes utiles

# Voir les IP bannies
sudo fail2ban-client get forgejo-archive banip

# Bannir manuellement une IP
sudo fail2ban-client set forgejo-archive banip 192.168.1.50

# Débannir une IP
sudo fail2ban-client set forgejo-archive unbanip 192.168.1.50

# Voir les logs de Fail2ban
sudo tail -f /var/log/fail2ban.log

Ajuster les paramètres

Dans /etc/fail2ban/jail.d/forgejo.conf :

Paramètre Signification Exemple
maxretry Nombre de tentatives avant ban 50 = bannir après 50 requêtes
findtime Fenêtre de temps (secondes) 600 = dans les 10 dernières minutes
bantime Durée du ban (secondes) 3600 = bannir pour 1 heure

Exemples de configurations :

# Tolérant (serveur public)
maxretry = 100
findtime = 600
bantime = 3600

# Strict (serveur privé)
maxretry = 20
findtime = 300
bantime = 86400  # 24 heures

# Permanent
bantime = -1  # Ban permanent

8. Rate limiting

Limite le nombre de requêtes par IP directement dans l'application.

Dans Forgejo/Gitea

Éditer app.ini :

sudo nano /path/to/forgejo/data/gitea/conf/app.ini

Ajouter :

[api]
ENABLE_RATE_LIMIT = true
RATE_LIMIT_BURST = 100

[repository]
DOWNLOAD_OR_CLONE_METHODS = http,https,ssh
DOWNLOAD_EXPIRY_TIME = 60

Redémarrer :

docker restart forgejo

Avec Nginx (si reverse proxy)

Dans la config Nginx :

http {
    # Définir une zone de rate limiting
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

    server {
        location / {
            # Appliquer la limite
            limit_req zone=mylimit burst=20 nodelay;
            proxy_pass http://localhost:3000;
        }
    }
}

Tester la config :

sudo nginx -t
sudo systemctl reload nginx

9. Monitoring continu

Script de surveillance quotidien

Créer un script :

sudo nano /usr/local/bin/check-suspicious-ips.sh

Contenu :

#!/bin/bash

LOG_FILE="/tmp/suspicious_ips_$(date +%Y%m%d).log"
THRESHOLD=100

echo "=== Suspicious IP Report - $(date) ===" > "$LOG_FILE"
echo "" >> "$LOG_FILE"

# Top 20 IP des dernières 24h
echo "Top 20 IPs (last 24h):" >> "$LOG_FILE"
docker logs forgejo --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | \
  sort | uniq -c | sort -rn | head -20 >> "$LOG_FILE"

echo "" >> "$LOG_FILE"

# IP dépassant le seuil
echo "IPs with more than $THRESHOLD requests:" >> "$LOG_FILE"
docker logs forgejo --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | \
  sort | uniq -c | sort -rn | awk -v threshold="$THRESHOLD" '$1 > threshold' >> "$LOG_FILE"

# Envoyer par email (optionnel)
# mail -s "Suspicious IPs Report" admin@example.com < "$LOG_FILE"

echo "Report saved to $LOG_FILE"

Rendre exécutable :

sudo chmod +x /usr/local/bin/check-suspicious-ips.sh

Ajouter au cron (tous les jours à 8h) :

sudo crontab -e

Ajouter :

0 8 * * * /usr/local/bin/check-suspicious-ips.sh

Dashboard temps réel

Surveiller les requêtes d'archives en temps réel :

watch -n 5 'docker logs forgejo --since 5m | grep "archive" | wc -l'

Voir les nouvelles IP actives :

watch -n 10 'docker logs forgejo --since 10m | grep -oP "\d+\.\d+\.\d+\.\d+" | sort -u'

Alertes par email

Installer mailutils :

sudo apt install mailutils

Script d'alerte :

#!/bin/bash
COUNT=$(docker logs forgejo --since 1h | grep "archive" | wc -l)

if [ "$COUNT" -gt 500 ]; then
    echo "ALERTE: $COUNT requêtes d'archives dans la dernière heure!" | \
    mail -s "Alerte serveur Forgejo" admin@example.com
fi

Ajouter au cron (toutes les heures) :

0 * * * * /path/to/alert-script.sh

10. Mémo rapide (cheat sheet)

Analyse basique

# Top 20 IP des dernières 24h
docker logs conteneur --since 24h | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -20

# Requêtes d'une IP spécifique
docker logs conteneur --since 24h | grep "IP_ADRESSE"

# Compter les requêtes d'archives
docker logs conteneur --since 24h | grep "archive" | wc -l

# Repos les plus ciblés
docker logs conteneur --since 24h | grep "archive" | grep -oP '/[^/]+/[^/]+/archive' | sort | uniq -c | sort -rn | head -10

# Whois d'une IP
whois IP_ADRESSE | head -30

Fail2ban

# Statut général
sudo fail2ban-client status

# Statut d'une jail
sudo fail2ban-client status nom_jail

# IP bannies
sudo fail2ban-client get nom_jail banip

# Bannir manuellement
sudo fail2ban-client set nom_jail banip IP

# Débannir
sudo fail2ban-client set nom_jail unbanip IP

# Logs Fail2ban
sudo tail -f /var/log/fail2ban.log

Blocage manuel

# Dans Forgejo (app.ini)
[security]
BANNED_IP_ADDRESSES = IP1,IP2,IP3

# Avec UFW
sudo ufw deny from IP_ADRESSE
sudo ufw status numbered
sudo ufw delete NUMERO

# Avec iptables
sudo iptables -A INPUT -s IP_ADRESSE -j DROP
sudo iptables -L -n

Cas pratiques

Cas 1 : Bot qui télécharge massivement des archives

Symptômes :

  • 2000+ requêtes d'archives en 24h
  • Disque qui se remplit rapidement
  • Cache repo-archive qui grossit

Diagnostic :

# Identifier l'IP
docker logs forgejo --since 24h | grep "archive" | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -5

# Analyser son comportement
docker logs forgejo --since 24h | grep "IP_SUSPECTE" | head -20

# Whois
whois IP_SUSPECTE

Solution :

  1. Bloquer l'IP dans Forgejo (app.ini)
  2. Configurer Fail2ban pour détecter automatiquement
  3. Ajouter rate limiting
  4. Mettre en place un cron de nettoyage du cache

Cas 2 : Scan de vulnérabilités

Symptômes :

  • Requêtes ciblant /vendor, /node_modules, .env
  • Beaucoup d'erreurs 404
  • User-Agent = curl ou python-requests

Diagnostic :

# Voir les URLs demandées
docker logs forgejo --since 24h | grep "IP_SUSPECTE" | grep -oP 'GET [^ ]*' | sort | uniq -c

Solution :

  1. Bloquer l'IP
  2. Vérifier qu'aucun fichier sensible n'est exposé
  3. Configurer Fail2ban pour bannir après 10 erreurs 404

Cas 3 : Attaque DDoS

Symptômes :

  • Centaines d'IP différentes
  • Requêtes très rapprochées
  • Serveur lent/inaccessible

Diagnostic :

# Nombre d'IP uniques
docker logs forgejo --since 10m | grep -oP '\d+\.\d+\.\d+\.\d+' | sort -u | wc -l

# Si > 100 IP en 10 min = DDoS potentiel

Solution :

  1. Mettre le service derrière Cloudflare
  2. Activer le mode "Under Attack" temporairement
  3. Réduire drastiquement le rate limiting

Ressources complémentaires

Documentation :

Outils utiles :

  • goaccess : Analyseur de logs web en temps réel
  • geoiplookup : Géolocalisation d'IP
  • tcpdump : Capture du trafic réseau
  • netstat / ss : Connexions actives

Regex IP :

\d+\.\d+\.\d+\.\d+          # IPv4 basique
\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b  # IPv4 plus précis

Guide créé le 2026-02-03