4 points par GN⁺ 2025-06-02 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Le Gitea et le blog d’un serveur personnel ont été submergés par du trafic de scraping, déclenchant une série d’alertes disque, CPU et mémoire ; l’administrateur a réagi en combinant analyse des logs, Nginx et Fail2Ban
  • Selon Zabbix, le trafic a fortement dépassé la normale ; la moyenne mensuelle de Nginx était de 8 requêtes par seconde, avec des pointes à plus de 20 requêtes par seconde
  • La cause n’était pas un afflux massif venu d’une seule source comme Reddit ou Hacker News, mais plutôt un scraping distribué de plusieurs blocs d’IP visant les URL de www.lambdacreate.com et krei.lambdacreate.com
  • Nginx renvoyait 403 aux user agents malveillants connus et appliquait une limitation de requêtes par IP ; les clients générant trop de 403 étaient ensuite bannis pendant 24 heures via Fail2Ban
  • Au moment de l’écriture, la liste de blocage était montée à 735 bans au total, avec en particulier des requêtes cherchant à générer des tarballs pour tous les commits des dépôts publics Gitea, ce qui alourdissait fortement la charge du serveur

Le trafic de scraping qui a mis un serveur personnel sous pression

  • Un afflux soudain de trafic de bots non désiré a touché un espace personnel sur Internet, au point d’affecter les services utilisés par de vrais lecteurs
  • Les services d’indexation destinés à préserver les sites, comme Archive.org, restent acceptables, mais Amazon, Facebook, OpenAI et divers bots aléatoires sont considérés comme des acteurs qui consomment le contenu à leurs propres fins
  • La collecte massive de données sur Internet par les grandes entreprises, ainsi que la demande de données pour entraîner des modèles d’IA, auraient encore accentué cette pression de scraping
  • Ce trafic n’était pas celui de vrais utilisateurs de Lambdacreate, mais un facteur perturbateur qui réduisait l’accessibilité pour les lecteurs humains

Les premiers signes d’anomalie détectés par Zabbix

  • C’est Zabbix qui a signalé le problème en premier, avec une alerte indiquant que le disque du conteneur était plein
  • Dans un environnement basé sur LXD, l’auteur a agrandi un sparse file ZFS puis brièvement arrêté et relancé le site, sans éliminer la cause profonde
  • Ensuite, l’instance Gitea a recommencé chaque jour à consommer tout l’espace disque, en générant 20 à 30 Go de données par jour
  • Au départ, le problème a été attribué au fait que Gitea n’active pas par défaut le nettoyage des archives de dépôts, ce qui a conduit à configurer un nettoyage agressif
  • Des alertes CPU et mémoire ont vite suivi ; sur Gitea, git pull et git push devenaient difficiles, et même le client weechat ne parvenait plus à maintenir sa connexion

Un volume de requêtes monté à 10 fois la normale

  • Grâce à une supervision hors bande mise en place pour comparer les métriques passées à l’état actuel, il a été possible de confirmer un schéma anormal
  • Sur le tableau de bord Zabbix, les indicateurs clés étaient le nombre de requêtes Nginx et le graphique du débit réseau
  • Sur un mois, la moyenne des requêtes Nginx tournait autour de 8 requêtes par seconde
  • Dans les pires périodes, le serveur recevait plus de 20 requêtes par seconde ; un volume modeste à l’échelle d’un grand service, mais pour un serveur personnel cela représentait environ 10 fois le niveau habituel
  • Au-delà du simple nombre de requêtes, l’augmentation conjointe de l’usage disque et CPU liée à Gitea alourdissait fortement l’exploitation du serveur

Suivre les logs avec lnav et goaccess

  • Pour garder le serveur en vie suffisamment longtemps afin d’examiner les logs, l’auteur a temporairement arrêté le conteneur et Nginx avant de lancer l’analyse
  • Les outils utilisés étaient lnav et goaccess
  • lnav affiche les fichiers de logs dans une interface TUI colorée et fournit une couche d’abstraction au-dessus des formats de logs classiques, ce qui permet de les interroger en SQL
  • Dans access.log, l’analyse s’est concentrée sur les questions suivantes
    • combien y avait-il d’adresses IP visiteuses au total ;
    • y avait-il des motifs dans les adresses IP ;
    • le trafic venait-il d’un referrer particulier ;
    • quels user agents étaient utilisés ;
    • quelles IP étaient associées à quels user agents
  • Le résultat a montré qu’il ne s’agissait pas d’un “hug of death” venu d’un referrer unique, mais de plusieurs blocs d’IP qui parcouraient les URL de l’ensemble du site

Des 403 basés sur le user agent et une limitation des requêtes

  • La première réponse a consisté à lister dans Nginx les user agents problématiques afin de leur renvoyer 403
  • L’exemple de configuration utilisait map $http_user_agent $badagent pour marquer des agents comme AdsBot-Google, Amazonbot et Amazonbot/0.1
  • La configuration Nginx de base incluait ces règles sur les user agents, ainsi qu’une limitation de débit par IP
  • La configuration de l’hôte virtuel comprenait notamment les comportements suivants
    • limit_req zone=krei burst=20 nodelay; pour appliquer une limitation des requêtes
    • si $badagent est vrai, return 403; bloque l’accès au contenu
  • Cette méthode aide à réduire le traitement côté backend, mais le serveur doit tout de même accepter la requête HTTP et traiter la réponse 403, ce qui laisse une charge non négligeable en cas de gros volume simultané

Automatiser le blocage au niveau pare-feu avec Fail2Ban

  • Une fois les logs 403 accumulés, lnav permettait d’identifier les IP uniques ayant reçu un 403
  • goaccess servait à analyser ensemble les logs passés et présents afin de visualiser le nombre de requêtes arrivées sur le serveur et les endpoints les plus ciblés
  • Pour protéger réellement le serveur, l’auteur a ajouté Fail2Ban
  • La règle Fail2Ban était simple : repérer dans le log d’accès Nginx les IP générant trop de réponses 403
  • La durée de blocage était fixée à 86400 secondes, soit 24 heures
  • Au moment de l’écriture, le résultat de fail2ban-client status nginx-forbidden était le suivant
    • Échecs actuels : 13
    • Échecs totaux : 57135
    • Blocages actuels : 38
    • Blocages totaux : 735

La vraie cible n’était pas le blog, mais la génération de tarballs Gitea

  • Au final, les lecteurs ont de nouveau pu accéder au blog et aux autres services de Lambdacreate
  • Quand il faut bloquer du trafic robotisé, il devient même difficile d’écrire un billet de blog
  • Le trafic problématique ne visait pas le scraping du blog, mais la génération de tarballs pour tous les commits de chaque dépôt public de l’instance Gitea
  • À plus long terme, l’auteur envisage d’étendre les listes de blocage ou de prévoir des exceptions pour des services légitimes comme Archive.org
  • Il ne souhaite pas voir son contenu disparaître des moteurs de recherche, mais ne veut pas non plus qu’il serve de carburant à la dégradation de l’Internet par l’IA

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.