¿Deberías bloquear los rastreadores de IA? Decide por bot, aplica por IP
Bloquea los rastreadores de IA según su función: frena los bots de entrenamiento, conserva los de búsqueda con IA y responde 403 a los GPTBot falsos comprobando la IP. Incluye código probado para nginx y Express.

Tu registro de accesos muestra GPTBot, ClaudeBot y algunos nombres que no reconoces. Todas las guías que encuentras dicen lo mismo: enumera los User-Agents en robots.txt y luego bloquea esas mismas cadenas en la configuración del servidor.
Ese consejo tiene un agujero. Un User-Agent es una cadena que escribe el cliente, y escribir "GPTBot" no cuesta nada. Una lista de bloqueo de nombres detiene a los bots honestos, que habrían obedecido robots.txt de todos modos, y deja pasar a todo scraper que tome prestado un nombre que permitiste. El nombre es una afirmación y la IP es la prueba, el mismo principio que la detección de bots por IP en general.
A continuación clasificamos los bots por función, mostramos lo que robots.txt puede y no puede hacer, pasamos cuatro direcciones reales de rastreadores por nuestra API y te damos una política de tres niveles con código probado para nginx y Express. Un GPTBot falsificado recibe un 403. Un Googlebot real, nunca.

¿Deberías bloquear los rastreadores de IA? Depende de la función del bot
Deberías bloquear los rastreadores de IA cuya función no aceptas y conservar los que te envían lectores. Los bots de IA hacen tres trabajos distintos, y bloquear cada uno te cuesta algo diferente.
- Rastreadores de entrenamiento: recopilan páginas que pueden entrenar modelos futuros. OpenAI dice que prohibir GPTBot "indicates a site's content should not be used in training generative AI foundation models" (indica que el contenido de un sitio no debe usarse para entrenar modelos fundacionales de IA generativa). Bloquearlos no cuesta nada en búsqueda.
- Bots de búsqueda con IA: indexan páginas para que un asistente pueda citarlas. OpenAI dice que los sitios excluidos de OAI-SearchBot "will not be shown in ChatGPT search answers" (no se mostrarán en las respuestas de búsqueda de ChatGPT). Bloquearlos te cuesta citas y los clics que traen.
- Fetchers activados por usuarios: cargan una página porque una persona pidió a un asistente que la leyera. Bloquearlos rompe la solicitud de esa persona.
Un medio con muro de pago tiene una razón clara para rechazar el entrenamiento. Una marca que quiere que los asistentes la recomienden debería conservar los bots de búsqueda. La mayoría de los sitios acaban con una división: no al entrenamiento, sí a la búsqueda y un límite de velocidad para los fetchers. Explicamos qué bot de OpenAI bloquear y lo que cuesta cada opción en otro artículo. Los agentes que compran en nombre de un usuario son otro problema, que tratamos en fraude de agentes de compra con IA en el checkout.
Qué bots de IA entrenan y cuáles te citan
Esta tabla clasifica por función los bots de IA que es más probable que veas, con lo que dice cada operador sobre robots.txt. Cada celda procede de la página del propio operador, consultada el 20 de octubre de 2026.
| Bot | Operador | Función | robots.txt, en palabras del operador |
|---|---|---|---|
| GPTBot | OpenAI | Entrenamiento | Disallow significa que el contenido "should not be used in training" (no debe usarse para entrenamiento) |
| OAI-SearchBot | OpenAI | Búsqueda con IA | Los sitios excluidos no se muestran en las respuestas de búsqueda de ChatGPT |
| ChatGPT-User | OpenAI | Fetch activado por usuario | Las reglas de robots.txt "may not apply" (pueden no aplicarse) |
| ClaudeBot | Anthropic | Entrenamiento | Respeta robots.txt y Crawl-delay |
| Claude-SearchBot | Anthropic | Búsqueda con IA | Respeta robots.txt y Crawl-delay |
| Claude-User | Anthropic | Fetch activado por usuario | Respeta robots.txt y Crawl-delay |
| Google-Extended | Token para uso por IA, sin rastreador | Solo un token de robots.txt, sin User-Agent propio | |
| Googlebot | Búsqueda, no es un bot de IA que bloquear | Los rastreadores comunes "always obey robots.txt rules when crawling automatically" (siempre obedecen las reglas de robots.txt al rastrear automáticamente) | |
| PerplexityBot | Perplexity | Búsqueda con IA | No se indica; Perplexity recomienda permitirlo |
| Perplexity-User | Perplexity | Fetch activado por usuario | "generally ignores robots.txt rules" (generalmente ignora las reglas de robots.txt) |
| CCBot | Common Crawl | Archivo web abierto que cualquiera puede descargar | Consulta robots.txt primero; obedece Crawl-delay |
| Applebot-Extended | Apple | Token para uso en entrenamiento de IA, sin rastreador | Apple dice que "does not crawl webpages" (no rastrea páginas web) |
| Meta-ExternalAgent | Meta | Entrenamiento e indexación | No se indica; Meta documenta una regla Disallow para él |
| Bytespider | ByteDance | No documentado en ninguna página que pudiéramos abrir | No documentado en ninguna página que pudiéramos abrir |
La prueba es una cuestión aparte de la política. Un bot solo se puede verificar si su operador publica desde dónde rastrea:
| Operador | Archivo de rangos | Prefijos el 20 de octubre de 2026 | DNS inverso documentado | GeoIPHub verifica |
|---|---|---|---|---|
| OpenAI | gptbot.json, además de searchbot.json y chatgpt-user.json | 18, 39 y 234 | No documentado | Sí, los tres |
| Anthropic | bots.json, un archivo para los tres bots | 38 (archivo con fecha del 7 de octubre de 2026) | No documentado | Sí, una coincidencia se nombra ClaudeBot |
| common-crawlers.json y otros cuatro | 317 en rastreadores comunes | Sí: googlebot.com, google.com, googleusercontent.com | Sí | |
| Perplexity | perplexitybot.json y perplexity-user.json | 8 y 4 | No documentado | Sí |
| Common Crawl | ccbot.json | 5 | Sí, crawl.commoncrawl.org, solo IPv4 | Sí |
| Apple | applebot.json | 24 | Sí, applebot.apple.com | Sí, para Applebot |
| Meta | No publicado | No publicado | No documentado | Solo coincidencia de ASN, verified: false |
| ByteDance | No encontramos ninguno | Ninguno encontrado | No documentado | No |
Antes de copiar una lista de otro sitio, revisa sus nombres. Algunas guías que posicionan para este tema todavía nombran anthropic-ai y Claude-Web, que la página actual de Anthropic no incluye, y omiten Claude-SearchBot y Claude-User. Una lista desactualizada bloquea cadenas que nadie envía.
Lo que robots.txt puede y no puede hacer
robots.txt puede decirles a los bots bien educados lo que quieres, y no puede detener nada. El RFC 9309, el estándar que lo define, dice: "These rules are not a form of access authorization." (Estas reglas no son una forma de autorización de acceso). Si ignorarlo tiene consecuencias legales es una pregunta para un abogado.
Aun así es el primer nivel, porque la mayoría de los bots con nombre lo leen. Este archivo rechaza el entrenamiento, da la bienvenida a la búsqueda con IA y no toca la Búsqueda de Google:
# Training: no
User-agent: GPTBot
User-agent: ClaudeBot
User-agent: CCBot
User-agent: Google-Extended
User-agent: Applebot-Extended
User-agent: Meta-ExternalAgent
User-agent: Bytespider
Disallow: /
# AI search: yes
User-agent: OAI-SearchBot
User-agent: PerplexityBot
Allow: /
# Anthropic honours Crawl-delay (seconds between requests)
User-agent: Claude-SearchBot
Allow: /
Crawl-delay: 2
Cuatro detalles deciden si ese archivo hace lo que crees:
- Google-Extended y Applebot-Extended son tokens, no rastreadores. La página de rastreadores comunes de Google, actualizada el 15 de octubre de 2026, dice que "Google-Extended doesn't have a separate HTTP request user agent string" (Google-Extended no tiene una cadena de user agent de solicitud HTTP propia) y que "does not impact a site's inclusion in Google Search" (no afecta a la inclusión de un sitio en la Búsqueda de Google). Nunca llega una solicitud de Google-Extended, así que ninguna regla de IP puede bloquearlo. La página de Applebot de Apple dice que Applebot-Extended tampoco rastrea páginas web: "does not crawl webpages".
- Bloquear Googlebot para frenar el uso por IA te cuesta la Búsqueda. Lo mismo ocurre con un grupo
User-agent: *conDisallow: /. - Los fetchers activados por usuarios pueden ignorar el archivo. OpenAI dice de ChatGPT-User que "robots.txt rules may not apply" (las reglas de robots.txt pueden no aplicarse). Perplexity dice que Perplexity-User "generally ignores robots.txt rules" (generalmente ignora las reglas de robots.txt).
- Los cambios no son instantáneos. OpenAI dice que "it can take ~24 hours from a site's robots.txt update for our systems to adjust" (nuestros sistemas pueden tardar unas 24 horas en ajustarse tras una actualización del robots.txt de un sitio).
Archivos más nuevos como llms.txt y ai.txt son propuestas. Igual que robots.txt, piden y no aplican.
El error opuesto es meter rastreadores de búsqueda en una lista de bloqueo de "bots de IA". La guía para bloquear rastreadores de IA de Contentstack muestra una función edge cuya lista de bots incluye googlebot y bingbot junto a gptbot y claudebot, y responde a todos con "Forbidden: AI crawlers are not allowed." Copiada tal cual, esa regla saca un sitio de las búsquedas de Google y Bing. Quien se hace pasar por Googlebot es un Googlebot falso, un problema distinto con una solución distinta.
Un rastreador real o una falsificación: cómo funciona la verificación
Distingues un rastreador real de una falsificación comprobando la IP de conexión con lo que publica el operador nombrado. Cuál de los tres métodos funciona depende del operador.
- Archivos de rangos. OpenAI, Anthropic, Perplexity, Common Crawl, Apple y Google publican listas JSON de sus prefijos. Para OpenAI y Anthropic es el único método, porque sus direcciones no tienen DNS inverso.
- DNS inverso con confirmación directa. La guía de verificación de Google te pide resolver la IP a un nombre, comprobar el dominio y luego resolver el nombre de vuelta para confirmar que devuelve la misma IP. Apple y Common Crawl documentan el mismo método.
- Solicitudes firmadas (Web Bot Auth). Un bot firma cada solicitud con una clave publicada. Todavía es un borrador; lo tratamos en la sección sobre el edge, más abajo.
Nuestra guía sobre cómo verificar un rastreador de IA por IP explica los tres en detalle. Consultamos cuatro direcciones de rastreadores a las 04:37 UTC del 20 de octubre de 2026, sin clave. Esta es la dirección de ClaudeBot, recortada, con el anidamiento conservado y los valores sin editar:
{
"ip": "216.73.216.10",
"asn": {
"asn": 16509,
"org": "AMAZON-02 - Amazon.com, Inc."
},
"threat": {
"is_crawler": true,
"crawler": {
"verified": true,
"name": "ClaudeBot",
"operator": "Anthropic",
"category": "ai",
"verification_method": "ip_range_list"
}
},
"scoring": {
"fraud_score": 0,
"recommended_action": "allow",
"detection_methods": ["datacenter_ip", "no_ptr_datacenter", "verified_crawler"]
}
}
Las otras tres, de la misma ejecución:
| IP | crawler.name / operador / categoría | Verificado, método | Puntuación, acción | detection_methods | ASN |
|---|---|---|---|---|---|
| 132.196.86.1 | GPTBot / OpenAI / ai | true, ip_range_list | 0, allow | datacenter_ip, no_ptr_datacenter, verified_crawler | 8075 MICROSOFT-CORP-MSN-AS-BLOCK |
| 66.249.66.1 | Googlebot / Google / search_engine | true, ip_range_list | 0, allow | datacenter_ip, verified_crawler | 15169 GOOGLE |
| 107.178.192.1 | GoogleUserTriggeredFetcher / Google / fetcher | true, ip_range_list | 0, allow | datacenter_ip, rdns_hosting, verified_crawler | 396982 GOOGLE-CLOUD-PLATFORM |
La dirección de GPTBot es el primer host de 132.196.86.0/24, el primer prefijo del gptbot.json de OpenAI. Después le pedimos nombres al DNS, a las 04:45 UTC:
$ dig -x 216.73.216.10 +short # ClaudeBot: NXDOMAIN, no name
$ dig -x 132.196.86.1 +short # GPTBot: NXDOMAIN, no name
$ dig -x 66.249.66.1 +short
crawl-66-249-66-1.googlebot.com.
$ dig crawl-66-249-66-1.googlebot.com +short
66.249.66.1
Ese es el hallazgo que la mayoría de las guías pasan por alto. ClaudeBot y GPTBot no tienen registro PTR, así que el DNS inverso no puede verificarlos. El archivo de rangos es la única comprobación. no_ptr_datacenter se activa en ambos, pero la puntuación se queda en 0, porque verified_crawler es una señal exculpatoria. Para estos operadores, la falta de PTR es normal. Googlebot pasa de las dos formas: su nombre se resuelve de vuelta a la misma dirección.
Hay dos límites. El campo category dice "ai" tanto para bots de IA de entrenamiento como para los que no lo son, así que el código de la política debería basarse en crawler.name. Y la consulta solo ve una IP, nunca el User-Agent, así que la API nunca marca una falsificación. La comparación entre el nombre declarado y el nombre demostrado ocurre en tu código. Puedes hacer la misma comprobación a mano en nuestra herramienta de consulta de IP.
Una política de tres niveles: pedir, verificar, limitar
Una política que se sostiene tiene tres niveles: pedir con robots.txt, verificar cada afirmación de bot contra su IP y limitar la tasa de todo lo demás. Bloquea por función, aplica por IP y nunca pongas Googlebot en una lista de bloqueo de IA.
Nivel 1: pedir. robots.txt transmite tu decisión por bot, además de Crawl-delay para los operadores que lo respetan.
Nivel 2: verificar. Cuando un User-Agent nombra un bot, consulta la IP de conexión y compara nombres. Si la IP no pertenece a ese bot, la solicitud recibe un 403. Si pertenece, aplica tu decisión del nivel 1, de modo que un GPTBot verificado que ignora tu Disallow sigue siendo rechazado.
Nivel 3: limitar. Todo lo demás recibe un límite de tasa: solicitudes que no afirman ser ningún bot, bots que no se pueden verificar y fetchers que actúan en nombre de una persona.
| Caso | Ejemplo | Acción |
|---|---|---|
| Bot verificado que permites | Googlebot desde 66.249.66.1 | Servir con normalidad, sin límite de tasa |
| Bot verificado que rechazaste y sigue llegando | GPTBot desde 132.196.86.1 con GPTBot prohibido | 403 |
| Afirmación no verificada: el UA nombra un bot y la IP no coincide | UA de GPTBot desde 216.73.216.10, una dirección de Anthropic | 403, o un desafío si lo prefieres |
| Bot que no se puede verificar | Bytespider, Meta-ExternalAgent | Limitar la tasa; robots.txt es tu única palanca |
| Sin afirmación de bot | Navegadores y scrapers que se hacen pasar por navegadores | Limitar la tasa por IP |
La tercera fila es la más instructiva. 216.73.216.10 es un rastreador verificado, solo que no el que nombra la solicitud, así que una comprobación que solo pregunte "¿es un rastreador verificado?" lo dejaría pasar. Compara nombres. Del mismo modo, 107.178.192.1 es un fetcher verificado de Google, pero una solicitud desde esa dirección que afirma ser Googlebot no es Googlebot.
Registra cada fallo del nivel 2. Una dirección fuera de los rangos publicados suele indicar una falsificación, pero puede ser un prefijo que el operador acaba de añadir. Nuestros archivos de rangos se descargan de nuevo cada día y la base de datos de consultas se reconstruye a diario, así que un prefijo nuevo puede tardar hasta unos dos días en verificarse.
Aplícalo en nginx y Express, con una prueba de GPTBot falsificado
La aplicación consiste en un pequeño servicio Express que hace la consulta, más una configuración de nginx que le pregunta por cada solicitud que dice ser un bot. nginx estándar no puede llamar a una API HTTP en línea, así que el módulo auth_request envía una subsolicitud al verificador y nginx almacena la respuesta en caché. Sin nginx, el mismo archivo protege por sí solo una aplicación Express.
El verificador compara el User-Agent con los tokens de bot actuales, consulta la IP con GET https://api.geoiphub.com/v1/lookup/{ip} y la cabecera x-api-key, guarda el resultado en caché durante una hora y compara threat.crawler.name con el nombre declarado. Necesita un mapa de nombres porque la API escribe algunos nombres sin guion: OAISearchBot, ChatGPTUser, PerplexityUser. Consulta los campos de rastreadores en la documentación de la API.
// bot-gate.js: tier 2 (verify the IP behind a bot claim) and tier 3 (rate-limit the rest).
// Tested with Node 24.20.0, Express 5.3.0 and express-rate-limit 8.7.1.
const express = require('express');
const { rateLimit } = require('express-rate-limit');
const { BlockList, isIP } = require('node:net');
const API_KEY = process.env.GEOIPHUB_KEY; // production: always set a key
const CACHE_MS = 60 * 60 * 1000; // one hour per IP
const cache = new Map(); // ip: { at, crawler }
// Your policy: User-Agent tokens you refuse even when verified. Everything verified and not listed passes.
const BLOCKED = new Set((process.env.BLOCKED_BOTS || 'GPTBot,ClaudeBot,CCBot').split(','));
// Maps each User-Agent token to the crawler.name our API returns for that operator's range file.
// Anthropic publishes one file for all three of its bots, so a match comes back as ClaudeBot.
const EXPECTED = {
'GPTBot': 'GPTBot',
'OAI-SearchBot': 'OAISearchBot',
'ChatGPT-User': 'ChatGPTUser',
'ClaudeBot': 'ClaudeBot',
'Claude-User': 'ClaudeBot',
'Claude-SearchBot': 'ClaudeBot',
'PerplexityBot': 'PerplexityBot',
'Perplexity-User': 'PerplexityUser',
'CCBot': 'CCBot',
'Googlebot': 'Googlebot',
'bingbot': 'Bingbot',
'Applebot': 'Applebot',
};
// Longest tokens first, so "Claude-SearchBot" is not read as a shorter token.
const TOKENS = Object.keys(EXPECTED).sort((a, b) => b.length - a.length);
// A real crawler never connects from a private or loopback address.
const privateNets = new BlockList();
for (const [net, bits] of [['10.0.0.0', 8], ['172.16.0.0', 12], ['192.168.0.0', 16],
['127.0.0.0', 8], ['100.64.0.0', 10]]) privateNets.addSubnet(net, bits, 'ipv4');
privateNets.addSubnet('fc00::', 7, 'ipv6');
privateNets.addAddress('::1', 'ipv6');
function claimedBot(ua = '') {
const lower = ua.toLowerCase();
return TOKENS.find((t) => lower.includes(t.toLowerCase())) || null;
}
async function lookupCrawler(ip) {
const hit = cache.get(ip);
if (hit && Date.now() - hit.at < CACHE_MS) return hit.crawler;
const res = await fetch(`https://api.geoiphub.com/v1/lookup/${ip}`, {
headers: API_KEY ? { 'x-api-key': API_KEY } : {}, // keyless only for a local test
signal: AbortSignal.timeout(1500),
});
if (!res.ok) throw new Error(`lookup ${res.status}`);
const data = await res.json();
cache.set(ip, { at: Date.now(), crawler: data.threat.crawler });
return data.threat.crawler;
}
async function verifyBot(req, res, next) {
const claim = claimedBot(req.get('user-agent'));
if (!claim) return next(); // no bot claim: tier 3 handles it
const ip = req.ip.replace(/^::ffff:/, '');
const family = isIP(ip) === 6 ? 'ipv6' : 'ipv4';
if (privateNets.check(ip, family)) {
return res.status(403).send(`unverified ${claim} claim\n`);
}
let crawler;
try {
crawler = await lookupCrawler(ip);
} catch (err) {
// Fail mode: never fail open to "verified". Mark it and let the rate limiter decide.
req.botUnverified = true;
return next();
}
// The API never flags a spoof: it sees only the IP, not the User-Agent.
// The spoof check is this comparison, in your code.
const verified = crawler.verified === true && crawler.name === EXPECTED[claim];
if (!verified) return res.status(403).send(`unverified ${claim} claim\n`);
if (BLOCKED.has(claim)) return res.status(403).send(`${claim} is blocked by policy\n`);
req.verifiedBot = crawler.name;
return next();
}
// Tier 3: everyone without a verified bot name, keyed per IPv4 address or per IPv6 /64.
// nginx auth_request understands only 2xx, 401 and 403, so the verifier endpoint answers 403.
const limiter = rateLimit({
windowMs: 60 * 1000,
limit: 120,
ipv6Subnet: 64,
skip: (req) => Boolean(req.verifiedBot),
handler: (req, res) => res.set('Cache-Control', 'no-store')
.status(req.path === '/_verify_bot' ? 403 : 429).send('rate limited\n'),
});
const app = express();
app.set('trust proxy', 'loopback'); // only nginx on this host may set X-Forwarded-For
// Endpoint for nginx auth_request: 204 lets the request through, 403 stops it.
// After a failed lookup, no-store keeps nginx from caching the 204, so the limiter sees every request.
app.get('/_verify_bot', verifyBot, limiter, (req, res) => {
if (req.botUnverified) res.set('Cache-Control', 'no-store');
res.sendStatus(204);
});
// Standalone use without nginx: protect every route.
app.use(verifyBot, limiter);
app.get('/', (req, res) => res.send('ok\n'));
app.listen(3000, '127.0.0.1');
Tres decisiones son deliberadas. Si la consulta falla o tarda más de 1,5 segundos, la solicitud nunca se trata como verificada; pasa al limitador de tasa. Detrás de nginx, esa respuesta se envía con no-store, así que nginx no la guarda en caché y el verificador cuenta cada solicitud contra el mismo límite. La lista de la política contiene tokens de User-Agent, de modo que rechazar ClaudeBot no rechaza Claude-SearchBot, aunque ambos vuelvan de la consulta como ClaudeBot. trust proxy es solo loopback, porque de lo contrario un cliente podría enviar su propio X-Forwarded-For y elegir la dirección que compruebas. Y solo se consultan las afirmaciones de bot, así que el volumen sigue al tráfico de bots, no a las páginas vistas. El plan gratuito cubre 1.500 consultas al día con clave, con todos los campos incluidos.
La parte de nginx asigna el User-Agent a un bot declarado, omite la subsolicitud cuando no hay afirmación y guarda en caché el 204 o el 403 del verificador por dirección y bot durante una hora, salvo las respuestas marcadas con no-store:
# Goes in the http {} block. Tested with nginx 1.30.6 built with --with-http_auth_request_module.
# Which bot does the User-Agent claim? Empty means no claim.
map $http_user_agent $claimed_bot {
default "";
"~*(GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User|CCBot|Googlebot|bingbot|Applebot)" $1;
}
# Tier 3 key: rate-limit requests with no bot claim. Claims go to tier 2 instead.
map $claimed_bot $limit_key {
"" $binary_remote_addr;
default "";
}
limit_req_zone $limit_key zone=perip:10m rate=10r/s;
# Cache the verifier's answer per address and claimed bot for one hour.
proxy_cache_path /var/cache/nginx/botcheck keys_zone=botcheck:1m max_size=10m inactive=1h;
server {
listen 8080;
location / {
limit_req zone=perip burst=20 nodelay;
limit_req_status 429;
auth_request /_verify_bot;
proxy_pass http://127.0.0.1:8000; # your app
}
location = /_verify_bot {
internal;
if ($claimed_bot = "") { return 204; } # no claim: no lookup
proxy_pass http://127.0.0.1:3000; # bot-gate.js
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_cache botcheck;
proxy_cache_key $remote_addr$claimed_bot;
proxy_cache_valid 204 403 1h;
}
}
nginx -t dio por buena esta configuración, y la ejecutamos delante del archivo Express el 20 de octubre de 2026, a las 05:05 UTC. Primero, la prueba del GPTBot falsificado, a través de nginx, desde la misma máquina:
$ curl -s -o /dev/null -w "%{http_code}\n" \
-A "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot" \
http://localhost:8080/
403
$ curl -s -o /dev/null -w "%{http_code}\n" \
-A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36" \
http://localhost:8080/
200
Esa cadena de GPTBot es el ejemplo actual de la página de bots de OpenAI. Desde tu propia máquina, la solicitud llega desde 127.0.0.1, que ningún rastreador usa, así que el verificador la rechaza antes de cualquier consulta. Para ver la consulta en acción, llama directamente al archivo Express con la dirección que reenviaría nginx:
$ GPT='Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot'
$ GB='Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
$ curl -s -A "$GPT" -H "X-Forwarded-For: 216.73.216.10" http://127.0.0.1:3000/
unverified GPTBot claim
$ curl -s -A "$GPT" -H "X-Forwarded-For: 132.196.86.1" http://127.0.0.1:3000/
GPTBot is blocked by policy
$ curl -s -A "$GB" -H "X-Forwarded-For: 107.178.192.1" http://127.0.0.1:3000/
unverified Googlebot claim
$ curl -s -A "$GB" -H "X-Forwarded-For: 66.249.66.1" http://127.0.0.1:3000/
ok
Sigue la primera línea de principio a fin. El User-Agent afirma ser GPTBot. El verificador consulta 216.73.216.10 y la API responde con un rastreador verificado llamado ClaudeBot. ClaudeBot no es GPTBot, así que la solicitud recibe un 403. La dirección real de GPTBot, 132.196.86.1, supera la verificación y se rechaza solo porque esta política rechaza el entrenamiento; con BLOCKED_BOTS=CCBot obtuvo un 200. Una afirmación de Claude-SearchBot desde 216.73.216.10 obtuvo un 200, porque esta política rechaza el token ClaudeBot, no el bot de búsqueda de Anthropic. Una copia de la configuración de nginx solo para pruebas que reenviaba las mismas cuatro direcciones devolvió 403, 403, 403 y 200. Con la API inaccesible a propósito, 130 afirmaciones de bingbot desde una misma dirección a través de nginx obtuvieron 120 respuestas con estado 200 y luego 403: una caída limita las afirmaciones de bot en lugar de dejarlas pasar.
Si pruebas sin clave, hazlo breve. Las consultas anónimas tienen un límite por minuto, y la llamada número 30 dentro de una misma ventana de 60 segundos ya es un 429 que bloquea tu IP durante dos horas.
Limita la tasa de lo que no puedes verificar en lugar de bloquearlo
La limitación de tasa es la herramienta adecuada para el tráfico que no puedes demostrar en ningún sentido: bots no verificables, fetchers activados por usuarios y todo lo que no afirma ser un bot. Para ver qué bots publican archivos de rangos y cuáles no, consulta nuestra lista archivo por archivo. Un límite impide que un scraper copie tu sitio en una tarde sin bloquear a las personas que hay detrás de un fetcher.
Ambos fragmentos ya lo hacen. limit_req de nginx usa como clave la dirección del cliente para las solicitudes sin afirmación de bot, a 10 por segundo con una ráfaga de 20. En nuestra prueba, 40 solicitudes seguidas devolvieron 25 éxitos y 15 respuestas con estado 429. Ajusta los números y excluye los recursos estáticos si una sola carga de página descarga decenas. El limitador de Express agrupa a los clientes IPv6 por su /64, porque un suscriptor suele controlar un /64 entero; consulta limitar la tasa de IPv6 por prefijo /64 para saber cuándo ampliar a /56 o /48.
Crawl-delay es la versión educada para los bots que lo respetan. La página de ayuda sobre el rastreador de Anthropic dice "we support the non-standard Crawl-delay extension to robots.txt" (admitimos la extensión no estándar Crawl-delay de robots.txt), y las preguntas frecuentes de Common Crawl dicen "We obey the Crawl-delay parameter" (obedecemos el parámetro Crawl-delay). Otros no. La especificación de robots.txt de Google dice que campos "such as crawl-delay aren't supported" (como crawl-delay no se admiten), y Apple dice "Applebot does not follow crawl-delay" (Applebot no sigue crawl-delay). Las páginas de OpenAI y Perplexity no lo mencionan.
El nivel 2 solo detecta las solicitudes que nombran un bot. Para bloquear scrapers de IA que nunca dicen ser bots, añade comportamiento al nivel 3: tasas de solicitudes, rutas y la red de la que procede la solicitud. Nuestro artículo sobre cómo detectar web scraping en tus registros cubre esas señales.
Opciones en el edge: el bloqueo de IA de Cloudflare y el pago por rastreo
Detrás de Cloudflare, puedes bloquear los rastreadores de IA con un ajuste en lugar de código, o cobrarles por solicitud. Ninguna de las dos opciones elimina la necesidad de saber con qué bots estás tratando.
Cloudflare anunció el 1 de julio de 2025, en un artículo modificado por última vez el 15 de julio de 2026, que estaba "changing the default to block AI crawlers unless they pay creators for their content" (cambiando el valor predeterminado para bloquear los rastreadores de IA a menos que paguen a los creadores por su contenido). Si también ejecutas tus propias reglas, comprueba qué bloquea ya Cloudflare en tu zona para que las dos capas coincidan.
Con el pago por rastreo (pay per crawl), un rastreador que solicita una página con precio recibe "a 402 Payment Required response, accompanied by a crawler-price header" (una respuesta 402 Payment Required, acompañada de una cabecera crawler-price), y puede reintentar con intención de pago. Los rastreadores firman las solicitudes según las propuestas de Web Bot Auth para que nadie pueda pagar haciéndose pasar por otro. Cloudflare dice que el pago por rastreo "is currently in private beta" (está actualmente en beta privada).
Web Bot Auth todavía no es un estándar. El 20 de octubre de 2026, el grupo de trabajo webbotauth del IETF tenía un documento del grupo de trabajo, draft-ietf-webbotauth-httpsig-protocol-00, del 1 de septiembre de 2026, y ningún RFC; el hito de abril de 2026 de su estatuto para una especificación de vía de estándares ya ha pasado. Un borrador individual, draft-illyes-webbotauth-jafar, propone un formato JSON común para los archivos de rangos de rastreadores. Hasta que lleguen, los rangos de IP y el DNS inverso son lo que puedes comprobar.
Mide lo que cambió la política
Mide la política registrando el resultado de la verificación en cada solicitud de bot y comparando el antes y el después.
- Proporción por bot verificado. Registra
crawler.nameycrawler.verifiedjunto a cada solicitud que afirmó ser un bot. La proporción de afirmaciones fallidas es tu tasa de falsificación. La proporción por nombre muestra qué operadores te rastrean realmente. - Referencias de IA. Cuenta las visitas que llegan desde chatgpt.com, perplexity.ai, claude.ai, copilot.microsoft.com y gemini.google.com. Trata esa cifra como un mínimo, ya que parte del tráfico de asistentes llega sin referente.
- Volumen de rastreo. Compara las solicitudes diarias de cada bot antes y después de un cambio. El informe Estadísticas de rastreo de Search Console solo cubre los rastreadores de Google, así que los demás bots tienen que salir de tus propios registros.
Si las citas caen después de bloquear un bot de búsqueda con IA, ya tienes tu respuesta sobre ese bot.
Cuándo revisar tu política de rastreadores de IA
Revisa tu política de rastreadores de IA siempre que un operador añada un bot, cambie un archivo de rangos o retire un token, y al menos una vez por trimestre. La página de bots de OpenAI ya incluye OAI-AdsBot, con su propio adsbot.json. Nuestros feeds de rastreadores no incluyen ese archivo y el código anterior no lo nombra, así que una afirmación de OAI-AdsBot cae en el nivel 3 hasta que decidas.
Ten claro lo que esta configuración no puede hacer:
- Solo demuestra los bots que publican rangos. Bytespider y Meta-ExternalAgent no se pueden verificar, y una falsificación de cualquiera de los dos es idéntica al original.
- Los prefijos nuevos llegan con retraso. Un prefijo añadido hoy puede tardar hasta unos dos días en verificarse, así que un bot real puede fallar brevemente el nivel 2.
- Los bloqueos por IP pueden ser contraproducentes. Anthropic advierte que bloquear sus IP "may not work correctly or persistently guarantee an opt-out, as doing so impedes our ability to read your robots.txt file" (puede no funcionar correctamente ni garantizar de forma persistente la exclusión, ya que impide que leamos tu archivo robots.txt). Mantén el Disallow en robots.txt aunque el nivel 2 lo aplique.
- La consulta no puede ver el User-Agent. La comprobación de falsificación es la comparación de nombres en tu código.
- El nivel 2 no detecta los scrapers que nunca declaran un nombre. Esos son trabajo del nivel 3.
Empieza por tus propios registros. Elige una dirección que haya afirmado ser GPTBot o ClaudeBot esta semana, pásala por una consulta y compara crawler.name con el nombre que declaró.
Preguntas frecuentes
¿Debería bloquear los rastreadores de IA?
Depende de la función del bot. Bloquea los rastreadores de entrenamiento como GPTBot y ClaudeBot si no quieres que tu contenido entrene modelos. Permite los bots de búsqueda con IA como OAI-SearchBot si quieres que te citen. Limita la tasa de los fetchers activados por usuarios en lugar de confiar en robots.txt.
¿robots.txt detiene a los rastreadores de IA?
Solo a los que deciden obedecerlo. El RFC 9309 dice que sus reglas "are not a form of access authorization" (no son una forma de autorización de acceso). Un scraper que usa un User-Agent de GPTBot lo ignora, así que la aplicación tiene que comprobar la IP desde la que llega la solicitud.
¿Bloquear los rastreadores de IA perjudica el SEO?
Bloquear el token Google-Extended no afecta a la Búsqueda de Google; Google dice que "does not impact" (no afecta) a la inclusión de un sitio en la Búsqueda. Bloquear Googlebot para frenar el uso por IA te saca de la Búsqueda. Bloquear bots de búsqueda con IA como OAI-SearchBot te deja fuera de las respuestas de búsqueda de ese asistente.
¿Puedo bloquear Google-Extended por IP?
No. Google-Extended es un token de robots.txt sin User-Agent propio. Los rastreadores existentes de Google son los que hacen las solicitudes, así que el único control es una regla de robots.txt para el token. Applebot-Extended funciona igual: Apple dice que no rastrea páginas web.
¿Cómo sé si una solicitud que dice ser GPTBot es real?
Comprueba que la IP de conexión está en el gptbot.json que publica OpenAI. El DNS inverso no sirve: las direcciones de GPTBot y ClaudeBot que revisamos no tienen registro PTR. Una consulta devuelve threat.crawler.verified y el nombre del bot, y tu código compara ese nombre con el User-Agent.
¿Se puede verificar por IP cualquier rastreador de IA?
No. No encontramos ningún archivo de rangos de ByteDance para Bytespider, y Meta no publica ninguno para Meta-ExternalAgent, así que ninguno de los dos se puede verificar por IP. Limita su tasa en lugar de confiar en el User-Agent.
El equipo detrás de la API de GeoIPHub
Escrito por el equipo de GeoIPHub, las personas que crean la API de inteligencia IP de GeoIPHub y su escáner. Los borradores se preparan con ayuda de IA y el equipo los edita; los ejemplos de la API son consultas reales contra la API en producción, salvo que se indique que son ilustrativos.


