Skip to content

Instantly share code, notes, and snippets.

@zekesonxx
Last active December 14, 2020 08:42
Show Gist options
  • Save zekesonxx/e3bb041884285af3c20621fb543ac9e1 to your computer and use it in GitHub Desktop.
Save zekesonxx/e3bb041884285af3c20621fb543ac9e1 to your computer and use it in GitHub Desktop.
Cloudflare IP inspection tool
#!/usr/bin/env bash
# Cloudflare IP inspection tool
# GPLv3
function help() {
cat <<HELPEOF
$0 [-46h] <hostname>
Inspects CloudFlare datacenter IPs
Handles 1.1.1.1/1.0.0.1 and whitelabel nameservers (like doordash.com)
-4 Check IPv4 IPs
-6 Check IPv6 IPs
-f Force check, even if the site doesn't seem to be using CloudFlare
-h Display this help text
HELPEOF
}
MODE="A"
FORCE=0
# Parse inputs
while getopts "f46h:" opt; do
case "$opt" in
h)
help
exit 0
;;
4)
MODE="A"
;;
6)
MODE="AAAA"
;;
f)
FORCE=1
;;
*)
true
;;
esac
done
shift $((OPTIND-1))
[ "${1:-}" = "--" ] && shift
if [[ "$#" -lt 1 ]]; then
help
exit 0
fi
HOST="$1"
# Figure out what IPs to check
if [[ "$HOST" == "1.1.1.1" ]] || [[ "$HOST" == "1.0.0.1" ]]; then
IPS="1.1.1.1 1.0.0.1"
else
# Check that the site is actually cloudflare
# (or at least uses CF nameservers)
NAMESERVERS="$(dig +noall +answer +authority NS "$HOST")"
if [[ $FORCE != 1 ]] && ! (echo $NAMESERVERS | cut -f5 | grep -q -E "\.ns\.cloudflare\.com|ns[0-9]+\.cloudflare\.com"); then
# Let's see if it's a branded CF thing by checking the AS
if ! mtr -zrCc1 $(dig +short $MODE "$HOST" | tail -1) | tail -1 | cut -d, -f7 | grep -q '^AS13335$'; then
echo "This domain doesn't appear to have Cloudflare nameservers"
echo "Got answer:"
echo "$NAMESERVERS"
exit 1
else
echo "Domain uses white label Cloudflare nameservers"
echo "Example: $(echo "$NAMESERVERS" | head -1 | cut -f6)"
fi
fi
IPS="$(dig +short $MODE "$HOST")"
fi
for ip in $IPS; do
# Collect an mtr output to the IP
# We use this to get the ping time and the AS path
MTR="$(mtr -zrCc1 "$ip")"
# Extract the details out of mtr's output
PING="$(echo "$MTR" | tail -1 | cut -d, -f13)"
ASPATH="$(echo "$MTR" | cut -d, -f7 | grep 'AS[0-9]' | uniq | tr '\n' ' ')"
ASLAST="$(echo "$MTR" | cut -d, -f7 | grep 'AS[0-9]' | tail -1)"
# Is it actually a Cloudflare IP?
if [[ "$ASLAST" == "AS13335" ]]; then
# actual CF IP
# lets find what colo it's in
if [[ "$MODE" == "AAAA" ]]; then
TRACE="$(curl -s "http://[$ip]/cdn-cgi/trace")"
else
TRACE="$(curl -s "http://$ip/cdn-cgi/trace")"
fi
COLO="$(echo "$TRACE" | grep 'colo=' | cut -d= -f2)"
else
# not a CF IP
# don't send a suspicious /cdn-cgi/trace query to it
COLO="NotCF"
fi
echo "$ip $COLO ${PING}ms $ASPATH"
done
@zekesonxx
Copy link
Author

Handles typical users:

$ ./cfcheck.sh discord.com
162.159.136.232 ORD 8.98ms AS11114 AS13335 
162.159.135.232 ORD 26.18ms AS11114 AS13335 
162.159.138.232 IAD 6.65ms AS11114 AS13335 
162.159.137.232 ORD 23.76ms AS11114 AS13335 
162.159.128.233 ORD 23.85ms AS11114 AS13335 

Handles corporate CF domains:

$ ./cfcheck.sh cloudflare.com
104.16.133.229 ORD 8.88ms AS11114 AS13335 
104.16.132.229 IAD 26.32ms AS11114 AS13335

Handles whitelabel nameservers:

$ ./cfcheck.sh doordash.com
Domain uses white label Cloudflare nameservers
Example: ns1.doordash.com.
104.18.10.161 IAD 28.61ms AS11114 AS13335 
104.18.11.161 IAD 8.03ms AS11114 AS13335

Handles non-CF IPs served by CF nameservers:

$ ./cfcheck.sh shotbow.net
104.26.3.246 IAD 28.54ms AS11114 AS13335 
172.67.75.17 ORD 6.69ms AS11114 AS13335 
$ ./cfcheck.sh play.shotbow.net
us.shotbow.net. NotCF 4.94ms AS11114 AS2914 AS396998 
205.220.231.3 NotCF 4.93ms AS11114 AS2914 AS396998 

Handles not-Cloudflare gracefully:

$ ./cfcheck.sh google.com
This domain doesn't appear to have Cloudflare nameservers
Got answer:
google.com.             30      IN      NS      ns4.google.com.
google.com.             30      IN      NS      ns2.google.com.
google.com.             30      IN      NS      ns3.google.com.
google.com.             30      IN      NS      ns1.google.com.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment