Robots d'IA avec Apache 2.4 - robots.txt, .htaccess, Require not env et plages IP
Refuser les robots d'entraînement avec Apache 2.4 via .htaccess, mod_setenvif ou mod_rewrite, et n'accepter les robots de recherche que depuis leurs plages IP.
Apache HTTP Server offre plusieurs façons de traiter les robots d'IA, selon l'accès dont vous disposez : un simple fichier .htaccess sur un hébergement mutualisé, ou la configuration complète de l'hôte virtuel sur votre propre serveur. Ce guide couvre les deux, avec la même politique que nos autres guides : refuser l'entraînement, laisser passer les robots de recherche de ChatGPT, Claude et Perplexity, et, quand c'est possible, refuser ceux qui empruntent leur nom sans venir des adresses de leur éditeur. Toutes les configurations ci-dessous ont été validées avec httpd -t puis par des requêtes réelles sur Apache 2.4.69 (compilation Windows d'Apache Lounge) ; la syntaxe est celle d'Apache 2.4, et une section dédiée résume ce qui change par rapport à la 2.2.
robots.txt reste la base
Le fichier se place à la racine du site (le DocumentRoot). C'est lui qui exprime vos choix auprès des robots qui les respectent, et le seul moyen de refuser l'entraînement à Google (Google-Extended) ou à Apple (Applebot-Extended) : ces jetons ne correspondent à aucun robot distinct, donc aucune règle serveur ne peut les viser. Un robots.txt refusé en 403 empêche le robot d'y lire votre refus, et la RFC 9309 assimile une erreur 5xx sur ce fichier à une interdiction totale : chaque configuration ci-dessous exclut donc /robots.txt du blocage.
Version .htaccess avec mod_setenvif
C'est la méthode recommandée en 2.4 : SetEnvIfNoCase pose une variable d'environnement quand le User-Agent correspond, puis Require not env refuse les requêtes qui la portent.
# .htaccess à la racine du site - Apache 2.4
# Nécessite : AllowOverride FileInfo (SetEnvIf) et AuthConfig (Require, AuthMerging)
# 1. Robots refusés (ici : entraînement ; à adapter). Recherche insensible à la casse.
SetEnvIfNoCase User-Agent "GPTBot" refus_ia
SetEnvIfNoCase User-Agent "ClaudeBot" refus_ia
SetEnvIfNoCase User-Agent "CCBot" refus_ia
SetEnvIfNoCase User-Agent "Bytespider" refus_ia
SetEnvIfNoCase User-Agent "meta-externalagent" refus_ia
# 2. robots.txt reste lisible par tous : on retire la variable
SetEnvIf Request_URI "^/robots\.txt$" !refus_ia
# 3. Combiner avec les règles d'accès déjà définies au-dessus (ET logique)
AuthMerging And
# 4. Tout le monde, sauf les requêtes marquées
<RequireAll>
Require all granted
Require not env refus_ia
</RequireAll>
Trois détails comptent. Un Require not ne peut jamais autoriser seul une requête : la documentation d'Apache impose de l'associer à une condition positive, ici Require all granted, dans un bloc <RequireAll>. Ensuite, sans AuthMerging And, les règles d'accès d'un .htaccess remplacent celles des sections parentes : un Require all granted posé à la racine pourrait rouvrir un site que la configuration du serveur limitait, par exemple à certaines adresses. Enfin, les directives d'un .htaccess ne sont lues que si AllowOverride le permet ; depuis Apache 2.4, sa valeur par défaut est None.
Version .htaccess avec mod_rewrite
Si mod_rewrite est déjà utilisé sur le site, ou si l'hébergeur n'autorise pas AuthConfig, la même règle s'écrit ainsi :
# .htaccess - variante mod_rewrite (AllowOverride FileInfo suffit)
RewriteEngine On
# Ne jamais bloquer robots.txt
RewriteCond %{REQUEST_URI} !^/robots\.txt$
# [NC] : comparaison insensible à la casse
RewriteCond %{HTTP_USER_AGENT} (GPTBot|ClaudeBot|CCBot|Bytespider|meta-externalagent) [NC]
# [F] : réponse 403 Forbidden, fin du traitement des règles
RewriteRule ^ - [F]
Lors de nos essais, les deux variantes donnaient le même résultat : 403 pour gptbot et CCBot, 200 pour GPTBot sur /robots.txt, 200 pour OAI-SearchBot et pour un navigateur.
Configuration serveur avec vérification des plages IP
Sur votre propre serveur, on peut aller plus loin : n'accepter un robot de recherche que s'il vient des plages publiées par son éditeur. Les listes d'adresses vivent dans des fichiers séparés, générés par un script, et sont incluses dans l'hôte virtuel.
# Dans <VirtualHost *:443> - Apache 2.4.16 ou plus récent
# Modules : setenvif, authz_core, authz_host, log_config
# 1. Éditeur revendiqué par le User-Agent
SetEnvIfNoCase User-Agent "GPTBot|OAI-SearchBot|ChatGPT-User" editeur_ia=openai
SetEnvIfNoCase User-Agent "ClaudeBot|Claude-SearchBot|Claude-User" editeur_ia=anthropic
SetEnvIfNoCase User-Agent "PerplexityBot|Perplexity-User" editeur_ia=perplexity
# 2. Robots refusés par principe (entraînement), sauf sur robots.txt
SetEnvIfNoCase User-Agent "GPTBot|ClaudeBot|CCBot|Bytespider|meta-externalagent" refus_ia
SetEnvIf Request_URI "^/robots\.txt$" !refus_ia
# 3. Journal dédié : uniquement les requêtes d'un robot d'IA annoncé
LogFormat "%h %t \"%r\" %>s robot=%{editeur_ia}e refus=%{refus_ia}e \"%{User-Agent}i\"" robots_ia
CustomLog ${APACHE_LOG_DIR}/robots-ia.log robots_ia env=editeur_ia
<Location "/">
# Ne remplace pas les règles des <Directory> : s'y ajoute
AuthMerging And
<RequireAll>
Require not env refus_ia
<RequireAny>
# Aucun robot d'IA annoncé : rien à vérifier
Require expr "-z %{ENV:editeur_ia}"
# robots.txt toujours accessible
Require expr "%{REQUEST_URI} == '/robots.txt'"
# Robot annoncé : il doit venir des plages de son éditeur
<RequireAll>
Require expr "%{ENV:editeur_ia} == 'openai'"
Include /etc/apache2/robots-ia/openai.conf
</RequireAll>
<RequireAll>
Require expr "%{ENV:editeur_ia} == 'anthropic'"
Include /etc/apache2/robots-ia/anthropic.conf
</RequireAll>
<RequireAll>
Require expr "%{ENV:editeur_ia} == 'perplexity'"
Include /etc/apache2/robots-ia/perplexity.conf
</RequireAll>
</RequireAny>
</RequireAll>
</Location>
Chaque fichier inclus contient un bloc <RequireAny> de lignes Require ip. Ce bloc est indispensable : plusieurs Require ip placés directement dans un <RequireAll> devraient tous réussir à la fois, ce qui est impossible. Require ip accepte la notation CIDR, en IPv4 comme en IPv6. Le script suivant, exécuté contre les fichiers officiels le 25 octobre 2026, produit ces fichiers et ne recharge Apache que si la configuration reste valide.
#!/usr/bin/env bash
# /usr/local/sbin/maj-robots-ia-apache.sh - dépend de curl et jq
set -euo pipefail
dossier=/etc/apache2/robots-ia
genere() { # $1 = éditeur, puis les URL des fichiers JSON officiels
local editeur=$1; shift
local tmp; tmp=$(mktemp)
for url in "$@"; do
# -L : perplexity.com redirige vers perplexity.ai
curl -fsSL --max-time 30 "$url" \
| jq -er '.prefixes[] | (.ipv4Prefix // .ipv6Prefix) | select(. != null)' >> "$tmp"
done
[ -s "$tmp" ] || { echo "liste vide pour $editeur, abandon" >&2; rm -f "$tmp"; exit 1; }
{ echo "<RequireAny>"
sort -u "$tmp" | sed 's/^/ Require ip /'
echo "</RequireAny>"; } > "$dossier/$editeur.conf.new"
rm -f "$tmp"
}
genere openai https://openai.com/gptbot.json https://openai.com/searchbot.json https://openai.com/chatgpt-user.json
genere anthropic https://claude.com/crawling/bots.json
genere perplexity https://www.perplexity.com/perplexitybot.json https://www.perplexity.com/perplexity-user.json
for e in openai anthropic perplexity; do
cp -p "$dossier/$e.conf" "$dossier/$e.conf.bak" 2>/dev/null || true
mv "$dossier/$e.conf.new" "$dossier/$e.conf"
done
if ! apachectl configtest; then
for e in openai anthropic perplexity; do
[ -f "$dossier/$e.conf.bak" ] && mv "$dossier/$e.conf.bak" "$dossier/$e.conf"
done
echo "configuration refusée, anciennes listes restaurées" >&2
exit 1
fi
apachectl graceful
Lancez-le une première fois avant d'ajouter le bloc <Location>, sinon les Include pointent vers des fichiers absents ; puis planifiez-le chaque jour avec cron. Sur Debian et Ubuntu, la commande s'appelle aussi apache2ctl. Pour contrôler à la main une adresse trouvée dans le journal, le vérificateur d'IP de robots IABIG interroge les mêmes listes.
Si un proxy ou un CDN précède Apache, l'adresse vue par Require ip est la sienne : configurez d'abord mod_remoteip, sinon tous les vrais robots seront refusés.
X-Robots-Tag avec mod_headers
<FilesMatch "\.pdf$">
Header set X-Robots-Tag "noindex"
</FilesMatch>
Google documente cet en-tête ; les pages d'OpenAI, d'Anthropic et de Perplexity consultées pour ce guide ne le mentionnent pas. Pour ces robots, robots.txt reste la consigne documentée.
Ce qui change par rapport à Apache 2.2
| Apache 2.2 | Apache 2.4 |
|---|---|
Order Allow,Deny puis Allow from all |
Require all granted |
Order Deny,Allow puis Deny from all |
Require all denied |
Deny from env=refus_ia |
Require not env refus_ia dans un <RequireAll> |
Allow from 192.0.2.0/24 |
Require ip 192.0.2.0/24 |
AllowOverride All par défaut |
AllowOverride None par défaut |
Les anciennes directives existent encore en 2.4 grâce à mod_access_compat, mais la documentation les déclare obsolètes et déconseille de les mélanger avec Require : les deux mécanismes se combinent de façon peu intuitive. Si vous reprenez un vieux .htaccess, convertissez-le en entier. Autre différence : avant la version 2.4.16, l'expression de Require expr devait être écrite sans guillemets.
Apache n'a pas d'équivalent intégré à la limitation de débit par requêtes de nginx : mod_ratelimit limite la bande passante, pas le nombre de requêtes.
Tester
apachectl configtest
# Robot d'entraînement : 403 ; même robot sur robots.txt : 200
curl -s -o /dev/null -w '%{http_code}\n' -A "compatible; GPTBot/1.4" https://www.example.com/
curl -s -o /dev/null -w '%{http_code}\n' -A "compatible; GPTBot/1.4" https://www.example.com/robots.txt
# Faux robot de recherche depuis votre poste : 403 avec la vérification IP
curl -s -o /dev/null -w '%{http_code}\n' -A "compatible; OAI-SearchBot/1.4" https://www.example.com/
tail -f /var/log/apache2/robots-ia.log
Ces tests sont indicatifs : curl reproduit le User-Agent, pas l'adresse du robot. Lors de nos essais, avec l'adresse locale déclarée comme plage d'OpenAI, OAI-SearchBot obtenait 200 et Claude-SearchBot 403, comme prévu. Le journal d'erreurs indique la cause de chaque refus (AH01630: client denied by server configuration).
Pièges à éviter
- Le User-Agent seul ne prouve rien. Le refus par nom n'arrête que les robots honnêtes ; seule la comparaison avec les plages IP écarte les usurpateurs, et seulement pour les éditeurs qui en publient.
- Un motif trop large.
botrefuserait Googlebot et Bingbot. - Bloquer les plages d'un éditeur pour refuser l'entraînement. Anthropic indique que cette méthode n'est pas fiable, car elle empêche aussi la lecture de robots.txt.
- Des listes périmées. Les plages évoluent ; un robot de recherche refusé dans le journal signale souvent une liste trop ancienne.
Revenir en arrière
Dans un .htaccess, supprimez ou commentez le bloc ajouté ; l'effet est immédiat. Dans la configuration serveur, retirez le bloc <Location> et les lignes SetEnvIfNoCase, puis apachectl configtest et apachectl graceful, et supprimez la tâche cron.
Sources officielles
- Apache 2.4, mod_authz_core (Require, RequireAll, AuthMerging) : https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html
- Apache 2.4, mod_authz_host (Require ip) : https://httpd.apache.org/docs/2.4/mod/mod_authz_host.html
- Apache 2.4, mod_setenvif : https://httpd.apache.org/docs/2.4/mod/mod_setenvif.html
- Apache 2.4, mod_rewrite : https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
- Apache 2.4, Access Control : https://httpd.apache.org/docs/2.4/howto/access.html
- Apache 2.4, Upgrading to 2.4 from 2.2 : https://httpd.apache.org/docs/2.4/upgrading.html
- Apache 2.4, mod_log_config (CustomLog env=) : https://httpd.apache.org/docs/2.4/mod/mod_log_config.html
- Apache 2.4, mod_headers : https://httpd.apache.org/docs/2.4/mod/mod_headers.html
- Apache 2.4, mod_remoteip : https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html
- Apache 2.4, mod_ratelimit : https://httpd.apache.org/docs/2.4/mod/mod_ratelimit.html
- RFC 9309, Robots Exclusion Protocol : https://www.rfc-editor.org/rfc/rfc9309
- OpenAI, Overview of OpenAI Crawlers : https://developers.openai.com/api/docs/bots
- Anthropic, Does Anthropic crawl data from the web : https://support.claude.com/en/articles/8896518
- Perplexity, Perplexity Crawlers : https://docs.perplexity.ai/docs/resources/perplexity-crawlers
À lire aussi
- Robots d'IA sur Netlify - robots.txt, fichier _headers et Edge Function de filtragePublier un robots.txt sur Netlify, ajouter X-Robots-Tag avec _headers et filtrer les robots d'IA par User-Agent avec une Edge Function ou l'extension dédiée.
- Robots d'IA sur IIS - robots.txt, URL Rewrite, Request Filtering et restrictions IPSur IIS, publier robots.txt, refuser les robots d'entraînement avec une règle URL Rewrite dans web.config et voir les limites des filtres et restrictions IP.
- Robots d'IA avec nginx - robots.txt, blocage par User-Agent, plages IP officielles et débitConfiguration nginx testée pour refuser les robots d'entraînement, laisser passer les vrais robots de recherche IA, limiter leur débit et les journaliser.
- Robots d'IA avec Next.js et Vercel - robots.ts, X-Robots-Tag et pare-feu VercelConfigurer robots.txt avec app/robots.ts dans Next.js, poser un en-tête X-Robots-Tag et régler le pare-feu Vercel sans bloquer ChatGPT Search ni Perplexity.