DNS Speed Test script

Pretty self-explanatory.
A Little script to test a handful of DNS resolvers.
(pings wikipedia.org by default)
Intended for those interested in such information, such as those preparing optimizations, or for educational purposes.
Please let me know of any problems or if there is a DNS provider you think should be included.

Note: requires package bind

dns-speed-test.sh
#!/bin/env bash
#
# dns speed test
#
if [[ -z "$DOMAIN" ]]; then
DOMAIN=wikipedia.org
fi;
CURRENTDNS=$(dig "$DOMAIN" | grep SERVER | awk -F'[)(]' '{print $2}')
if [[ -z "$SKIP" ]]; then
echo
echo " Test common resolvers by calculating average response times of 3 queries."
echo
annc() {
echo 
echo " DNS Primary  Secondary"
echo 
echo " Adguard 94.140.14.14 94.140.15.15"
echo " Comodo 8.26.56.26 8.20.247.20"
echo " Control-D 76.76.2.2 76.76.10.2"
echo " Cloudflare 1.1.1.1 1.0.0.1"
echo " CyberGhost 38.132.106.139 194.187.251.67"
echo " Google 8.8.8.8 8.8.4.4"
echo " Neustar 156.154.70.5 156.154.71.2"
echo " NextDNS 45.90.28.97 45.90.30.97"
echo " OpenDNS 208.67.222.222 208.67.220.220"
echo " Quad9 9.9.9.9 149.112.112.112"
echo 
}
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
annc | column -tL
fi;
if [[ -n "$TESTDNS" ]]; then
echo "Custom Test DNS $TESTDNS"
fi
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
echo
while true; do
    read -p " Do you wish to flush the DNS cache? " yn
    case $yn in
        [Yy]* ) resolvectl flush-caches; break;;
        [Nn]* ) break;;
        * ) echo -e "\n Please answer yes or no.\n";;
    esac
done
echo
echo "Current DNS $CURRENTDNS"
   for reps in {1..3}
   do
    dig "$DOMAIN" | awk '/time/ {print $4 " ms"}'
    sleep 1
   done | awk '/ms/ {sum+=$1} END {print "Avg time: ",sum/3, " ms"}'
echo
if [[ -z "$SKIP" ]]; then
rank() {
for resolver in "Adguard 94.140.14.14" "Comodo 8.26.56.26" "Control-D 76.76.2.2" "Cloudflare 1.1.1.1" "CyberGhost 38.132.106.139" "Google 8.8.8.8" "Neustar 156.154.70.5" "NextDNS 45.90.28.97" "OpenDNS 208.67.222.222" "Quad9 9.9.9.9";
do
   echo $resolver
   for reps in {1..3}
   do
    dig "$DOMAIN" "@${resolver#* }" | awk '/time/ {print $4 " ms"}'
    sleep 1
   done | awk '/ms/ {sum+=$1} END {print "Avg time: ",sum/3, " ms"}'
   echo
done
}
rank;
fi;
if [[ -n "$TESTDNS" ]]; then
echo "Custom Test DNS $TESTDNS"
   for reps in {1..3}
   do
    dig "$DOMAIN" "@$TESTDNS" | awk '/time/ {print $4 " ms"}'
    sleep 1
   done | awk '/ms/ {sum+=$1} END {print "Avg time: ",sum/3, " ms"}'
echo
fi
exit

How to use
  • Create a text file containing the above data and saved as dns-speed-test.sh

  • Mark executable
    chmod +x dns-speed-test.sh

  • Run
    ./dns-speed-test.sh

  • (Optional) Add your own DNS for testing
    TESTDNS=176.103.130.130 ./dns-speed-test.sh

  • (Optional) Set your own target URL
    DOMAIN=manjaro.org ./dns-speed-test.sh

  • (Optional) Set SKIP variable to avoid running default sample tests
    SKIP=1 TESTDNS=1.1.1.1 ./dns-speed-test.sh


Edit/Update:

  • Removed extra DNS samples
  • Added $TESTDNS variable to allow extra DNS test on the fly.
  • Added $DOMAIN variable to allow setting ping test target URL.
  • Added $SKIP variable to avoid pinging sample DNS resolvers.
  • Added new resolvers
8 Likes

Considering this is a Linux forum I don’t know how happy people are going to be about the inclusion of Google’s DNS :sweat_smile:

Eh. So many people use chrome,brave,g-suite … and some might be agnostic and simply care about whats fastest.
I dont think many would be bothered by a lil ping , but I’d happily remove it if theres a deluge of unhappiness.
For now I will do something I had already intended - allow for skipping the sample DNS.

Edit… and done @fasto :wink:

Thanks. It worked fine. I had to install the Bind package to get it to work. Prior to the installation of bind I was getting:

dig command not found.

Just for fun I asked chatgpt to do this. The result is not as nice or functional as yours, but on the other hand took just seconds to produce. It picked the resolvers and targets by itself.

type or#!/bin/bash

# Define the list of DNS resolvers to test
resolvers=("1.1.1.1 Cloudflare" "8.8.8.8 Google" "9.9.9.9 Quad9" "208.67.222.222 OpenDNS" "208.67.220.220 OpenDNS" "185.228.168.9 CleanBrowsing" "185.228.169.9 CleanBrowsing" "64.6.64.6 Verisign")

# Define the list of web pages to query
webpages=("www.google.com" "www.facebook.com" "www.github.com")

# Loop through the DNS resolvers and web pages and calculate the average response time
for resolver in "${resolvers[@]}"
do
  resolver_ip=$(echo "$resolver" | awk '{print $1}')
  resolver_owner=$(echo "$resolver" | awk '{print $2}')
  printf "\nResolver: $resolver_ip ($resolver_owner)\n"
  for webpage in "${webpages[@]}"
  do
    total_time=0
    for i in {1..3}
    do
      time=$(dig "$webpage" +time=1 +tries=1 +noall +stats @"$resolver_ip" | awk '/Query time:/ {print $4}')
      total_time=$(echo "$total_time + $time" | bc)
    done
    average_time=$(echo "$total_time / 3" | bc)
    printf "Webpage: %-20s Average response time: %s ms\n" "$webpage" "$average_time"
  done
done

you just like to see the world burn, don’t you :smiley: