Last active
October 4, 2023 19:33
-
-
Save AlexAtkinson/b3f18301d9dea5c2eb3f452260a03591 to your computer and use it in GitHub Desktop.
A quick dns propagation checker in BASH.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# -------------------------------------------------------------------------------------------------- | |
# dnsPropagationCheck.sh | |
# | |
# NOTE: Requires dnsServers.txt. Example: | |
# | |
#8.8.8.8 Google_1 | |
#8.8.4.4 Google_2 | |
#9.9.9.9 Quad9_1 | |
#149.112.112.112 Quad9_2 | |
#77.88.8.1 Yandex_1 | |
#77.88.8.8 Yandex_2 | |
#208.67.222.222 OpenDNS_1 | |
#208.67.220.220 OpenDNS_2 | |
#209.244.0.3 Level3_1 | |
#209.244.0.4 Level3_2 | |
#216.146.35.35 DYN_1 | |
#216.146.36.36 DYN_2 | |
#8.26.56.26 Comodo_1 | |
#8.20.247.20 Comodo_2 | |
#64.6.64.6 UltraDNS_1 | |
#64.6.65.6 UltraDNS_2 | |
#1.1.1.1 Cloudflare_1 | |
#1.0.0.1 Cloudflare_2 | |
#185.228.168.9 CleanBrowsing_1 | |
#185.228.169.9 CleanBrowsing_2 | |
#64.6.64.6 Verisign_1 | |
#64.6.65.6 Verisign_2 | |
#176.103.130.130 AdGuard_1 | |
#176.103.130.131 AdGuard_2 | |
# | |
# -------------------------------------------------------------------------------------------------- | |
# Help | |
# -------------------------------------------------------------------------------------------------- | |
help="\ | |
NAME | |
dnsPropagationCheck.sh | |
SYNOPSIS | |
${0##*/} [-h] [-t \e[04mtype\e[0m] [-d \e[04mdomain\e[0m] | |
DESCRIPTION | |
Retrieves the TTL of a DNS record from across many DNS servers. | |
The following options are available: | |
-h Print this menu. | |
-t \e[04mtype\e[0m | |
Specify the record type to check. | |
-d \e[04mdomain\e[0m | |
Specify the domain name to check. | |
EXAMPLES | |
The following retrieves the TTL of www.nike.com from accross man DNS servers. | |
./dnsPropagationCheck.sh -t cname -d www.nike.com | |
" | |
printHelp() { | |
echo -e "$help" >&2 | |
} | |
# -------------------------------------------------------------------------------------------------- | |
# Sanity (1/2) | |
# -------------------------------------------------------------------------------------------------- | |
if [[ "$1" != '-h' && $# -lt 4 ]]; then | |
printHelp | |
exit 1 | |
fi | |
if [[ ! -f dnsServers.txt ]]; then | |
echo -e "\e[01;31mERROR\e[0m: The file 'dnsServers.txt' is required." | |
exit 1 | |
fi | |
# -------------------------------------------------------------------------------------------------- | |
# Arguments | |
# -------------------------------------------------------------------------------------------------- | |
OPTIND=1 | |
while getopts "ht:d:" opt; do | |
case $opt in | |
h) | |
printHelp | |
exit 0 | |
;; | |
t) | |
arg_t='set' | |
arg_t_val=("$OPTARG") | |
;; | |
d) | |
arg_d='set' | |
arg_d_val=("$OPTARG") | |
;; | |
*) | |
echo -e "\e[01;31mERROR\e[00m: Invalid argument!" | |
printHelp | |
exit 1 | |
;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
# -------------------------------------------------------------------------------------------------- | |
# Sanity (2/2) | |
# -------------------------------------------------------------------------------------------------- | |
if [[ "$arg_t" == 'set' && "$arg_d" != 'set' ]]; then | |
echo -e "\e[01;31mERROR\e[0m: Both the DNS record type and domain name must be specified." | |
printHelp | |
exit 1 | |
fi | |
if [[ "$arg_t" != 'set' && "$arg_d" == 'set' ]]; then | |
echo -e "\e[01;31mERROR\e[0m: Both the DNS record type and domain name must be specified." | |
printHelp | |
exit 1 | |
fi | |
# -------------------------------------------------------------------------------------------------- | |
# Variables | |
# -------------------------------------------------------------------------------------------------- | |
recordType="$arg_t_val" | |
domain="$arg_d_val" | |
printf "\e[04mQuery Summary:\e[0m\n" | |
printf " Record Type: $recordType\n" | |
printf " Record Name: $domain\n\n" | |
col1="\e[04mServer\e[0m" | |
col2="\e[04mTTL\e[0m" | |
col3="\e[04mValue\e[0m" | |
printf "$col1" | |
printf '%*s' "$((${COLUMNS}-$((${COLUMNS}-$(wc -c<<<$col1)+60))))" | |
printf "$col2" | |
printf '%*s' "$((${COLUMNS}-$((${COLUMNS}-$(wc -c<<<$col2)+6))))" | |
printf "$col3\n" | |
while read -r line; do | |
server=$(awk '{print $1}' <<< $line) | |
name=$(echo $line | cut -d' ' -f2- | awk '{$1=$1;print}') | |
unset ttl | |
if nc -zv -w 1 $server 53 2>/dev/null; then | |
response=$(dig ${recordType} @${server} +tcp +noall +answer ${domain} | head -n1) | |
ttl=$(echo "$response" | awk '{print $2}') | |
[[ -z $ttl ]] && ttl='na' | |
val=$(echo "$response" | awk '{print $5}') | |
[[ -z $val ]] && val='na' | |
printf "$server" | |
printf '%*s' "$((${COLUMNS}-$((${COLUMNS}-$(wc -c<<<$server)+19))))" | |
printf "$name" | |
printf '%*s' "$((${COLUMNS}-$((${COLUMNS}-$(wc -c<<<$name)+31))))" | |
printf "$ttl" | |
printf '%*s' "$((${COLUMNS}-$((${COLUMNS}-$(wc -c<<<$ttl)+13))))" | |
printf "$val\n" | |
else | |
printf "ERROR: DNS server ${server} (${name}) could not be reached.\n" | |
fi | |
done <<< $(cat dnsServers.txt) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Outputs like: