Table des matières

Bloquer les robots crawlers non souhaités

Pourquoi ?

Les robots d'exploration (crawlers) peuvent devenir les principaux consommateurs de ressources1) d'un serveur hébergeant des sites web. Le but poursuivi dans cette fiche est de bloquer les robots non souhaités (indésirables) tout en laissant les autres parcourir et indexer les sites visés.

Dans le cas traité, on souhaite bloquer deux types d'indésirables :

Identification

À la différences d'autres fauteurs d'accès non souhaité 3), les crawlers font des requêtes légitimes4) qui ne déclencheront aucun avertissement.

Parasites

Les parasites se comportent ouvertement comme des crawlers :

On en vient à les considérer comme parasites parce qu'on ne retire aucun bénéfice de l'exploration à laquelle ils se livrent tout les laissant consommer les ressources nécessaires à leur exploration.

Usurpateurs

Les usurpateurs se comportent eux aussi comme des crawlers mais dissimulent leur activité derrière de faux identifiants identiques à un service connu.

Leur qualification d'usurpateurs ne découle pas à une appréciation subjective mais du constat qu'ils ne sont pas qui ils prétendent être.

Également non souhaités

Une troisième catégorie, non détaillée ici, réunit les attaquants en [D]DOS qui se font passer pour l'une ou l'autre des deux autres catégories.

Mise en œuvre

L'environnement de référence pour cette fiche est Debian 12, dans une configuration web s'appuyant sur Apache2, avec les paquetages fournis pas la distribution.

Les techniques présentées ici ne font pas appel à des outils sophistiqués ni dédiés. Elles s'appuient sur deux outils basiques : Fail2ban7) et Apache2.

Parasites

La détection des parasites est confiée à Fail2ban. Cela signifie 3 choses.

  1. La détection s'appuie sur les journaux d'Apache et ne peut donc intervenir qu'après coup, c'est-à-dire à partir d'un événement renseigné dans un journal.
  2. Le blocage s'applique à toute requête émise depuis l'IP d'origine, pas uniquement les requêtes web traitées par Apache (effet de bord)
  3. Le blocage être persistant, de quelques secondes à toujours.

En pratique : Le filtre de base utilisé est apache-badbots, disponible dans /etc/fail2ban/filter.d Il est épaulé par un filtre dérivé permettant de construire sa propre liste de parasites qui complète celles des parasites recensés par la communauté8). Une règle (jail) spécifique précise le journal à analyser et les conditions de bannissement9).

Contenu du fichier de filtre dérivé apache-badbots-me.local, ajouté dans le répertoire /etc/fail2ban/filter.d :

# Fail2Ban configuration file
#
# Regexp to catch known spambots and software alike. Please verify
# that it is your intent to block IPs which were driven by
# above mentioned bots.
#
# Ajout de robots indésirables et correction de l'expression régulière
[INCLUDES]

before = apache-badbots.conf

[Definition]

mebotcustom = Bytespider|MJ12bot

failregex = ^<HOST> -.*(GET|POST|HEAD).*HTTP.*(?:%(badbots)s|%(badbotscustom)s|%(mebotcustom)s)

Section ajoutée au fichier /etc/fail2ban/jail.local :

[apache-badbots-me]
enabled = true
backend = auto
port     = http,https
logpath = %(apache_access_log)s
        /var/log/virtualmin/*_access_log
bantime  = 48h
maxretry = 1

Usurpateurs

Sources :

La détections de usurpateurs est confiée au module mod_authz_host d'Apache2. Cela a 2 conséquences :

  1. le blocage se fait dès l'analyse de la requête par Apache,
  2. les blocages ne sont pas persistants : on bloque à chaque fois, autant de fois que la requête est émise10).

Si les usurpateurs émettent des requêtes très ressemblantes à celles des crawlers qu'ils imitent, ils le font depuis des IPs «non légitimes». Cela suppose que le moteur de recherche original (par exemple, Google ou Bing) fournit un moyen d'identifier les IPs légitimes depuis lesquelles opèrent leurs crawlers (resp. Googlebot et bingbot).

Deux principaux moyens d'identification sont généralement fournis :

  1. une liste d'IPs légitimes (susceptible de mise à jours permanentes)
  2. les noms de domaines parents auxquels sont associés les IPs légitimes (resp. google.com ou googlebot.com et search.msn.com).

Le dernier moyen évite d'avoir à suivre la mise à jour des IPs légitimes et peut être exploité à travers de banales requêtes DNS.

Concrètement, on ajoutera les directives suivantes en tête de la section directory du répertoire de base du site :

<If "%{HTTP_USER_AGENT} =~ /Googlebot/ && ! -n %{HTTP:X-FORWARDED-FOR}">
  Require host .google.com .googlebot.com
</If>

<If "%{HTTP_USER_AGENT} =~ /bingbot/ && ! -n %{HTTP:X-FORWARDED-FOR}">
  Require host .search.msn.com
</If>

Explicitation

Les deux règles de filtrages sont similaires. On peut expliciter la seconde comme suit :

si l’auteur de la requête prétend être un "bingbot"
  alors
     le reverse de l'IP d'origine doit avoir pour domaine parent "search.msn.com"
    et
     ce reverse doit pointer sur l'IP d'origine.
finsi

La sous-expression contenant “HTTP:X-FORWARDED-FOR” n'éclaire pas notre propos. Elle est néanmoins nécessaire pour traiter correctement le cas où la requête transite par un Réseau de Diffusion de Contenu (RDC ou CDN).

Extension

Cette technique est facilement applicable à d'autres crawlers dont on souhaite tester l'identité. Par exemple, Apple fournit les indications permettant d'authentifier l'Applebot. On en tire la règle suivante :

<If "%{HTTP_USER_AGENT} =~ /Applebot/ && ! -n %{HTTP:X-FORWARDED-FOR}">
  Require host .applebot.apple.com
</If>
1)
Processeur, bande passante…
2)
Au sens où la plupart des responsables web souhaitent leur visite : Google, Bing, Yahoo!…
3)
Hackers, notamment.
4)
Pas d'erreur d'authentification, de pages inexistantes découlant d'une recherche plus ou moins aléatoire de fichiers pouvant servir de porte d'entrée, etc.
5)
Ce qui ne veut pas dire qu'ils en respectent les directives.
6)
Comme le feraient des attaquant en DOS.
7)
Donc iptables, donc Netfilter.
8)
Et mise à jour avec le paquetage.
9)
Sachant que bannir l'IP d'origine est l'action par défaut de Fail2ban.
10)
Sauf traitement de ces blocages répétés par un autre moyen ;-)