I’ve recently dragged all of my DNS records from Site5. It only took me six years to finally get off that godawful hosting service. In retrospect, keeping a better track of all DNS records would not have wasted time. Then again, I would not be a sysadmin if I wasn’t tremendously lazy.

Having gone through this DNS ordeal, I decided to keep better records. Tracking SLDs – igoroseledko.com, igoros.com, etc. – is no biggie, as I don’t have many of those. The real pain in the neck is all the CNAMEs. In the ideal world, you could do AXFR from your DNS provider. Realistically, AXFR would require a premium DNS service with secondary DNS and all added expense and complexity that comes with such a setup.

My solution was to maintain a text file containing a list of SLDs, subdomains, and other records I created. Here’s an example:

igoroseledko.com
www.igoroseledko.com
mail.igoroseledko.com

And then, I wrote a script that would go through this list of records and pull all the details from the authoritative DNS servers. The resulting CSV file looks something like this:

Record,TLD,SLD,3LD,4LD,Type,TTL,Value
igoroseledko.com,com,igoroseledko.com,none,none,A,600,72.94.59.26
igoroseledko.com,com,igoroseledko.com,none,none,NS,3600,ns31.domaincontrol.com
igoroseledko.com,com,igoroseledko.com,none,none,NS,3600,ns32.domaincontrol.com
igoroseledko.com,com,igoroseledko.com,none,none,SOA,3600,600
www.igoroseledko.com,com,igoroseledko.com,www.igoroseledko.com,none,CNAME,3525,igoroseledko.com

The script is below; you can also get it from my GitHub page.

The script
#!/bin/bash
list=""
if [ ! -r "${list}" ]; then exit 1 ; fi
grep . "${list}" | awk -F. '{print $(NF-1)"."$NF}' | sort -u |
while read m
do
  egrep "${m}(\s|$)" "${list}" | sort -u | while read i
  do
    unset array_variables array_values
    levels=$(echo "${i}" | sed 's/[^.]//g' | awk '{ print length+1 }')
    array_variables=($(for j in $(seq 1 ${levels}); do echo s${j}ld; done))
    array_values=($(for l in $(seq ${levels} -1 1); do echo "${i}" | awk -F. -v f=${l} '{s = ""; for (i = f; i <= NF; i++) s = s$i " "; print s }' | sed 's/\s/./g' | sed 's/\.$//g'; done))
    for ((k = 0; k < ${#array_variables[@]}; k++))
    do
      eval "$(echo "${array_variables[$k]}")"="$(echo "\"${array_values[$k]}\"")"
    done
    dig ${i} @$(dig ns ${i} 2>/dev/null | \
    egrep -m1 "^${i}.*IN.(CNAME|NS)" | awk '{print $NF}' | \
    sed 's/\.$//g') -t any 2>/dev/null | grep -v \; | grep . | while read line
    do
      t=$(echo "${line}" | awk '{print $4}')
      r=$(echo "${line}" | awk '{print $1}')
      ttl=$(echo "${line}" | awk '{print $2}')
      v=$(echo "${line}" | awk '{print $NF}' | sed 's/\.$//g')
      echo "${i:-none},${s1ld:-none},${s2ld:-none},${s3ld:-none},${s4ld:-none},${t:-none},${ttl:-none},${v:-none}"
    done
  done
done | (echo "Record,TLD,SLD,3LD,4LD,Type,TTL,Value" && cat)