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