Guest User

domain-check

a guest
Sep 3rd, 2019
1,300
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. #
  3. # Program: Domain Expiration Check <domain-check>
  4. #
  5. # Author: Matty < matty91 at gmail dot com >
  6. #
  7. # Current Version: 1.9
  8. #
  9. # Revision History:
  10. #  Version 1.9
  11. #    Bug fix and enhancement for .uk and .co.uk -- Vivek Gite <vivek@nixcraft.com>
  12. #
  13. #  Version 1.8
  14. #    Bug fix added $MAIL -- Vivek Gite <vivek@nixcraft.com>
  15. #
  16. #  Version 1.7
  17. #    Added support for .jp domain names  -- Vivek Gite <vivek@nixcraft.com>
  18. #
  19. #  Version 1.6
  20. #    Added support for .uk domain names; fixed a bug detecting tldtype  -- Vivek Gite <vivek@nixcraft.com>
  21. #
  22. #  Version 1.5
  23. #    Added support for .org, .in, .biz and .info domain names -- Vivek Gite <vivek@nixcraft.com>
  24. #
  25. #  Version 1.4
  26. #    Updated the documentation.
  27. #
  28. #  Version 1.3
  29. #    Gracefully Handle the case where the expiration data is unavailable
  30. #
  31. #  Version 1.2
  32. #    Added "-s" option to allow arbitrary registrars
  33. #
  34. #  Version 1.1
  35. #    Fixed issue with 'e' getopt string -- Pedro Alves
  36. #
  37. #  Version 1.0
  38. #    Initial Release
  39. #
  40. # Last Updated: 07-Aug-2012
  41. #
  42. # Purpose:
  43. #  domain-check checks to see if a domain has expired. domain-check
  44. #  can be run in interactive and batch mode, and provides faciltities
  45. #  to alarm if a domain is about to expire.
  46. #
  47. # License:
  48. #  This program is distributed in the hope that it will be useful,
  49. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  50. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  51. #
  52. # Notes:
  53. #   Since each registrar provides expiration data in a unique format (if
  54. #   they provide it at all), domain-check is currently only able to
  55. #   processess expiration information for a subset of the available
  56. #   registrars.
  57. #
  58. # Requirements:
  59. #   Requires whois
  60. #
  61. # Installation:
  62. #   Copy the shell script to a suitable location
  63. #
  64. # Tested platforms:
  65. #  -- Solaris 9 using /bin/bash
  66. #  -- Solaris 10 using /bin/bash
  67. #  -- OS X 10.4.2 using /bin/sh
  68. #  -- OpenBSD using /bin/sh
  69. #  -- FreeBSD using /bin/sh
  70. #  -- Redhat advanced server 3.0MU3 using /bin/sh
  71. #
  72. # Usage:
  73. #  Refer to the usage() sub-routine, or invoke domain-check
  74. #  with the "-h" option.
  75. #
  76. # Example:
  77. #
  78. #  The first example will print the expiration date and registrar for prefetch.net:
  79. #
  80. #  $ domain-check.sh -d prefetch.net
  81. #
  82. #  Domain                              Registrar         Status   Expires     Days Left
  83. #  ----------------------------------- ----------------- -------- ----------- ---------
  84. #  prefetch.net                        INTERCOSMOS MEDIA Valid    13-feb-2006   64  
  85. #
  86. #  The second example prints the expiration date and registrar for the domains
  87. #  listed in the file "domains":
  88. #
  89. #  $ domain-check.sh -f domains    
  90. #
  91. #  Domain                              Registrar         Status   Expires     Days Left
  92. #  ----------------------------------- ----------------- -------- ----------- ---------
  93. #  sun.com                             NETWORK SOLUTIONS Valid    20-mar-2010   1560
  94. #  google.com                          EMARKMONITOR INC. Valid    14-sep-2011   2103
  95. #  ack.com                             NETWORK SOLUTIONS Valid    09-may-2008   880  
  96. #  prefetch.net                        INTERCOSMOS MEDIA Valid    13-feb-2006   64  
  97. #  spotch.com                          GANDI             Valid    03-dec-2006   357  
  98. #
  99. #  The third example will e-mail the address admin@prefetch.net with the domains that
  100. #  will expire in 60-days or less:
  101. #
  102. #  $ domain-check -a -f domains -q -x 60 -e admin@prefetch.net  
  103. #
  104.  
  105. PATH=/bin:/usr/bin:/usr/local/bin:/usr/local/ssl/bin:/usr/sfw/bin ; export PATH
  106.  
  107. # Who to page when an expired domain is detected (cmdline: -e)
  108. ADMIN="info@vasepodjetje.si"
  109.  
  110. # Mail from:
  111. MFROM="From: Vase podjetje d.o.o. <info@vasepodjetje.si>"
  112.  
  113. # Number of days in the warning threshhold  (cmdline: -x)
  114. WARNDAYS=30
  115.  
  116. # If QUIET is set to TRUE, don't print anything on the console (cmdline: -q)
  117. QUIET="FALSE"
  118.  
  119. # Don't send emails by default (cmdline: -a)
  120. ALARM="FALSE"
  121.  
  122. # Whois server to use (cmdline: -s)
  123. WHOIS_SERVER="whois.internic.org"
  124.  
  125. # Location of system binaries
  126. AWK="/usr/bin/awk"
  127. WHOIS="/usr/bin/whois"
  128. DATE="/bin/date"
  129. CUT="/usr/bin/cut"
  130. MAIL="/usr/bin/mail"
  131. # Place to stash temporary files
  132. WHOIS_TMP="/var/tmp/whois.$$"
  133.  
  134. #############################################################################
  135. # Purpose: Convert a date from MONTH-DAY-YEAR to Julian format
  136. # Acknowledgements: Code was adapted from examples in the book
  137. #                   "Shell Scripting Recipes: A Problem-Solution Approach"
  138. #                   ( ISBN 1590594711 )
  139. # Arguments:
  140. #   $1 -> Month (e.g., 06)
  141. #   $2 -> Day   (e.g., 08)
  142. #   $3 -> Year  (e.g., 2006)
  143. #############################################################################
  144. date2julian()
  145. {
  146.     if [ "${1} != "" ] && [ "${2} != ""  ] && [ "${3}" != "" ]
  147.     then
  148.          ## Since leap years add aday at the end of February,
  149.          ## calculations are done from 1 March 0000 (a fictional year)
  150.          d2j_tmpmonth=$((12 * ${3} + ${1} - 3))
  151.        
  152.           ## If it is not yet March, the year is changed to the previous year
  153.           d2j_tmpyear=$(( ${d2j_tmpmonth} / 12))
  154.        
  155.           ## The number of days from 1 March 0000 is calculated
  156.           ## and the number of days from 1 Jan. 4713BC is added
  157.           echo $(( (734 * ${d2j_tmpmonth} + 15) / 24 -  2 * ${d2j_tmpyear} + ${d2j_tmpyear}/4
  158.                         - ${d2j_tmpyear}/100 + ${d2j_tmpyear}/400 + $2 + 1721119 ))
  159.     else
  160.           echo 0
  161.     fi
  162. }
  163.  
  164. #############################################################################
  165. # Purpose: Convert a string month into an integer representation
  166. # Arguments:
  167. #   $1 -> Month name (e.g., Sep)
  168. #############################################################################
  169. getmonth()
  170. {
  171.        LOWER=`tolower $1`
  172.              
  173.        case ${LOWER} in
  174.              jan) echo 1 ;;
  175.              feb) echo 2 ;;
  176.              mar) echo 3 ;;
  177.              apr) echo 4 ;;
  178.              may) echo 5 ;;
  179.              jun) echo 6 ;;
  180.              jul) echo 7 ;;
  181.              aug) echo 8 ;;
  182.              sep) echo 9 ;;
  183.              oct) echo 10 ;;
  184.              nov) echo 11 ;;
  185.              dec) echo 12 ;;
  186.                *) echo  0 ;;
  187.        esac
  188. }
  189.  
  190. #############################################################################
  191. # Purpose: Calculate the number of seconds between two dates
  192. # Arguments:
  193. #   $1 -> Date #1
  194. #   $2 -> Date #2
  195. #############################################################################
  196. date_diff()
  197. {
  198.         if [ "${1}" != "" ] &&  [ "${2}" != "" ]
  199.         then
  200.                 echo $(expr ${2} - ${1})
  201.         else
  202.                 echo 0
  203.         fi
  204. }
  205.  
  206. ##################################################################
  207. # Purpose: Converts a string to lower case
  208. # Arguments:
  209. #   $1 -> String to convert to lower case
  210. ##################################################################
  211. tolower()
  212. {
  213.      LOWER=`echo ${1} | tr [A-Z] [a-z]`
  214.      echo $LOWER
  215. }
  216.  
  217. ##################################################################
  218. # Purpose: Access whois data to grab the registrar and expiration date
  219. # Arguments:
  220. #   $1 -> Domain to check
  221. ##################################################################
  222. check_domain_status()
  223. {
  224.     local REGISTRAR=""
  225.     # Avoid WHOIS LIMIT EXCEEDED - slowdown our whois client by adding 3 sec
  226.     sleep 7
  227.     # Save the domain since set will trip up the ordering
  228.     DOMAIN=${1}
  229.     TLDTYPE="`echo ${DOMAIN} | cut -d '.' -f3 | tr '[A-Z]' '[a-z]'`"
  230.     if [ "${TLDTYPE}"  == "" ];
  231.     then
  232.         TLDTYPE="`echo ${DOMAIN} | cut -d '.' -f2 | tr '[A-Z]' '[a-z]'`"
  233.     fi
  234.  
  235.     # Invoke whois to find the domain registrar and expiration date
  236.     #${WHOIS} -h ${WHOIS_SERVER} "=${1}" > ${WHOIS_TMP}
  237.     # Let whois select server
  238.     if [ "${TLDTYPE}"  == "org" ];
  239.     then
  240.         ${WHOIS} -h "whois.pir.org" "${1}" > ${WHOIS_TMP}
  241.     elif [ "${TLDTYPE}"  == "in" ]; # India
  242.     then
  243.         ${WHOIS} -h "whois.registry.in" "${1}" > ${WHOIS_TMP}
  244.     elif [ "${TLDTYPE}"  == "uk" ]; # United Kingdom  
  245.     then
  246.         ${WHOIS} -h "whois.nic.uk" "${1}" > ${WHOIS_TMP}
  247.     elif [ "${TLDTYPE}"  == "si" ]; # Slovenia
  248.     then
  249.         ${WHOIS} -h "whois.arnes.si" "${1}" > ${WHOIS_TMP}
  250.     elif [ "${TLDTYPE}"  == "biz" ];
  251.     then
  252.         ${WHOIS} -h "whois.neulevel.biz" "${1}" > ${WHOIS_TMP}
  253.     elif [ "${TLDTYPE}"  == "info" ];
  254.     then
  255.         ${WHOIS} -h "whois.afilias.info" "${1}" > ${WHOIS_TMP}
  256.     elif [ "${TLDTYPE}"  == "jp" ]; # Japan
  257.     then
  258.         ${WHOIS} -h "whois.jprs.jp" "${1}" > ${WHOIS_TMP}
  259.  
  260.     elif [ "${TLDTYPE}"  == "com" -o "${TLDTYPE}"  == "net" -o "${TLDTYPE}"  == "edu" ];
  261.     then
  262.     ${WHOIS} -h ${WHOIS_SERVER} "=${1}" > ${WHOIS_TMP}
  263.     else
  264.     ${WHOIS} "${1}" > ${WHOIS_TMP}
  265.     fi
  266.  
  267.     # Parse out the expiration date and registrar -- uses the last registrar it finds
  268.     REGISTRAR=`cat ${WHOIS_TMP} | ${AWK} -F: '/Registrar/ && $2 != ""  { REGISTRAR=substr($2,2,17) } END { print REGISTRAR }'`
  269.  
  270.     if [ "${TLDTYPE}" == "uk" ]; # for .uk domain
  271.     then
  272.     REGISTRAR=`cat ${WHOIS_TMP} | ${AWK} -F: '/Registrar:/ && $0 != ""  { getline; REGISTRAR=substr($0,2,17) } END { print REGISTRAR }'`
  273.     elif [ "${TLDTYPE}" == "si" ]; # for Slovenian domains
  274.     then
  275.         REGISTRAR=`cat ${WHOIS_TMP} | ${AWK} '/registrar:/ { print $2 }'`
  276.     elif [ "${TLDTYPE}" == "jp" ];
  277.     then
  278.         REGISTRAR=`cat ${WHOIS_TMP} | ${AWK} '/Registrant/ && $2 != ""  { REGISTRAR=substr($2,1,17) } END { print REGISTRAR }'`
  279.  
  280.      fi
  281.  
  282.     # If the Registrar is NULL, then we didn't get any data
  283.     if [ "${REGISTRAR}" = "" ]
  284.     then
  285.         prints "$DOMAIN" "Unknown" "Unknown" "Unknown" "Unknown"
  286.         return
  287.     fi
  288.  
  289.     # The whois Expiration data should resemble the following: "Expiration Date: 09-may-2008"
  290.  
  291.     # for .in, .info, .org domains
  292.     if [ "${TLDTYPE}" == "in" -o "${TLDTYPE}" == "info" -o "${TLDTYPE}" == "org" ];
  293.     then
  294.         DOMAINDATE=`cat ${WHOIS_TMP} | ${AWK} '/Expiration Date:/ { print $2 }' | cut -d':' -f2`
  295.     elif [ "${TLDTYPE}" == "biz" ]; # for .biz domain
  296.     then
  297.             DOMAINDATE=`cat ${WHOIS_TMP} | awk '/Domain Expiration Date:/ { print $6"-"$5"-"$9 }'`
  298.     elif [ "${TLDTYPE}" == "uk" ]; # for .uk domain
  299.     then
  300.             DOMAINDATE=`cat ${WHOIS_TMP} | awk '/Renewal date:/ || /Expiry date:/ { print $3 }'`
  301.     elif [ "${TLDTYPE}" == "si" ]; # for .si domain
  302.     then
  303.             DOMAINDATE=`cat ${WHOIS_TMP} | awk '/expire:/ { d="date +\"%d-%b-%Y\" -d \""$2"\""; d | getline v; print v; close (d) }'`
  304.     elif [ "${TLDTYPE}" == "jp" ]; # for .jp 2010/04/30
  305.     then
  306.         tdomdate=`cat ${WHOIS_TMP} | awk '/Expires on/ { print $3 }'`
  307.             tyear=`echo ${tdomdate} | cut -d'/' -f1`
  308.             tmon=`echo ${tdomdate} | cut -d'/' -f2`
  309.            case ${tmon} in
  310.                  1|01) tmonth=jan ;;
  311.                  2|02) tmonth=feb ;;
  312.                  3|03) tmonth=mar ;;
  313.                  4|04) tmonth=apr ;;
  314.                  5|05) tmonth=may ;;
  315.                  6|06) tmonth=jun ;;
  316.                  7|07) tmonth=jul ;;
  317.                  8|08) tmonth=aug ;;
  318.                  9|09) tmonth=sep ;;
  319.                  10)tmonth=oct ;;
  320.                  11) tmonth=nov ;;
  321.                  12) tmonth=dec ;;
  322.                       *) tmonth=0 ;;
  323.         esac
  324.             tday=`echo ${tdomdate} | cut -d'/' -f3`
  325.         DOMAINDATE=`echo $tday-$tmonth-$tyear`
  326.     else # .com, .edu, .net and may work with others     
  327.         DOMAINDATE=`cat ${WHOIS_TMP} | ${AWK} '/Expiration/ { print $NF }'`
  328.     fi
  329.  
  330.     #echo $DOMAINDATE # debug
  331.     # Whois data should be in the following format: "13-feb-2006"
  332.     IFS="-"
  333.     set -- ${DOMAINDATE}
  334.     MONTH=$(getmonth ${2})
  335.     IFS=""
  336.  
  337.     # Convert the date to seconds, and get the diff between NOW and the expiration date
  338.     DOMAINJULIAN=$(date2julian ${MONTH} ${1#0} ${3})
  339.     DOMAINDIFF=$(date_diff ${NOWJULIAN} ${DOMAINJULIAN})
  340.  
  341.     if [ ${DOMAINDIFF} -lt 0 ]
  342.     then
  343.           if [ "${ALARM}" = "TRUE" ]
  344.           then
  345.                 echo "Domena ${DOMAIN} je potekla!" \
  346.                 | ${MAIL} -s "Domena ${DOMAIN} je potekla!" ${ADMIN}
  347.            fi
  348.  
  349.            prints ${DOMAIN} "Poteklo" "${DOMAINDATE}" "${DOMAINDIFF}" ${REGISTRAR}
  350.  
  351.     elif [ ${DOMAINDIFF} -lt ${WARNDAYS} ]
  352.     then
  353.            if [ "${ALARM}" = "TRUE" ]
  354.            then
  355.                     echo "Domena ${DOMAIN} bo potekla dne ${DOMAINDATE}" \
  356.                     | ${MAIL} -a $MFROM -s "Domena ${DOMAIN} bo potekla v ${WARNDAYS}-dnevih ali manj" ${ADMIN}
  357.             fi
  358.             prints ${DOMAIN} "Hmalu Poteklo" "${DOMAINDATE}" "${DOMAINDIFF}" "${REGISTRAR}"
  359.      else
  360.             prints ${DOMAIN} "Valid" "${DOMAINDATE}"  "${DOMAINDIFF}" "${REGISTRAR}"
  361.      fi
  362. }
  363.  
  364. ####################################################
  365. # Purpose: Print a heading with the relevant columns
  366. # Arguments:
  367. #   None
  368. ####################################################
  369. print_heading()
  370. {
  371.         if [ "${QUIET}" != "TRUE" ]
  372.         then
  373.                 printf "\n%-35s %-17s %-8s %-11s %-5s\n" "Domain" "Registrar" "Status" "Expires" "Days left"
  374.                 echo "----------------------------------- ----------------- -------- ----------- ---------"
  375.         fi
  376. }
  377.  
  378. #####################################################################
  379. # Purpose: Print a line with the expiraton interval
  380. # Arguments:
  381. #   $1 -> Domain
  382. #   $2 -> Status of domain (e.g., expired or valid)
  383. #   $3 -> Date when domain will expire
  384. #   $4 -> Days left until the domain will expire
  385. #   $5 -> Domain registrar
  386. #####################################################################
  387. prints()
  388. {
  389.     if [ "${QUIET}" != "TRUE" ]
  390.     then
  391.             MIN_DATE=$(echo $3 | ${AWK} '{ print $1, $2, $4 }')
  392.             printf "%-35s %-17s %-8s %-11s %-5s\n" "$1" "$5" "$2" "$MIN_DATE" "$4"
  393.     fi
  394. }
  395.  
  396. ##########################################
  397. # Purpose: Describe how the script works
  398. # Arguments:
  399. #   None
  400. ##########################################
  401. usage()
  402. {
  403.         echo "Usage: $0 [ -e email ] [ -x expir_days ] [ -q ] [ -a ] [ -h ]"
  404.         echo "          {[ -d domain_namee ]} || { -f domainfile}"
  405.         echo ""
  406.         echo "  -a               : Send a warning message through email "
  407.         echo "  -d domain        : Domain to analyze (interactive mode)"
  408.         echo "  -e email address : Email address to send expiration notices"
  409.         echo "  -f domain file   : File with a list of domains"
  410.         echo "  -h               : Print this screen"
  411.         echo "  -s whois server  : Whois sever to query for information"
  412.         echo "  -q               : Don't print anything on the console"
  413.         echo "  -x days          : Domain expiration interval (eg. if domain_date < days)"
  414.         echo ""
  415. }
  416.  
  417. ### Evaluate the options passed on the command line
  418. while getopts ae:f:hd:s:qx: option
  419. do
  420.         case "${option}"
  421.         in
  422.                 a) ALARM="TRUE";;
  423.                 e) ADMIN=${OPTARG};;
  424.                 d) DOMAIN=${OPTARG};;
  425.                 f) SERVERFILE=$OPTARG;;
  426.                 s) WHOIS_SERVER=$OPTARG;;
  427.                 q) QUIET="TRUE";;
  428.                 x) WARNDAYS=$OPTARG;;
  429.                 \?) usage
  430.                     exit 1;;
  431.         esac
  432. done
  433.  
  434. ### Check to see if the whois binary exists
  435. if [ ! -f ${WHOIS} ]
  436. then
  437.         echo "ERROR: The whois binary does not exist in ${WHOIS} ."
  438.         echo "  FIX: Please modify the \$WHOIS variable in the program header."
  439.         exit 1
  440. fi
  441.  
  442. ### Check to make sure a date utility is available
  443. if [ ! -f ${DATE} ]
  444. then
  445.         echo "ERROR: The date binary does not exist in ${DATE} ."
  446.         echo "  FIX: Please modify the \$DATE variable in the program header."
  447.         exit 1
  448. fi
  449.  
  450. ### Baseline the dates so we have something to compare to
  451. MONTH=$(${DATE} "+%m")
  452. DAY=$(${DATE} "+%d")
  453. YEAR=$(${DATE} "+%Y")
  454. NOWJULIAN=$(date2julian ${MONTH#0} ${DAY#0} ${YEAR})
  455.  
  456. ### Touch the files prior to using them
  457. touch ${WHOIS_TMP}
  458.  
  459. ### If a HOST and PORT were passed on the cmdline, use those values
  460. if [ "${DOMAIN}" != "" ]
  461. then
  462.         print_heading
  463.         check_domain_status "${DOMAIN}"
  464. ### If a file and a "-a" are passed on the command line, check all
  465. ### of the domains in the file to see if they are about to expire
  466. elif [ -f "${SERVERFILE}" ]
  467. then
  468.         print_heading
  469.         while read DOMAIN
  470.         do
  471.                 check_domain_status "${DOMAIN}"
  472.  
  473.         done < ${SERVERFILE}
  474.  
  475. ### There was an error, so print a detailed usage message and exit
  476. else
  477.         usage
  478.         exit 1
  479. fi
  480.  
  481. # Add an extra newline
  482. echo
  483.  
  484. ### Remove the temporary files
  485. rm -f ${WHOIS_TMP}
  486.  
  487. ### Exit with a success indicator
  488. exit 0
RAW Paste Data