LINUX:HTTP: Robots
→ retour au menu du serveur Web
But
L'activité des Robots sur Internet devient de plus en plus intense spécialement ceux liés à la récolte d'informations pour nourrir l'IA.
Ils pénalisent l'activité des petits serveurs.
L'activité en est multipliée facilement par 10 et les transferts réseaux par 100. Celle-ci est souvent le fait de deux ou trois robots.
Cette croissance d'activité réseau peut être détectée via la commande de ligne:
ifconfig
En comparant les chiffres d'un jour à l'autre, on peut mesurer ce trafic.
En ce qui concerne l'ampleur des requêtes et la liste des robots présents parmi elles, il suffit d'analyser la rubrique HTTPD du rapport journalier du service LogWatch.
Analyse
Se pose la question de réguler leur présence, spécialement les plus gourmandw.
Pour se faire, on a créé un script qui analyse journellement leur activité.
Il est basé sur l'analyse du fichier journal d'Apache "/var/log/httpd/access_log".
Format du journal du service Httpd
Comme le script est basé sur l'analyse du journal 'Apache, il faut connaitre son format.
Ce format est défini classiquement dans le fichier de configuration de base du service Httpd "/etc/httpd/conf/httpd.conf".
Le nom du fichier journal et le format qui lui est lié se retrouve sous l'option "CustomLog". Voici un exemple donné par défaut:
CustomLog "logs/access_log" combinedio
Nous retrouverons le type de format "combinedio" dans l'option suivante.
L'option qui définit les zones reprises dans le journal des accès, se nomme "LogFormat".
Voici un exemple classique que nous utilisons (avec quelques ajouts selon les besoins):
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O %p %v " combinedio
Nous retrouvons le type de format "combinedio" en fin de ligne.
Voici un descriptif des zones utilisées ci-dessus:
- %a : adresse IP de la machine distante
- %l : nom de connexion distante (non utilisé)
- %u : utilisateur distant (non utilisé)
- %t : date (au format anglais)
- \"%r\" : 1ère ligne de requête
- %>s : statut final de la requête
- %b : taille de la réponse en octets
- \"%{Referer}i\" : variable Referer
- \"%{User-Agent}i\" : variable User Agent
- %I : nombre d'octets reçus
- %O : nombre d'octets envoyés
- %p : port du serveur (80 ou 443)
- %v : nom du serveur (ServerName)
Il y en a d'autres que l'on peut trouver sur le site d'Apache.
Voici un exemple de sortie dans le journal:
52.167.144.184 - - [11/Dec/2025:00:05:49 +0100] "GET / HTTP/2.0" 200 2581 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/116.0.1938.76 Safari/537.36" 233 2811 443 laplanchedenvol.be
Nous allons filtrer le journal selon la date du jour, dans l'exemple: "11/Dec/2025".
C'est dans la zone "User Agent" que l'on trouvera le nom du robot. Dans l'exemple ci-dessus, nous trouvons "bingbot".
Nous pourrons valider le rejet des requêtes de certains robots via la zone du statut de la requête. On rencontrera le plus souvent trois catégories:
- les 200 pour les requêtes validées
- les 300 pour les redirections, utilisées principalement, dans notre cas, pour rediriger les requêtes non cryptée (port 80 - HTTP) vers des cryptées (port 443 - HTTPS) ou la réorientation un DNS vers un autre DNS
- les 400 pour les requêtes rejetées suite par exemple à une URL non trouvée ou à un refus d’autorisation
Liste des robots
On constitue un fichier texte reprenant la liste des robots. Ce fichier nommé "bot.txt" se trouvera dans le même répertoire que le script.
Voici un exemple de contenu:
AhrefsBot aiohttp Amazonbot Applebot Barkrowler bingbot BitSightBot Bytespider CensysInspect ChatGPT-User ClaudeBot cypex.ai DataForSeoBot DotBot DuckDuckBot facebookexternalhit Googlebot GPTBot MercuryLeads meta-externalagent MJ12bot OAI-SearchBot OpenTheBoxBot PerplexityBot PetalBot Qwantbot SeekportBot SemrushBot SERankingBacklinksBot TerraCotta YandexBot ZoominfoBot
Cette liste n'est pas exhaustive. Amendez-la au fur et à mesure de la présence de nouveaux venus.
Répertoire du script
Nous avons l'habitude de regrouper tous nos scripts personnels utilisés via ce service Cron dans le répertoire "/application/cron". Nous y créons un sous répertoire "bot".
Répertoire de travail
Dans le répertoire ("/application/cron/bot") où se situe le script "bot.bat" et le fichier "bot.txt", on crée un sous-répertoire "log" qui accueillera les fichiers de traitements du script.
Script
Voici le contenu du script ("bot.bat"), à adapter selon vos besoins:
#!/bin/bash
##########################################
#
# Détection de la fréquence des bots qui accèdent à notre site Web
#
##########################################
#
# A adapter selon vos besoins
#
CHEMINBASE="/application/cron/bot"
##########################################
CHEMIN="$CHEMINBASE/log"
cd $CHEMIN
# Nettoyage
rm -f *.log
rm -f *.sor
# Date du jour au format anglais standard
LANG=C
DATE=`date +%d/%b/%Y `
echo "Date du jour: $DATE"
# Sélection des enregistrements du jour dans les journaux d'Apache
grep "\[$DATE:" /var/log/httpd/access_log > jour.log
# Sélection du contenu intéressant
awk -F '" ' '{printf("%s \t %s\n",$2,$3)}' jour.log > tot.log
# Sélection selon les codes
grep "^2" tot.log > 200.log
grep "^3" tot.log > 300.log
grep "^4" tot.log > 400.log
cat 200.log 300.log > 200300.log
# Liste des codes utilisés
awk '{printf("%s\n",$1)}' tot.log > code.log
sort -u code.log > code.sor
rm -f code.log
echo ""
echo "Codes"
echo "-----"
LISTECODE=`cat code.sor`
for CODE in ${LISTECODE}
do
echo -n "code: $CODE - "
grep "^$CODE" tot.log | wc -l
done
echo -n "Total - "
NBS=`wc -l tot.log| awk '{printf("%s\n",$1)}'`
echo $NBS
# Liste des Bots à repérer
LISTEBOT=`cat $CHEMINBASE/bot.txt`
echo ""
echo "Bot (tous les codes)"
echo "--------------------"
for BOT in ${LISTEBOT}
do
NBS=`awk -F "\t" '{printf("%s\n",$2)}' tot.log | grep "$BOT" | wc -l`
echo -ne "$NBS\t : "
echo $BOT
grep "$BOT" tot.log >> bot.log
done
echo ""
echo "Bot (codes 200 et 300)"
echo "----------------------"
for BOT in ${LISTEBOT}
do
NBS=`awk -F "\t" '{printf("%s\n",$2)}' 200300.log | grep "$BOT" | wc -l`
echo -ne "$NBS\t : "
echo $BOT
done
echo ""
echo "Bot (codes 400)"
echo "---------------"
for BOT in ${LISTEBOT}
do
NBS=`awk -F "\t" '{printf("%s\n",$2)}' 400.log | grep "$BOT" | wc -l`
echo -ne "$NBS\t : "
echo $BOT
done
# Liste des User-Agents
awk -F '\t' '{printf("%s\"\n",$2)}' tot.log > trav.log
sort -u trav.log > agenttot.log
awk -F '\t' '{printf("%s\"\n",$2)}' bot.log > trav.log
sort -u trav.log > agentbot.log
rm -f trav.log
comm -23 agenttot.log agentbot.log > agentautre.log
Il est à faire remarquer que ce script est spécialement conçu pour le format d'Apache présenté ci-dessus, spécialement pour les zones "%t", "%>s" et "\"%{User-Agent}i\"".
Le résultat s'affiche à l'écran ou dans un mail de gestion du système (user: root) lors de son exécution via le service Cron.
En début, on sélectionne les enregistrements selon la date du jour.
Ensuite vient le nombre de requête par code de statut.
Enfin viennent les fréquences des requêtes faites par les robots recensés par grandes catégories de statuts.
En fin de script, des listes des User Agents sont créées. On peut les consulter dans le sous-répertoires "/application/cron/bot/log":
- agenttot.log : ensemble des User Agents
- agentbot.log : ensemble des User Agents des robots répertoriés dans le fichier "bot.txt"
- agentautre.log : ensemble des User Agents autres
Dans ce dernier, vous pourrez repérer les robots non encore répertoriés.
Cron
Nous allons utiliser ce script en fin de journée de façon systématique afin d'analyser un maximum de requêtes de cette journée. Pour cela, nous utilisons le système "Cron".
Nous ajoutons la ligne suivante dans le fichier "/etc/crontab":
# BOT 59 23 * * * root /application/cron/bot/bot.bat
Filtrage sous Apache
Il existe divers moyens de filtrer les requêtes provenant de robots.
Les premières utilisent la méthode "RewriteEngine" à placer dans les fichiers de configuration d'Apache soit dans les fichiers ".htaccess" directement dans les scripts du site concerné.
Nous utiliserons une troisième méthode utilisant les variables d'environnement d'Apache et le module "mod_authz_core.c" dans les fichiers de configuration d'Apache.
On les place à l'intérieur des balises "<Directory>" et "</Directory>".
Voici un exemple de fichier de configuration classique:
Alias /wordpress /web/wordpress
<Directory /web/wordpress>
Options +FollowSymLinks -Indexes
AllowOverride All
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
Nous désirons refuser l'accès à ce répertoire pour quatre robots: Amazonbot, ClaudeBot, SemrushBot et GPTBot.
Nous ajoutons la variable d'environnement "pasderobot" qui analyse le "User-Agent" et y détecte la présence d'un de ces quatre robots. Et c'est en leur absence que l'accès est autorisé.
Voici les modifications apportées:
Alias /wordpress /web/wordpress
<Directory /web/wordpress>
Options +FollowSymLinks -Indexes
AllowOverride All
SetEnvIfNoCase User-Agent (Amazonbot|ClaudeBot|SemrushBot|GPTBot) pasderobot
<IfModule mod_authz_core.c>
<RequireAll>
Require all granted
Require not env pasderobot
</RequireAll>
</IfModule>
</Directory>
Il faut évidemment relancer le service concerné:
systemctl restart httpd.service
→ retour au menu du serveur Web