How to block AI crawlers on your server
Last updated:
AI companies crawl the web to train models, to power AI search and to fetch pages when a user asks about them. On a small server the load alone can be a problem, and many site owners do not want their content used for training.
There are four tools, and they work best together: robots.txt for the crawlers that follow it, user-agent rules in the web server for those that announce themselves, reverse DNS or published IP lists to tell a real crawler from a fake one, and rate limits for everything else. Commands are for nginx and Apache on Debian, Ubuntu and the RHEL family.
Know which crawlers you are dealing with
The main ones, as of October 2026, from each operator's own documentation. Some are crawlers; some are only robots.txt tokens that control how another crawler's data is used.
| Name | Operator | What it does |
|---|---|---|
GPTBot | OpenAI | Crawls content that may be used to train OpenAI's models. Published IP list. |
OAI-SearchBot, ChatGPT-User | OpenAI | ChatGPT search, and pages fetched when a user asks. OpenAI says robots.txt may not apply to ChatGPT-User. |
ClaudeBot, Claude-SearchBot, Claude-User | Anthropic | Training, search, and pages fetched for a user. Anthropic says they honor robots.txt. Published IP list. |
Google-Extended | A robots.txt token only, with no user agent of its own: it controls use for Gemini training and grounding. It does not affect Google Search. | |
Applebot-Extended | Apple | A robots.txt token only: it controls use of what Applebot crawls for Apple's model training. |
CCBot | Common Crawl | Builds the Common Crawl dataset, widely used to train models. Verifiable by reverse DNS. |
meta-externalagent | Meta | Crawls for uses such as training AI models. |
PerplexityBot, Perplexity-User | Perplexity | Perplexity search, and pages fetched for a user. Perplexity says Perplexity-User generally ignores robots.txt. |
Decide per purpose. Blocking training crawlers keeps your content out of future training sets; blocking AI search and user fetchers also keeps your site out of those answers, and the visits they send. To see which of them reach your server, count the user agents in the access log:
sudo awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20Ask them to stay away with robots.txt
Put a robots.txt at the root of every host you want to cover (each subdomain has its own). Several User-agent lines can share one rule:
User-agent: GPTBot
User-agent: ClaudeBot
User-agent: CCBot
User-agent: Google-Extended
User-agent: Applebot-Extended
User-agent: meta-externalagent
Disallow: /This list blocks training and leaves search alone. Add OAI-SearchBot, Claude-SearchBot and PerplexityBot to keep out of AI search too. Keep your existing rules for other crawlers below it, and never write User-agent: * with Disallow: / unless you also want to leave Google and Bing.
What robots.txt cannot do
- It is a request. Crawlers that follow it stop; the others do not, and nothing tells you which is which.
- User-triggered fetchers may not apply it, by their operators' own account.
- Changes take time: operators cache the file, often for up to a day.
- A scraper that hides its name or claims to be a browser is not covered at all.
Block by user agent in nginx or Apache
The web server can refuse the crawlers that announce themselves. This stops them even if they ignore robots.txt, as long as they keep their name.
nginx
The map goes in the http context: files in /etc/nginx/conf.d/ are included there by the Debian, Ubuntu and RHEL-family packages.
sudo tee /etc/nginx/conf.d/ai-crawlers.conf > /dev/null <<'EOF'
map $http_user_agent $ai_crawler {
default 0;
~*(GPTBot|ClaudeBot|CCBot|meta-externalagent|PerplexityBot) 1;
}
EOFThen add this inside each server block that should refuse them, in /etc/nginx/sites-available/ on Debian and Ubuntu or /etc/nginx/conf.d/ on the RHEL family:
if ($ai_crawler) {
return 403;
}Test the configuration, reload, and check: the first curl must print 403, the second 200 (replace example.com with your site).
sudo nginx -t && sudo systemctl reload nginx
curl -s -o /dev/null -w "%{http_code}\n" -A "GPTBot/1.2" https://example.com/
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/Warning: Keep the patterns exact. A pattern like bot or Google also blocks Googlebot and Bingbot, and your site drops out of search. Google-Extended and Applebot-Extended are not user agents: they belong in robots.txt only.
Apache
With mod_rewrite, inside each <VirtualHost> (both the port 80 and the port 443 one) or in the site's .htaccess. Rewrite rules in the main configuration do not apply to virtual hosts.
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (GPTBot|ClaudeBot|CCBot|meta-externalagent|PerplexityBot) [NC]
RewriteRule ^ - [F]sudo a2enmod rewrite
sudo apachectl configtest && sudo systemctl reload apache2sudo apachectl configtest && sudo systemctl reload httpdNote: In .htaccess the rules need AllowOverride FileInfo (or All) for that directory. On shared hosting this is usually already the case.
Verify real bots by reverse DNS
Anyone can send User-Agent: Googlebot. Scrapers do it to get past rules that allow search engines. A real crawler is confirmed by forward-confirmed reverse DNS: the address resolves to a name in the operator's domain, and that name resolves back to the same address.
sudo apt install -y bind9-hostsudo dnf install -y bind-utilsip=66.249.66.1
name=$(host "$ip" | awk '/pointer/ {print $NF; exit}' | sed 's/\.$//')
echo "$name"
host "$name" | awk '{print $NF}' | grep -qxF "$ip" && echo "confirmed" || echo "NOT confirmed"- Googlebot:
googlebot.comorgoogle.com. Bingbot:search.msn.com. Applebot:applebot.apple.com. CCBot:crawl.commoncrawl.org. - A name in another domain, or one that does not resolve back to the address, is a fake.
OpenAI, Anthropic, Perplexity and Common Crawl publish their crawlers' address ranges as JSON instead (the links are in each operator's documentation). This checks an address against such a list:
python3 - 20.171.207.10 https://openai.com/gptbot.json <<'EOF'
import ipaddress, json, sys, urllib.request
ip = ipaddress.ip_address(sys.argv[1])
req = urllib.request.Request(sys.argv[2], headers={"User-Agent": "Mozilla/5.0"})
prefixes = json.load(urllib.request.urlopen(req))["prefixes"]
nets = [ipaddress.ip_network(p.get("ipv4Prefix") or p.get("ipv6Prefix")) for p in prefixes]
print("in the list" if any(ip in n for n in nets) else "NOT in the list")
EOFThe same JSON lists can be loaded into an nginx geo block or the firewall, if you want to allow only the real crawlers that use a given name.
Rate limit crawlers
A rate limit works whatever a crawler calls itself, and protects the server from the ones that crawl too fast. In nginx, this limits each address whose user agent looks like a bot to 30 requests a minute, with a short burst; other visitors are not counted, because an empty key is not limited.
sudo tee /etc/nginx/conf.d/bot-limit.conf > /dev/null <<'EOF'
map $http_user_agent $bot_key {
default "";
~*(bot|crawler|spider|scraper) $binary_remote_addr;
}
limit_req_zone $bot_key zone=bots:10m rate=30r/m;
limit_req_status 429;
EOFThen, in the server or location blocks of the dynamic pages, and reload as above:
limit_req zone=bots burst=10 nodelay;Warning: Behind a CDN or a proxy, every request comes from the proxy's address: set set_real_ip_from and real_ip_header first, or the limit applies to all visitors together. Search engines slow down when they get 429, so keep the rate generous.
Apache has no per-address request limit of its own (mod_ratelimit limits bandwidth). The usual options are mod_evasive, a fail2ban jail on the access log, or nginx or a CDN in front.
When a crawler ignores everything
If a crawler ignores robots.txt and changes its user agent, block the addresses it uses at the firewall (replace the example range):
sudo ufw insert 1 deny from 198.51.100.0/24sudo firewall-cmd --permanent --zone=drop --add-source=198.51.100.0/24
sudo firewall-cmd --reloadHow InfraFence handles AI crawlers
InfraFence's bot management reads the web server's access logs and recognizes about 1,500 bots from public lists updated every day. AI crawlers are a category of their own.
- For each category, or for a single bot, you choose: allow, log only or block. Changes reach your servers within seconds.
- Each bot comes with a plain-language explanation: who runs it, what it is for (training, search, assistant, agent) and whether it declares that it respects robots.txt.
- When a bot set to block shows up in the log, its address is banned at the firewall. The ban comes from the log, so the request that revealed it has already been answered.
- Bots that claim to be a search engine or another known crawler, such as Googlebot, Bingbot or Applebot, are checked by forward-confirmed reverse DNS, and fakes are reported as spoofed.
- Requests that look like a bot but match no known one are reported as unknown bots.
AI crawlers are recognized by their user agent. A scraper that hides its name is left to the web firewall, which scores each visitor on what it does. InfraFence does not edit your robots.txt: the steps above stay useful next to it.
Questions
- Does blocking AI crawlers hurt my Google ranking?
- Not if you block the right names.
Google-Extendedin robots.txt does not affect Google Search, according to Google. BlockingGooglebot, or a pattern that matches it, does. - Is robots.txt enough?
- For the crawlers that follow it, yes. It does nothing against the ones that ignore it or hide their name, which is why the user-agent rules and rate limits exist.
- Should I block AI search crawlers too?
- It depends on whether you want to appear in AI answers. Blocking them keeps your content out of those answers and loses the visits they send. Many sites block training crawlers and allow search.
Try it free on 1 server
Starter is free for one server, with full protection and automatic blocking. No credit card.
Install the agent as root, with your token in place of <TOKEN>:
curl -fsSL https://github.com/infrafence/infrafence-agent/releases/latest/download/install.sh | sudo bash -s -- --token <TOKEN>The token is created in the dashboard, in Servers › Add server.
