#!/bin/sh # # Program: Website content check # # Author: Matty < matty91 at gmail dot com > # # Current Version: 1.2 # # Revision History: # # Version 1.2 # Check for connection timeouts # # Version 1.1 # Added additional logging # # Version 1.0 # Initial Release # # Last Updated: 12-02-2006 # # Purpose: # The content-check script can be used to checksum a webpage returned from a server, and # generate E-mail notifications if the content doesn't hash to a saved hash. This can # help spot problems with servers that are accepting connections, but failing to return # valid content (e.g., when a bad code deployment occurs). # # License: # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Installation: # Copy the shell script to a suitable location # # Usage: # To use content-check, you will need to first generate a checksum of the site # you would like to monitor. You can acquire a checksum for a site by passing # the site to check to the "-g" option: # # $ content-check -g http://prefetch.net/index.html # cd116f4c65952075ac3e374666f13c507685e5e7 # # Once the hash is calculated, you can add the site and hash to a file: # # $ echo "http://prefetch.net/index.html cd116f4c65952075ac3e374666f13c507685e5e7" >> sites # # The file can contain one or more site / checksum key value pairs. This file # can be passed as an argument to content-check's "-f" option. Content-check # will retrieve the page listed in the file, and compare a current checksum # to the one stored in the file. If content-check determines that the hashes # don't match, a syslog message will be logged, and an E-mail send to the # website administrator (the E-mail address can be passed to the "-e" option). PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH # Default user to send E-mail to ADMIN="root" # Paths to various binaries FACILITY="daemon.notice" LOGGER="/usr/bin/logger" MAIL="/usr/bin/mail" MKTEMP="/bin/mktemp" OPENSSL="/usr/sfw/bin/openssl" TIMEOUT=10 WGET="/usr/sfw/bin/wget" # Useful functions usage () { echo "Usage: $0 [ -e EMAIL_ADDRESS ] -g SITE || -f SITE FILE" echo " -e address : address to send alarms to" echo " -f site file : file with list of sites and checksums" echo " -g site : generate checksum for site" echo " -t timeout : set a timeout value" } # If no options are provided, print a help screen if [ $# -eq 0 ] then usage exit 0 fi # Parse the options that are passed to the script while getopts e:g:f:t: option do case "${option}" in e) ADMIN=${OPTARG} ;; f) SITES=${OPTARG} ;; g) GENERATE=${OPTARG} ;; t) TIMEOUT=${OPTARG} ;; \?) usage exit 1;; esac done # Check to make sure the utilities are present if [ ! -f ${WGET} ] || [ ! -f ${OPENSSL} ] || [ ! -f ${MAIL} ] || [ ! -f ${LOGGER} ] || [ ! -f ${MKTEMP} ] then echo "ERROR: Cannot find the logger, mail, mktemp, wget or openssl utilities" usage exit 1 fi # IF the "-g" option is present, print a checksum on the tty if [ "${GENERATE}" != "" ] then ${WGET} -q -O - "${GENERATE}" | ${OPENSSL} sha1 exit 0 fi # Sanity check the arguments if [ ! -f ${SITES} ] && [ "${GENERATE}" != "" ] then echo "ERROR: No options passed to script" usage exit 1 fi # Create a temporary file to store the results of the wget TMP=`${MKTEMP} /var/tmp/content.XXXXXX` # Cycle through the file and send E-mail for each # checksum that doesn't match cat ${SITES} | while read SITE CHECKSUM do # Make sure all entries are key / value pairs if [ "${SITE}" = "" ] || [ "${CHECKSUM}" = "" ] then ${LOGGER} -p ${FACILITY} "ERROR: Trouble processing ${SITE} in ${SITES}" echo "ERROR: Trouble processing ${SITE} in ${SITES}" exit 1 fi # Grab the page from the website ${WGET} -t 1 -T ${TIMEOUT} -q -O ${TMP} ${SITE} # If unable to resolve name or create a TCP connection, bail # out and log an error if [ $? -ne 0 ] then ${LOGGER} -p ${FACILITY} "ERROR: Cannot establish connection to ${SITE}" echo "ERROR: Cannot establish connection to ${SITE}" exit 1 fi # Generate a checksum CURRENTCHECKSUM=`cat ${TMP} | ${OPENSSL} sha1` # Make sure the checksums match if [ "${CHECKSUM}" != "${CURRENTCHECKSUM}" ] then ${LOGGER} -p ${FACILITY} "ERROR: Content from ${SITE} did not hash to ${CHECKSUM}" echo "ERROR: Content from ${SITE} did not hash to ${CHECKSUM}" \ | ${MAIL} -s "${SITE} did not pass health check" ${ADMIN} fi done # Remove the temporary file, but be paranoid and double check that it exists if [ -f ${TMP} ] then rm -f ${TMP} fi exit 0