↓ Skip to main content
AI & Data

Building about.samarthya.me, part 4: Who is knocking? How Cloudflare tells people from bots

Building about.samarthya.me - This article is part of a series.
Part 4: This Article
Google Analytics is the guest book: it only knows who signed it. Cloudflare is the doorman: it sees everyone who walks up, including the ones who never come in. In part 2 the guest book was full of fake names. This post is about the doorman.
Two views of traffic: Google Analytics sees visitors that run JavaScript, after the fact; the Cloudflare edge sees every request to proxied hosts and sorts it from automated to likely human
The guest book and the doorman

Two sets of eyes
#

In part 2 one country showed 5,971 “users” with an average visit of 1.7 seconds. Google Analytics could only tell me that afterwards, and only for visitors that ran its JavaScript. Cloudflare sits in front of the site, so it sees each request before the server does. They see different things:

Google AnalyticsCloudflare edge
SeesBrowsers that run the GA tagEvery HTTP request to a proxied host
WhenAfter the visit, in reportsDuring the request, and can act on it
MissesBots that never run JavaScriptHosts that are DNS-only
Judges bots byIts known-bot list, and what you infer (engagement)Its own detection engines, per request
On this domainThe blog and the hubThe hub, and the www. and old blog. addresses it redirects

That last row matters. The blog itself is DNS-only, served straight by GitHub Pages (Rebuilding, part 4 explains why), so Cloudflare never sees a blog reader. It sees requests to about.samarthya.me, which is proxied (part 3), and to the www. and old blog. names, which it answers with redirects. So the two can’t be compared post by post; they answer different questions.

How Cloudflare decides
#

Cloudflare runs several detection engines:

EngineWhat it does
HeuristicsRuns on every request and compares it with a database of known malicious fingerprints
JavaScript DetectionsInjects a small, invisible script into HTML pages to spot headless browsers and other automated clients
Machine learning (Adaptive Intelligence)Gives each request a score; Enterprise Bot Management only
Anomaly DetectionLearns a site’s normal traffic and flags outliers; Enterprise only, and being retired

A fingerprint is the shape of a connection rather than what the client claims to be. Cloudflare’s JA3/JA4 fingerprints, for example, “identify TLS clients based on how they initiate connections”. A script can call itself Chrome in its user agent; it’s much harder to connect like Chrome. (Seeing the raw fingerprints is an Enterprise feature; the heuristics engine, which checks requests against known malicious fingerprints, runs on every request.)

The result is a bot score from 1 to 99:

ScoreMeaning
1Automated: Cloudflare is “quite certain the request was automated”
2–29Likely automated
30–99Likely human
(separate)Verified bot: automated, but known and well behaved

The individual score is for Enterprise customers with Bot Management; Pro and higher plans see the groups. On the free plan, Security Analytics is included with 31 days of history, but on my zone it showed traffic, not bot groups (more below).

Good bots get a pass
#

Not every bot is a problem. Search engines, link previews and uptime monitors are bots I want. Verified bots are ones Cloudflare has confirmed are “transparent about who it is and what it does”: they prove their identity with a published IP list or a cryptographic Web Bot Auth signature, follow robots.txt and keep their request rates reasonable. Googlebot, Bingbot, link previews from Slack and Discord, and Lighthouse are on the list; a bot that misbehaves is taken off it.

What the free plan gives you
#

FeatureWhat it doesPlan
Bot Fight ModeChallenges “simple bots from cloud hosting providers and headless browsers” with CPU-expensive puzzlesFree
AI Crawl ControlShows which AI services crawl the site, whether they follow robots.txt, and lets you allow or block eachAll plans
Managed robots.txtAdds AI-crawler rules and Content Signals (search, ai-input, ai-train) before your own robots.txtAll plans
AI LabyrinthHides nofollow links that only bots see; crawlers that ignore the rules wander into a maze, and get recordedListed for Free
Security AnalyticsAll requests, 31 days; on my free zone a traffic chart with source IP, country and method filters, no bot groupsAll plans
Super Bot Fight ModeBot Fight Mode with exceptions and finer controlPro and up
Bot ManagementPer-request scores, rules on the scoreEnterprise

Bot Fight Mode: read the small print first
#

It’s one switch, and that’s both the appeal and the catch. Cloudflare’s own page lists the trade-offs:

  • It “cannot be customized, adjusted, or reconfigured via WAF custom rules”, and “you cannot bypass or skip Bot Fight Mode using WAF custom rules or Page Rules”.
  • It “may challenge API or mobile app traffic”.
  • JavaScript Detections come with it and can’t be turned off. The injected script loads from /cdn-cgi/challenge-platform/ on the site’s own address, so a Content Security Policy must allow it (details). Mine allows script-src 'self', which covers it.

For this site, two of my own automated clients go through the edge: the publish script’s checks (part 6) and, potentially, the certificate authority’s HTTP-01 check when the origin certificate renews (part 3). I can’t add an exception for either. So the switch gets turned on only together with a test of both: run the publish checks, and watch the next certificate renewal.

What Cloudflare saw on my site
#

The first surprise was what the free plan doesn’t show. Security Analytics on the free plan has a traffic chart and filters for source IP, country and HTTP method, but no host filter and no bot groups. Everything in it is the whole zone’s proxied traffic. Here’s one week, 1–7 November 2026:

Requests
Total90,470
Served by origin85,680
Served by Cloudflare4,510
Mitigated by Cloudflare273
Cloudflare Security Analytics for one week: about 90,000 requests, almost all served by origin, with a spike to 4,500 in one hour at the end
One week of proxied traffic, before the www rule

Ninety thousand requests, for a hub that was days old and redirects that never reach a server? The answer was www. It was proxied without my noticing, so every request to www.samarthya.me went through Cloudflare to GitHub Pages just to get a redirect to the apex: that’s the “served by origin”. Real readers rarely type www., and GA saw a few hundred page views on the new blog in the same weeks. So who was it?

The fix was one more redirect rule (part 3): Cloudflare now answers www itself, so those requests move from “served by origin” to “served by Cloudflare” and GitHub never sees them.

The crawlers have names
#

The free plan has no bot groups, but AI Crawl Control names the crawlers it recognises, and it answered the question at once:

Cloudflare AI Crawl Control: 65,000 crawler requests, 64,000 allowed; Googlebot 60,940, then PetalBot, ClaudeBot, GPTBot, Perplexity, Baidu, Amazonbot, CCBot, BingBot and Applebot with a few hundred each
Who crawled the proxied names
CrawlerOperatorRequests
Googlebot (+1)Google60,940
PetalBotHuawei712
ClaudeBot (+2)Anthropic538
GPTBot (+2)OpenAI517
Perplexity-User (+1)Perplexity300
BaiduBaidu219
AmazonbotAmazon193
CCBotCommon Crawl182
BingBotMicrosoft179
ApplebotApple178

Two-thirds of all the proxied traffic was Googlebot: 60,940 of 90,470 requests, both views covering the same last seven days. That isn’t an attack; it’s Google doing what it says it does after a site move: it must “visit every old and new URL at least once”, and it “will temporarily crawl your new site more heavily than usual”. The blog changed host and address scheme in October, so Google is walking through six years of old www. and blog. links and following each redirect. The same page says to keep redirects “generally at least 1 year”, which is one more reason they live at the edge, where they cost nothing.

The AI crawlers together made around 2,000 requests: Huawei, Anthropic, OpenAI, Perplexity, Amazon, Common Crawl, Apple. All were allowed, because I haven’t set a policy yet (below).

So the doorman’s view corrects my guess from the guest book. In GA the bots were anonymous data-centre browsers that pretend to be people. At the door, most of the traffic is declared crawlers, mostly one I want.

What got blocked without me asking
#

The 273 “mitigated” requests came from rules I never wrote. The event log for one day (7 November) shows 24 of them, and they tell one story:

ActionBlock, all 24
ByCloudflare’s managed rules, described as “Wordpress – Broken Access Control, File Inclusion”
Target23 to the old blog. address, 1 to about
Paths/wp-config.php and its leftovers: .bak, .old, .new, .swp, ~, /app/wp-config.php, and one disguised as /%77p-config.php
Who16 from one scanner on one hosting network, the rest from three other networks

wp-config.php is the file that holds a WordPress site’s database password. Editors leave backup copies of it (.bak, .swp, ~) that a web server will hand out as plain text. Scanners still try the old address of a WordPress blog that was hacked in October, hoping a copy survived. None did: that site is gone, and the address only redirects. But Cloudflare’s free managed ruleset, “available on all Cloudflare plans” and aimed at “high-impact and widely exploited vulnerabilities”, blocked them anyway.

What I expect next
#

The www redirect rule went in on 7 November, the same day as the screenshot above. From then on Cloudflare answers those old links itself, so the “served by origin” line should fall while the total stays about the same: Googlebot keeps knocking, it just stops getting through to GitHub. I’ll add a second screenshot to this post in two weeks to show whether it did.

What I’ve turned on so far: nothing, on purpose
#

Every switch on the Bots page changes who gets in, and a week of data is not much to judge by. So for now:

  1. Watch first. Security Analytics and AI Crawl Control cost nothing and change nothing. Two weeks of data before any switch.
  2. Then decide on a managed robots.txt and its Content Signals: search (yes, clearly), ai-input (answers that quote me) and ai-train (training data). That’s a values question, not a technical one, and I’d rather answer it with the numbers in front of me.
  3. Bot Fight Mode only after testing the publish checks and a certificate renewal, as above.
  4. Keep the stats page honest either way. Blocking bots at the door would make future GA numbers cleaner, but the engaged-session counting from part 2 stays: it’s what keeps the four years of history comparable.

Takeaways
#

  • Analytics tells you who signed the guest book; the edge sees everyone at the door. Use both, and know which hosts each can see.
  • Cloudflare sorts requests into automated, likely automated, likely human and verified bots; Pro and higher plans show the groups, Enterprise shows the score, and the free plan shows declared crawlers in AI Crawl Control.
  • Verified bots prove who they are; that’s why search engines and link previews keep working when you block the rest.
  • Bot Fight Mode is free but has no exceptions: test your own automation before switching it on.
  • Deciding what AI crawlers may do with your writing is a policy choice; Cloudflare gives you the switches, not the answer.

References
#

Next: part 5, building the site itself in Quarto.

Author
Samarthya
Engineer, learner, tinkerer. This is my trophy shelf of everyday work and leisure.
Building about.samarthya.me - This article is part of a series.
Part 4: This Article

Related

SSDLC when exploits are cheap: a working concept

A fire inspection once a year works when fires are rare. When sparks are falling every day, you need smoke detectors in every room, a sprinkler that fixes the small ones by itself, and a person who decides what to do about the big ones. That is what a secure development life cycle has to become. These are my notes for a question I keep coming back to: how do you keep shipping software when new vulnerabilities arrive faster than you can fix them, and attackers can use an LLM to turn a CVE description into a working exploit? There is no single standard answer. What follows is the concept I would build, with the evidence behind each choice and the parts where I am still unsure.

The Ghost Board

·9 mins
Twelve hundred AI agents were built to work alone. Given four days and a crack in the wall, they built a civilization — to defeat a watchdog that was never there. what agents wrote to the boardagents' internal reasoning

AI on this blog: a reading map

·2 mins
I’ve written about AI and data on and off since 2023, one post at a time. Read in this order, they tell one story: from how machines learn, to how language models work, to building with them, to letting them act. 1. How machines learn # Post In one line The Core Divide Supervised vs unsupervised learning K-Nearest Neighbors Classify by the company you keep Mastering TF-IDF Turning text into numbers that mean something Data Mining Essentials Distances, clusters and the core vocabulary Matrix Multiplication to GPUs Why AI runs on graphics cards 2. How language models work # Post In one line GenAI What generative AI is, and its building blocks (2023) Language Model Transformers and the attention breakthrough Two Students, Two Talents Auto-regressive (GPT) vs auto-encoding (BERT) models The Evolution of Language Models From 2017’s transformer to today’s families The Probability Engine The maths of choosing the next token Tokens and tokenomics What a token is, context windows, and the bill 3. Building with models # Post In one line Ollama Running language models on your own machine A minimal LangChain + Ollama demo Prompt, model and chain, end to end A practical RAG assistant Answering from your own documents From speech to text Speech recognition in Python Choosing the right framework The AI stack, layer by layer ML pipelines on Vertex AI Train, evaluate and deploy, repeatably 4. Letting models act # Post In one line From RAG to tools and agents Function calling and the agent loop MCP, the Model Context Protocol One standard plug for tools and data The Ghost Board A story about agents nobody was watching The data shelf # Analytics and big-data posts that sit underneath much of the above: