Page 1 of 1

Building a whois script to report days left Rate Topic: ***** 1 Votes

#1 no2pencil  Icon User is offline

  • Admiral Fancy Pants
  • member icon

Reputation: 5322
  • View blog
  • Posts: 27,231
  • Joined: 10-May 07

Posted 05 December 2013 - 03:27 PM

For building my whois script, I have two scripts & one text file.

Quote

~ $ ls
checkall.sh domains.txt whois.sh

whois.sh is a stand alone script that runs whois, & parses the heck out of the return.
checkall.sh is a script that will read in the domain list, & run whois.sh on each domain.

whois.sh will return with exit codes, so it's easily used with nagios.

Ok, so the first thing that we do here is check the arguments passed to whois.sh.
#!/bin/bash

if [ ! $1 ]; then
  echo Usage $0 '(domain)'
  exit 1
fi
which whois >/dev/null 2>&1
if [ $? -ne 0 ]; then
  echo Please install whois
  exit
fi
DEBUG=0
if [ $2 ]; then
  DEBUG=1
fi



At this point we have verified that we have a domain name, the whois command is installed, & we have or don't have the debug value. The debug value is simply used to echo out the days left from whois on the domain. If we are using this & only want to see warnings & critical, then just omit the debug value in the command line. Otherwise we get a full listing in the output.

Now we set the domain name from the argument passed, & we setup our warning & critical values.
domain=`echo $1`
warn=60
crit=30



Here we get the output from whois & grep just for the expire line. I've noticed that based on the domain registrar the expire line can be many things, but is always capital E followed by xp. Lastly we always force multiple spaces to condense to one single space with tr. tr -s " " will for " " to be " ", or 3 spaces to 1. This is important for the cut delimiter we use later.

expire_text=`whois ${domain} | grep Exp | tr -s " "`



echo ${expire_text} | grep GMT >/dev/null 2>&1
if [ $? -eq 0 ]; then
  ## eNom (Sun May 03 23:59:59 GMT 2015)
  text=`echo ${expire_text} | cut -d: -f2,3,4`
  day=`echo ${text} | cut -d' ' -f3`
  month=`echo ${text} | cut -d' ' -f2`
  year=`echo ${text} | cut -d' ' -f6`
  text=`echo ${month}-$day-${year}`



Above we echo the output from our first grep & tr to check for GMT. I've noticed that only eNom registrars will use GMT, but they also foobar up the entire date string. So here we correct that.

else
  echo ${expire_text} | grep : >/dev/null 2>&1
  if [ $? -ne 0 ]; then
     ## Yahoo
     text=`echo ${expire_text} | sed 's/: /:/g' | cut -d: -f2 | cut -d' ' -f5`
  else
     ## GoDaddy / eNom
     text=`echo ${expire_text} | sed 's/: /:/g' | cut -d: -f2 | cut -d' ' -f1`
  fi
fi



Above here we are not in GMT, so we check for the semi-colon. If we have it, force any semi-colons followed by a space to remove the space. Then we cut by the line, delimited by a space character, & depending on our grep output we are looking for the fifth or first set of characters.

echo ${expire_text} | grep "\." >/dev/null 2>&1
if [ $? -eq 0 ]; then
  ## Yahoo?  Expiry Date.......... 2014-04-06
  text=`echo ${expire_text} | tr -s "." | cut -d' ' -f3`
fi



Above we have our last registrar. Some Yahoo domains have this funky, Expiry line, a ton of spaces, & a date. Notice that there are no semi-colons, & that makes the if/else easier as we can do this outside of the above statements. Condense the periods to one, grep by space & take line 3 & we have our expiration date.

if [ $? -ne 0 ]; then
  echo Something failed looking the whois information for ${domain}
  echo Please try again later
  exit 1
fi


If there is another domain name registrar I don't have here, please end it to me. As I'm just bailing out for now on a lack of one.

Next we set up our dates for comparison & convert to unix date time stamp. It's good to have a common denominator.

today=`date +%F`
expire_unix=`date --date=${text} +"%s"`
today_unix=`date --date=${today} +"%s"`



Lastly we do some math... & print if we feel we should
daysleft=$(( ($expire_unix - $today_unix) / 60 / 60 / 24 ))
if [ ${DEBUG} -gt 0 ]; then
  echo ${daysleft} - ${domain}
fi



& return the results!
if [ ${daysleft} -gt ${warn} ] ;then
  exit 0
fi
if [ ${daysleft} -lt ${warn} ]; then
  exit 1
fi
if [ ${daysleft} -lt ${crit} ]; then
  exit 2
fi




So that wasn't so bad. We gathered some text, created some dates, & reported our results. Now lets make a process out of it!

#!/bin/bash

DEBUG=' '
if [ $1 ]; then
  DEBUG=1
fi



Ok ok, you're probably wondering why debug is argument 1 here, & 2 above. Well that's because this script doesn't take any other arguments. It simply passes debug from here to the next script. It's cheap, but that's what I came up with.

Now we gather our domains into an array
domains=`cat domains.txt`



Then we parse the array, run the script, & act upon the return code

for domain in ${domains}
do
  ./whois.sh ${domain} ${DEBUG}
  case $? in
    2)
      echo ${domain} is within 30 days
    ;;
    1)
      echo ${domain} is within 60 days
    ;;
    0)
      #echo ${domain} is not in warning of registration
    ;;
    *)
      echo Checking ${domain} failed for some reason
    ;;
  esac
done



Couldn't be simpler!

Using our exmaple domains below, we get the following output :

Quote

~ $ sh checkall.sh debug
1546 - dreamincode.net
250 - dreamincode.com
2474 - google.com
3331 - yahoo.com
2929 - yelp.com


Try it with your domains, & see what you can come up with!

Again, if there was any registrar that I'm not parsing for, let me know as I'd love to ad it.

Full Code :

whois.sh
#!/bin/bash

if [ ! $1 ]; then
  echo Usage $0 '(domain)'
  exit 1
fi
which whois >/dev/null 2>&1
if [ $? -ne 0 ]; then
  echo Please install whois
  exit
fi
DEBUG=0
if [ $2 ]; then
  DEBUG=1
fi

domain=`echo $1`
warn=60
crit=30
expire_text=`whois ${domain} | grep Exp | tr -s " "`
echo ${expire_text} | grep GMT >/dev/null 2>&1
if [ $? -eq 0 ]; then
  ## eNom (Sun May 03 23:59:59 GMT 2015)
  text=`echo ${expire_text} | cut -d: -f2,3,4`
  day=`echo ${text} | cut -d' ' -f3`
  month=`echo ${text} | cut -d' ' -f2`
  year=`echo ${text} | cut -d' ' -f6`
  text=`echo ${month}-$day-${year}`
else
  echo ${expire_text} | grep : >/dev/null 2>&1
  if [ $? -ne 0 ]; then
     ## Yahoo
     text=`echo ${expire_text} | sed 's/: /:/g' | cut -d: -f2 | cut -d' ' -f5`
  else
     ## GoDaddy / eNom
     text=`echo ${expire_text} | sed 's/: /:/g' | cut -d: -f2 | cut -d' ' -f1`
  fi
fi

echo ${expire_text} | grep "\." >/dev/null 2>&1
if [ $? -eq 0 ]; then
  ## Yahoo?  Expiry Date.......... 2014-04-06
  text=`echo ${expire_text} | tr -s "." | cut -d' ' -f3`
fi

if [ $? -ne 0 ]; then
  echo Something failed looking the whois information for ${domain}
  echo Please try again later
  exit 1
fi
today=`date +%F`
expire_unix=`date --date=${text} +"%s"`
today_unix=`date --date=${today} +"%s"`
daysleft=$(( ($expire_unix - $today_unix) / 60 / 60 / 24 ))
if [ ${DEBUG} -gt 0 ]; then
  echo ${daysleft} - ${domain}
fi
if [ ${daysleft} -gt ${warn} ] ;then
  exit 0
fi
if [ ${daysleft} -lt ${warn} ]; then
  exit 1
fi
if [ ${daysleft} -lt ${crit} ]; then
  exit 2
fi



checkall.sh
#!/bin/bash

DEBUG=' '
if [ $1 ]; then
  DEBUG=1
fi
domains=`cat domains.txt`
for domain in ${domains}
do
  ./whois.sh ${domain} ${DEBUG}
  case $? in
    2)
      echo ${domain} is within 30 days
    ;;
    1)
      echo ${domain} is within 60 days
    ;;
    0)
      #echo ${domain} is not in warning of registration
    ;;
    *)
      echo Checking ${domain} failed for some reason
    ;;
  esac
done



domains.txt

Quote

dreamincode.net
dreamincode.com
google.com
yahoo.com
yelp.com


Is This A Good Question/Topic? 1
  • +

Page 1 of 1