Mise à mal des forges Git par les indexeurs d'IA

Bonjour à tous !
Il semblerait qu’un phénomène touche beaucoup d’acteurs de l’hébergement aujourd’hui, notamment plusieurs du côté du CHATONS. Il s’agit de la mise à mal des forges Git par des crawlers, ou indexeurs d’IA. Nous sommes, chez Deuxfleurs, également impactés. Comme le mode opératoire semble être sensiblement le même partout, nous avons tout intérêt à partager des techniques de contre-mesures communes et à dialoguer sur le sujet. Voici donc un topic dans lequel nous pouvons partager. Je vais ci-dessous répertorier l’ensemble des informations à ma connaissance. Je peux corriger et mettre à jour ce message à chaque rectification, demande, ou apparition d’éléments nouveaux.

Le 17 janvier 2025, Xe Iaso a publié sur son journal personnel un article expliquant que l’indexeur pour IA d’Amazon a un impact majeur sur son instance Gitea, au point de générer un besoin d’achat de nouveau matériel. Une politique stricte sur le robots.txt n’y change rien. D’abord caché derrière un VPN, le service est de nouveau en ligne derrière un système de preuve de travail fait maison : Anubis.

Le 12 février 2025 nous avons été obligés, chez Deuxfleurs, de configurer des abandons de requêtes à toute la plage d’IP en /13 d’Alibaba, au niveau d’iptables. Notre instance Forgejo subissait un DoS de leur part. Il y a eu des questionnements en interne sur l’intérêt ou non d’appliquer une sanction similaire aux agents homologues de l’ouest, pour ne pas accuser de biais. Nous avons renoncé pour deux raisons : l’abus de nos services par les indexeurs d’Alibaba est à un facteur x10 par rapport aux autres indexeurs, qui eux ne mettent pas en péril notre infrastructure. La deuxième raison est que bannir toute une plage d’IP risque fortement de faire des victimes collatérales, il convient alors de limiter cette pratique au maximum pour préserver les idéaux autour d’internet. Par ailleurs, nous avons fixé les règles iptables de manière temporaire, avec l’espoir que les abus prendraient fin bientôt.

Le 23 février 2025 nous redémarrons, chez Deuxfleurs, notre instance Forgejo, actant ainsi l’arrêt des règles iptables précédemment introduites. Nous instaurons cependant un robots.txt restrictif. Dans un premier temps, cela semble fonctionner, mais il n’est pas encore possible de dire si c’est parce qu’Alibaba a arrêté son indexation, ou si c’est grâce au robots.txt. Ci-dessous le graphe d’utilisation du processeur sur la machine hébergeant notre Forgejo, la différence est nette entre avant et après cette date.

Le 2 mars 2025, sdomi annonce sur le fédivers avoir bloqué l’intégralité des IP d’Alibaba Cloud, pour la même raison que chez Deuxfleurs : son instance Forgejo se voit surutilisée à cause d’eux et sature régulièrement son système à base de Ryzen 9 7950X3D. Ils ont provoqué la génération de 9Go de journaux et 230Go d’archives. Le même jour, TooTech répond en expliquant qu’il subissait le même phénomène, et a mis en place des redirections occasionnelles vers des pages abordant le sujet des manifestations de la place Tian’anmen. Suite de quoi les indexeurs auraient disparu après 12 heures.

Le 4 mars 2025, Jade Ellis annonce sur son journal que son instance Forgejo subit des abus de la part d’indexeurs depuis le 19 février. Elle explique que mettre en place un robots.txt plus strict a résolu le problème.

Le 8 mars 2025, l’instance Forgejo de Deuxfleurs a complètement rempli son disque et a une forte charge processeur, à cause encore une fois des indexeurs IA d’Alibaba. Ils provoquent des générations d’archives en boucle. Ceux-ci se seraient donc réveillés de nouveau et ne respecteraient pas le robots.txt. Nous remettons en place des règles iptables au niveau du service Forgejo similaires à celles du 12 février (mais concernant deux /16 au lieu de tout un /13, cela dit), et rajoutons une règle au niveau du serveur Nginx faisant office de proxy inverse, pour ignorer les requêtes vers les chemins d’archives.

Le 8 mars 2025, le même jour par coïncidence, la @lacontrevoie annonce sur le fédivers avoir son instance Git mise à mal par une vague de robots chinois utilisant jusqu’à 3500 adresses IP différentes chaque minute.

Voilà l’ensemble des éléments connus à ce jour. N’hésitez pas à renvoyer les gens n’étant pas au courant du problème vers ce topic pour qu’ils puissent se renseigner.

6 Likes

Bonjour tout le monde,

Merci Vincent de mettre en lumière le problème.

Pour notre part, voilà quelques éléments d’analyse.

Diagnostic

Analyse du trafic

Ci-dessus : capture de Grafana, avec un focus sur l’usage de Gitea.

On a identifié deux formes d’attaques :

  1. du crawling passif : assez intense mais encore supportable, comme on peut le voir de 06h55 à 08h30 ;
  2. du crawling agressif : un raid de crawlers qui déboule d’un coup, (comme c’est arrivé à 08h30) avec ~3500 IPs différentes en une seule minute : quand ça se produit, Gitea se coupe immédiatement car PostgreSQL arrive au maximum de connexions simultanées qu’il peut lui donner. Le service a été redémarré à 09h30.

Dans les deux cas : de très nombreuses IPs différentes sont utilisées, rendant nos mécanismes de défense habituels (reaction/fail2ban) peu efficaces.

Analyse des IPs

Cette capture a été réalisée avec le logiciel d’analyse GoAccess avec la commande suivante :
goaccess ~/spam-raw.txt --log-format=COMBINED --exclude-ip=<monitoring> --enable-panel=ASN --geoip-database=dbip-asn-lite-2025-03.mmdb

  • spam-raw.txt représentant 1h35 de logs (de 06h55 à 08h30 sur notre service), dont le raid de 08h30 (1 minute) ainsi qu’un autre raid à 11h28 (1 minute).
  • la BDD des ASN pouvant être récupérée gratuitement sur DB-ip ;

Réflexion sur des contremesures

On constate que la majorité du trafic encaissé provient des serveurs cloud de Alibaba et Huawei, mais une part non négligeable du trafic provient d’autres acteurs (Tencent, China Mobile, China Unicom, Chinanet…) ce qui laisse penser qu’il pourrait s’agir de blocs contenant des IPs résidentielles.

  • Un géoblocage de toutes les IPs chinoises serait embêtant, car cela pourrait empêcher à des utilisateur·ices légitimes potentiel·les d’accéder à notre service ;
  • Il faudrait bannir de très nombreuses IPs et il est probable que les IPs que nous connaissons ne reflètent qu’une petite partie de leur pool d’IP totale.

Solutions en place

Crawling passif : filtres avec reaction/fail2ban

Cette solution est déjà en place chez nous depuis pluiseurs semaines et fonctionne plutôt bien. Elle consiste à bannir les IPs pendant plusieurs jours si elles effectuent un certain nombre de requêtes dans un temps donné.
Ces filtres s’appliquent sur toutes les IPs et cible spécifiquement les requêtes réalisées par ces crawlers.

        gitea: {
          regex: [
            @'^<ip> .* "GET \/user\/login\?redirect_to.*',
          ],
          retry: 15,
          retryperiod: '48h',
          actions: banFor("gitea_simple"),
        },
        gitea_harder: {
          regex: [
            @'^<ip> .* "GET \/user\/login\?redirect_to.*',
            @'^<ip> .* "GET \/[^\/]*\/[^\/]*\/(?:raw\/|src\/|rss\/|blame\/|commits\/|find\/)?(?:commit\/|branch\/|pulls\?|issues\?|compare\/)',
          ],
          retry: 80,
          retryperiod: '48h',
          actions: banFor("gitea_harder"),

Le filtre gitea_simple : si vous consultez https://git.lacontrevoie.fr/user/login?redirect_to=%2fexplore%2frepos 15 fois en l’espace de 48h, votre IP sera bannie une semaine. Un·e utilisateur·ice clique rarement 15 fois sur la page de login ; cela dit, nous allons progressivement essayer d’augmenter cette limite car elle reste très basse et pourrait déclencher des faux positifs.

Le filtre gitea_harder : on cible plus largement les routes récupérées par les bots. Il y a plus de chances qu’elles soient consultées par des personnes humaines, ce pourquoi la limite est beaucoup plus haute (80 essais).

Le fait que de nombreuses IPs soient utilisées nous oblige à définir la plage de détection à 48h.

Crawling agressif : ratelimit avec Caddy

Nous utilisons le plugin caddy-ratelimit du serveur HTTP Caddy pour appliquer un rate limit spécifiquement sur les IPs de Alibaba et Huawei. Ce rate limit est partagé entre leur pool d’IPs : toutes les requêtes venant de leurs serveurs sont comptabilisées ensemble.

Obtention des blocs d’IP de Alibaba et Huawei

Autonomous System Lookup (AS / ASN / IP) | HackerTarget.com → saisir AS45102 et AS136907, et récupérer leur plage d’IPs. On connaît leurs ASN grâce à GoAccess utilisé plus haut (et parce qu’il s’agit d’une information publique).

https://cidr-aggregator.pages.dev/ → coller l’intégralité de leurs plages d’IP. L’outil nous fusionne les blocs d’IP qui peuvent aller dans un même bloc CIDR.

Dans le Caddyfile de Gitea :

    rate_limit {
        zone sta_baba {
                match {
                        path_regexp \/[^\/]*\/[^\/]*\/(?:raw\/|src\/|rss\/|blame\/|commits\/|find\/)?(?:commit\/|branch\/|pulls\?|issues\?|compare\/)
                        client_ip 1.178.32.0/20 1.178.48.0/20 101.132.174.144/32…
                }
                key sta_baba_k
                events 10
                window 60s
        }
        log_key
        jitter 20.0
    }
  • Le paramètre client_ip a été tronqué car il fait 3 kilomètres. Il représente tous les ranges d’IP en notation CIDR séparés par un espace, je n’ai pas trouvé de façon plus élégante de le noter.
  • La configuration actuelle permet 10 requêtes pour 60 secondes, pour l’ensemble de ces IPs. C’est pas beaucoup, mais c’est pour tester ; on augmentera par la suite si ça marche bien.
  • Point d’amélioration : ne définir ce rate limit que sur les requêtes utilisées par les bots (voir le regex dans Reaction). Car là, rien qu’en comptant les assets pour charger une page, on les atteint très vite, les 10 requêtes… EDIT: appliqué à l’aide de path_regexp.
  • Point d’amélioration 2 : récupérer les codes HTTP 429 renvoyées par Caddy dans un filtre avec Reaction pour bannir plus rapidement les raids.

Cette configuration nous permet de nous prémunir du crawling agressif en provenance des IPs de Alibaba / Huawei sans pour autant bannir toutes leurs IPs, ce qui devrait couvrir 75% des requêtes reçues (les 25% restants proviennent de China Unicom, China mobile et les autres).

Si cette configuration n’est pas suffisante, on pourra mettre en place un deuxième rate limit, plus tolérant, sur les IPs de China Unicom et les autres. Plus tolérant car il y a beaucoup plus de chances que des IPs résidentielles s’y trouvent que sur les serveurs Alibaba/Huawei.

Autre mitigation importante conseillée : définir une limite de connexions à la BDD PostgreSQL pour l’user de Gitea, surtout si vous partagez votre BDD avec d’autres services, sinon Gitea va saturer PostgreSQL avant de crash lui-même.
Comme ceci : ALTER ROLE gitea_db_user CONNECTION LIMIT 50; (modifiez le nom de l’user et le nombre de connexions).

On a mis le rate limit en place ce matin. Je vous dirai si ça marche.

EDIT 10/03 01h57: Mise à jour du regex pour inclure d’autres pages habituellement listées par les bots, et ajout du regex de Reaction dans Caddy pour n’appliquer le rate limit que sur certaines routes.

9 Likes

Merci d’avoir lancé le sujet. Merci aussi @neil pour la solution du rate-limiting qui me semble être une bonne solution.
Sur ma forge personnelle j’ai aussi subit ce genre de crawling agressif de la part d’Alibaba, j’ai simplement mis ma forge derrière une allowlist et ajoute les IPs ou les ranges à mesure que ça m’est demandé et quand c’est légitime mais c’est clairement une solution temporaire. Je pense que je vais mettre en place le rate-limiting en gardant dans un coin l’allowlist en cas de coup dur.

Sur mes sites web perso, je bannis les indexeurs d’IA avec reaction à partir des UserAgent. J’ai documenté ça dans le wiki de reaction : AI crawlers (ChatGPT...) - Reaction wiki
Mais je suppose qu’AliBaba ne met pas d’UserAgent customisé pour se fondre dans la masse ?

2 Likes

J’imagine que des bots qui ne respectent pas le robots.txt utilisent aussi un user agent de navigateur web.
J’ai l’impression qu’une solution serait un système à la Anubis comme mentionné par @Vincent (challenge SHA1 comme pour les blockchains).
Mais ça saoule parce qu’il y a aussi des scraping légitimes.
Peut être le honey pot est plus raisonnable.

J’ai développé et testé une solution similaire à Anubis pour de l’hébergement mutualisé, sauf que ça rajoute du rate-limit en amont pour ne pas avoir l’écran de proof of work systématiquement, qui ne fonctionne qu’avec javascript : LocalSec: LocalSec

1 Like

Quelques jours après : je vous confirme que le rate limit fonctionne bien, les serveurs Alibaba/Huawei vont continuer à représenter une grande partie de notre trafic (peut-être encore 40~70%) mais ils ne constituent plus une menace pour la stabilité du service, pour l’instant.

J’ai mis à jour le regex pour inclure d’autres pages.

Bonjour à tous,

Tout ça me fait dire que ce que j’avais pris pour des attaques étaient peut être des Crawlers : Bloquer attaque http, ip multiple - #24 par kepon (solution Crowdsec)

Merci pour ce partage !
David

Bonjour, question de néophyte : qu’est-ce qu’un indexeur d’IA et à quoi cela sert-il ? Sont-ce des crawlers qui récupèrent des données pour nourrir des IA pour leur phase d’apprentissage ? Si oui, pourquoi « attaquent »-ils en masse ? Ils ne devraient avoir besoin que d’un seul passage ?

Ceci dans le but d’entrevoir des solutions plus politiques que techniques.

1 Like

Oui, indexeur est une traduction française de crawler. C’est effectivement eux qui essayent de capturer le maximum de données sur le web pour entraîner des intelligences artificielles. On peut aussi parler de robot si l’on veut.

Pour obtenir les performances des IAs que l’on a aujourd’hui, on estime que les entreprises qui les développent exploitent d’ores et déjà à peu près tout ce qui est accessible publiquement sur internet. On peut penser que l’agressivité des indexeurs provient notamment de là : il leur faut explorer encore plus en profondeur que ce qu’ils font déjà.

La raison majeure est cependant certainement plus liée à une large incurie de la part des entreprises qui les développent. Pour explorer le web, un robot « clique » sur tous les liens qu’il trouve, dans l’espoir de trouver de nouvelles pages. Il y a des mesures simplistes qui permettent d’éviter de réitérer trop de fois sur la même page; elles fonctionnent bien sur les sites web statiques comme les blogs par exemple. Mais elles fonctionnent mal sur les services dynamiques, qui proposent plein de boutons et de liens pour faire réaliser un travail au serveur. C’est le cas des forges Git tels que Gitea, Gitlab et Forgejo. Tu as plein de liens pour explorer plein de commits, plein de fichiers et plein de branches différents du même projet. Tu as plein de boutons pour que le serveur te génère des archives d’un projet ou fasse des actions liées à l’intégration et au test continus. Les robots ont du mal à voir qu’il s’agit d’actions redondantes, donc dans le doute ils cliquent et ils capturent à tout va. Et ton serveur mouline à fond pour répondre à toutes les requêtes.

Je serais prudent avec le vocabulaire martial (« attaque », « offensive »…), justement parce qu’en réalité, on a surtout à faire à des gigantesques entreprises avec des gigantesques moyens qui tapent dans toutes les ressources qu’ils trouvent dans la plus grande insouciance. Sans volonté délibérée de nuire, donc, mais avec des conséquences réelles à leur négligence, cependant.

1 Like

En soit, corrige-moi Vincent si je me trompe, mais je ne crois pas que nous ayons d’indication tangible que les crawlers sont bel et bien utilisés pour entraîner des IA. Il pourrait complètement s’agir d’un moteur de recherche, d’un annuaire, d’un outil d’archivage, d’analyse…

Hormis le fait, évidemment, que l’IA soit la tendance en ce moment et qu’il s’agit de l’un des usages probables.
(Pas pour faire l’avocat du diable de l’IA, mais pour éviter d’éventuels gros titres tendancieux sur le fedivers du style « les gentils petits CHATONS sont attaqués par les méchantes IA !! » :sweat_smile:)

Oui tu as tout à fait raison. D’ailleurs on peut peut-être même dire que les requêtes qui viennent d’Alibaba Cloud, si elles proviennent effectivement de leurs centres de données, sont en réalité missionnées par d’autres entreprises qui ne font que louer les infrastructures d’Alibaba à des fins complètement arbitraires.

On a alors certainement une double incertitude : à la fois sur les raisons, que sur les acteurs réels derrière.

Merci pour les précisions, c’est quand je lis qu’il s’agit de milliers d’IP différentes qui requêtent un même serveur que je tique. Je me dis que ça ne peut pas être un hasard dû au grand nombre de services, IA ou pas, lancés en même temps…?

De ce que je comprends c’est majoritairement ByteDance, société mère de TikTok, dont les applis installées sur les téléphones des utilisateurs servent à faire des DDOS, officiellement c’est juste du crawling, mais comme on l’a vu c’est des gros volumes qui mettent à genoux les serveurs.

En gros l’appli mobile reçoit des commandes du service central pour aller crawler des pages, et renvoyer le contenu au service central, probablement pour de l’IA. Le but est bien sûr de contourner les blocages anti-robots, notamment le rate limiting. Et c’est pour ça qu’on voit des tonnes d’IP. Il y a des IP qui correspondent à des serveurs, mais d’autres qui correspondent à des IP mobiles ou résidentielles…

À ce stade il est compliqué de lutter à moins de bloquer toute la Chine…

Ah tiens, tu as une source sur ce sujet ? Merci :smiley_cat:

1 Like

Un mail courtois adressé à abuse des AS concernés pourrait être une façon conviviale de signaler ces usages indélicats.
À titre personnel, je me retrouve régulièrement confronté à des HTTP 429 Too Many Request sans avoir pratiqué un DDOS.

1 Like

Sur mes serveurs, le plus grand et nuisible rzo d’IPs est celui de Bytedance.
Leur bot d’IA se contrefiche des robots.txt, j’ai une liste de plus de 10000 adresses IP mis automatiquement dans un ipset DROP grace à un petit script bash qui passe sur le log Apache.

1 Like

Si chaque hébergeur fait ça (écrire à l’AS concerné), ça peut peut-être produire un petit effet. Si on (enfin vous) se synchronise c’est crédible non ? Ne serait-ce que pour faire respecter le robots.txt.

(oui je crois encore en un internet plus ou moins fonctionnel, laissez-moi)

1 Like

Juste des posts sur des forums, et mon constat personnel de voir l’UAs de ByteDance venir d’IP résidentielles en Chine en masse si je commence à bloquer leurs IP et Alibaba…

Nouveau raid ce matin, 2944 requêtes par 2903 IPs différentes en l’espace d’une minute.

Cette fois, c’est le Brésil. :woman_shrugging:

À ce stade, même bloquer par IP blocks d’AS ne sert plus à rien…
Je pense que je vais mettre en place un rate limit global sur toutes les routes qui ne sont pas des assets, quand j’aurai un peu de temps.

EDIT : Rate limit ajouté, il limite à 200 le nombre total de requêtes pouvant être traité par Gitea en 30 secondes, toutes IP confondues, uniquement sur les routes à contenu dynamique (pas les assets). C’est déjà beaucoup, on verra si on peut diminuer encore.