Identify the CDN, WAF, or bot-management vendor in front of a domain.
Project description
cdn-detect
Identify the CDN, WAF, or bot-management vendor in front of a domain. Vendor-neutral, no API keys, no cloud account.
$ cdn-detect cloudflare.com github.com
domain: cloudflare.com
ip: 104.16.132.229
is_cdn: True
cdn_provider: Cloudflare
methods: ip_prefix, http_header
domain: github.com
ip: 140.82.121.4
asn: AS36459 (GITHUB)
is_cdn: False
methods:
Why publish this? Most "what CDN is this site on?" tools either guess from a single signal (headers only, or DNS only) and miss obvious cases, or wrap a paid intel feed. cdn-detect runs four independent detection strategies — CNAME chain, IP prefix, ASN lookup, response headers, plus cookie-based bot-management fingerprints — and tells you which one fired. No registrations, no rate limits, MIT-licensed.
Install
pip install cdn-detect
Requires Python 3.10+ and outbound DNS + HTTPS.
Use
CLI:
cdn-detect example.com
cdn-detect example.com --json
cdn-detect example.com --no-http # DNS-only, no HTTP round-trip
cdn-detect a.com b.com c.com # multiple domains
Library:
from cdn_detect import detect
result = detect("example.com")
print(result.cdn_provider) # 'Cloudflare', 'Akamai', None, ...
print(result.detection_methods) # ['cname', 'http_header']
print(result.bot_management) # 'Cloudflare Bot Management', None, ...
print(result.as_dict()) # JSON-serialisable
What it detects
| Signal | What's matched | Example |
|---|---|---|
| CNAME chain | Vendor-owned hostnames in the resolution chain | evil.com → evil.com.cdn.cloudflare.net. |
| IP prefix | Hard-coded vendor IPv4 ranges | 104.16.0.0/12 → Cloudflare |
| ASN | Origin AS number via Team Cymru DNS | AS13335 → Cloudflare |
| ASN org | Vendor name in AS org string | AS54113 FASTLY → Fastly |
| HTTP headers | Vendor-specific response headers | cf-ray:, x-amz-cf-id:, x-akamai-* |
| Cookies | Vendor bot-management cookies | __cf_bm, _abck, incap_ses_* |
| Tunnels | Reverse-tunnel and zero-trust providers | cfargotunnel.com, *.ts.net, ngrok.io |
Currently knows about: Cloudflare, Akamai, Fastly, CloudFront, Imperva, Sucuri, Radware, StackPath, Edgio, Bunny CDN, KeyCDN, Reblaze, Azure Front Door / CDN, Google Cloud CDN, Vercel, Netlify, F5/Volterra, GitHub Pages — plus bot-management from Cloudflare, Akamai, Imperva, Radware, AWS WAF, PerimeterX/HUMAN, DataDome, Kasada — plus tunnels from Cloudflare, Tailscale, ngrok, Twingate, ZeroTier, Azure Dev Tunnels, and others.
Why multiple strategies
A single signal misses a lot:
- Cloudflare proxied behind another reverse proxy: HTTP headers are stripped, but ASN still resolves to AS13335.
- Akamai customer with a custom hostname: CNAME chain has no
akamai.netreference, but the IP lands in23.32.0.0/11. - Customer behind Cloudflare Tunnel (
cfargotunnel.com): the resolved IP belongs to Cloudflare, but the protection model is fundamentally different —tunnel_providersurfaces this distinction. - Sites running an on-prem WAF that doesn't add response headers: cookies often still leak the vendor.
detection_methods lists every strategy that fired so you know how confident the verdict is.
What it doesn't do
- Doesn't enumerate every vendor IP range. The IP-prefix list is curated, not exhaustive — for production-grade matching, supplement with vendor-published feeds (Cloudflare
/ips-v4, AWSip-ranges.json, etc.). - Doesn't probe the origin behind the CDN. That's a separate problem (and a much more invasive one). For origin-discovery, see DDactic or commercial DAST tooling.
- Doesn't try to fingerprint custom on-prem appliances by deep behavior — only by easily observable signals.
Contributing signatures
The signature data lives in src/cdn_detect/signatures.py. PRs adding new providers or expanding IP ranges are very welcome, please include a one-line citation (vendor doc, public IP feed URL, or observable example) in the PR description.
License
MIT. See LICENSE.
Maintained by
DDactic — DDoS resilience testing and external attack-surface management.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cdn_detect-0.1.0.tar.gz.
File metadata
- Download URL: cdn_detect-0.1.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89dfb80275666fc16b327635e6a8fdfc072cb93d3251414ceee1a6ae57037896
|
|
| MD5 |
008c090f8920ced8187a4487f9487440
|
|
| BLAKE2b-256 |
f19f472eb5069fd4d6d0a0c9634b9e9b78c14a63692a6d8a823bea4888b5e8c6
|
Provenance
The following attestation bundles were made for cdn_detect-0.1.0.tar.gz:
Publisher:
publish.yml on DDactic/cdn-detect
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdn_detect-0.1.0.tar.gz -
Subject digest:
89dfb80275666fc16b327635e6a8fdfc072cb93d3251414ceee1a6ae57037896 - Sigstore transparency entry: 1493807789
- Sigstore integration time:
-
Permalink:
DDactic/cdn-detect@ce8c8bd581ee7602a24894053fd60af48c745215 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/DDactic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ce8c8bd581ee7602a24894053fd60af48c745215 -
Trigger Event:
release
-
Statement type:
File details
Details for the file cdn_detect-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cdn_detect-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5de839d886e07990221c61213ef57a94302c1684e59a5738c1db53c03cf3beb
|
|
| MD5 |
232dca0f6f89479a89cec4db694e960f
|
|
| BLAKE2b-256 |
473f710da38884f4ae0ee4db5888420e622267901e3edd5cc3fc7f447e9af49a
|
Provenance
The following attestation bundles were made for cdn_detect-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on DDactic/cdn-detect
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cdn_detect-0.1.0-py3-none-any.whl -
Subject digest:
f5de839d886e07990221c61213ef57a94302c1684e59a5738c1db53c03cf3beb - Sigstore transparency entry: 1493807926
- Sigstore integration time:
-
Permalink:
DDactic/cdn-detect@ce8c8bd581ee7602a24894053fd60af48c745215 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/DDactic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ce8c8bd581ee7602a24894053fd60af48c745215 -
Trigger Event:
release
-
Statement type: