Your IP : 216.73.216.229


Current Path : /home/jeromecohp/www/aesecure/pro/crontab/
Upload File :
Current File : /home/jeromecohp/www/aesecure/pro/crontab/aesecure.sh

#!/bin/bash

# -------------------------------------------------------------------------------------------------------------------------------
# aesecure v2.0 - aeSecure (c) 2014-2015 Christophe Avonture
#
# Scan a folder recursively and list every files that have been modified during the last 60 minutes.   Send a notification email
# if such files are found.
#
# This script shouldn't be altered.
# 
# Initialization should be done in the aesecure.json file that is shipped with this script and should be placed in the same folder.
# Open aesecure.json and update its content to fit your needs.
# 
# Once done, add a job in your cron and schedule this script to be fired every hour.  Be sure to synchronize the duration 
# (in the json file (in minutes)) and your cronjob.  The two value should be the same
# 
# -------------------------------------------------------------------------------------------------------------------------------

# -----------------------------------------------------------------------------------------------------------------------------
# Initialize variables
# -----------------------------------------------------------------------------------------------------------------------------
function initialize {

   # Root folder and his child, logs
   ROOTFOLDER="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
   TEMPLATESFOLDER=$ROOTFOLDER/"templates/"
   LOGFOLDER=$ROOTFOLDER/"logs/"

   # Retrieve the full name of this script.   
   SCRIPT_FULLNAME=$ROOTFOLDER/`basename "${BASH_SOURCE[0]}"`
   # Script name (only the name, without folder and extension)
   SCRIPT=`basename $0 | sed 's/.sh//'` #`echo "${BASH_SOURCE[0]}" | sed 's/.sh//'`
   # Associated json
   JSON=$ROOTFOLDER/$SCRIPT".json"

   # Read the json configuration and initialize variables 
   # http://www.experts-exchange.com/Programming/Languages/Regular_Expressions/Q_27568762.html
   json=`cat $JSON`                                                                         # Get file content into a memory variable

   SERVER=`echo $json | sed -e 's/^.*"server"[ ]*:[ ]*"//' -e 's/".*//'`                # Extract the server (f.i. avonture.be)
   TIMEZONE=`echo $json | sed -e 's/^.*"timezone"[ ]*:[ ]*"//' -e 's/".*//'`            # Extract the timezone (f.i. EUROPE/Brussels)
   RECIPIENT=`echo $json | sed -e 's/^.*"recipient"[ ]*:[ ]*"//' -e 's/".*//'`          # Extract the email recipient (people who'll receive an email notification when files are modified)
   HOMEDIR=`echo $json | sed -e 's/^.*"homedir"[ ]*:[ ]*"//' -e 's/".*//'`              # Extract the homedir (f.i. /home/myuser/public_html); root folder from where the search will start
   HOMEDIR="${HOMEDIR//\\/}"                                                            # Due to json encoding, the / directory separator is encoded as \/ so remove the / part.

   TMPDIR=`echo $json | sed -e 's/^.*"tmpdir"[ ]*:[ ]*"//' -e 's/".*//'`                # Extract the location of the temporary folder (f.i. /home/myuser/tmp)
   TMPDIR="${TMPDIR//\\/}"                                                              # Due to json encoding, the / directory separator is encoded as \/ so remove the / part.
         
   DURATION=`echo $json | sed -e 's/^.*"crontab_duration"[ ]*:[ ]*"//' -e 's/".*//'`    # Extract the duration (in minutes) for the tracking
   SENDMAIL=`echo $json | sed -e 's/^.*"sendmail"[ ]*:[ ]*"//' -e 's/".*//'`            # Does the script send a notification by email ?
   SAVELOGS=`echo $json | sed -e 's/^.*"savelogs"[ ]*:[ ]*"//' -e 's/".*//'`            # Does the script save logs ?
   CLEANAFTER=`echo $json | sed -e 's/^.*"cleanafter"[ ]*:[ ]*"//' -e 's/".*//'`        # Remove old logs and backup after xxxx days.
   
   # Actions
   RUN_IOFILESMOD=`echo $json | sed -e 's/^.*"ioFilesMod"[ ]*:[ ]*"//' -e 's/".*//'`    # Should we fire the script "Get files modified the last xxx minutes" ? 
   RUN_DBUSERSLIST=`echo $json | sed -e 's/^.*"dbUsersList"[ ]*:[ ]*"//' -e 's/".*//'`  # Should we fire the script "Get the list of users created in the database during the last xxx minutes" ? 
   RUN_DBBACKUP=`echo $json | sed -e 's/^.*"dbBackup"[ ]*:[ ]*"//' -e 's/".*//'`        # Should we fire the script "Make DB Backup" ? 
   
   # ioFilesMod   
   IO_FILEMOD_FOLDERS=`echo $json | sed -e 's/^.*"folders"[ ]*:[ ]*"//' -e 's/".*//' | tr '@' '|'`   # Extract the list of folders to ignore (f.i. /cache/ and /temp/); this as a regular expression
   IO_FILEMOD_FILES=`echo $json | sed -e 's/^.*"files"[ ]*:[ ]*"//' -e 's/".*//' | tr '@' '|'`   # Extract the list of files to ignore (f.i. *.log, *.tmp, ...); this as a regular expression

   # Database
   DBHOST=`echo $json | sed -e 's/^.*"dbhost"[ ]*:[ ]*"//' -e 's/".*//'`               # Database host (f.i. localhost)
   DBNAME=`echo $json | sed -e 's/^.*"dbname"[ ]*:[ ]*"//' -e 's/".*//'`               # Database name
   DBUSER=`echo $json | sed -e 's/^.*"dbuser"[ ]*:[ ]*"//' -e 's/".*//'`               # Database username
   DBPWD=`echo $json | sed -e 's/^.*"dbpwd"[ ]*:[ ]*"//' -e 's/".*//'`                 # Database password
   DBPREFIX=`echo $json | sed -e 's/^.*"dbprefix"[ ]*:[ ]*"//' -e 's/".*//'`           # Database table prefix
   DBBACKUPDIR=`echo $json | sed -e 's/^.*"backupdir"[ ]*:[ ]*"//' -e 's/".*//'`       # Folder where to store databases's backup
   DBBACKUPDIR="${DBBACKUPDIR//\\/}"                                                   # Due to json encoding, the / directory separator is encoded as \/ so remove the / part.

   LASTRUNFILE=$ROOTFOLDER"/_lastrun.log"                                              # Lastrun file
   
   # Be sure that the LOGFOLDER exists otherwise use temp
   if [ ! -d "$LOGFOLDER" ]; then mkdir "$LOGFOLDER"; fi

   # Set the timezone for this script so date/hours will be correctly displayed
   export TZ=$TIMEZONE   
}
# -----------------------------------------------------------------------------------------------------------------------------
# Debug function - Display variables
# -----------------------------------------------------------------------------------------------------------------------------
function dump_variables {

   clear
   echo ""
   echo "##############################################"
   echo "# aeSecure - Bash script - List of variables #"
   echo "##############################################"
   echo ""
   echo "Script variables:"
   echo "================="
   echo ""
   echo "Script                   = $SCRIPT"
   echo "Script fullname          = $SCRIPT_FULLNAME"
   echo "Root folder              = $ROOTFOLDER"
   echo "Templates folder         = $TEMPLATESFOLDER"
   echo "Log folder               = $LOGFOLDER"
   echo "JSON file                = $JSON"
   echo ""
   echo "Configuration (from json):"
   echo "=========================="
   echo ""
   echo "Server                   = $SERVER"
   echo "Timezone                 = $TIMEZONE"
   echo "Duration                 = $DURATION minutes"
   echo "Home directory           = $HOMEDIR"
   echo "Temporary directory      = $TMPDIR"
   echo "Save logs                = $SAVELOGS"
   echo "Remove logs/backups afer = $CLEANAFTER days"
   echo "Send email notification  = $SENDMAIL"
   echo "Mail recipient           = $RECIPIENT"
   echo ""
   echo "Action to fire"
   echo "--------------"
   echo "Get files modified the last xxx min.            = $RUN_IOFILESMOD"
   echo "Get the list of users created the last xxx min. = $RUN_DBUSERSLIST"
   echo "Make DB Backup                                  = $RUN_DBBACKUP"   
   echo ""
   echo "Filesmod - settings"
   echo "-------------------"
   echo "Exceptions - Folders     = $IO_FILEMOD_FOLDERS"
   echo "Exceptions - Files       = $IO_FILEMOD_FILES"
   echo ""
   echo "Database - settings"
   echo "-------------------"
   echo "Host                     = $DBHOST"
   echo "DBName                   = $DBNAME"
   echo "UserName                 = $DBUSER"
   echo "Password                 = $DBPWD"
   echo "TablePrefix              = $DBPREFIX"
   echo "Backup folder            = $DBBACKUPDIR"
   echo ""
   echo ""
   
}
# -----------------------------------------------------------------------------------------------------------------------------
# Get the LastRun Date of this script
# -----------------------------------------------------------------------------------------------------------------------------
function getLastRunDate {
      
   # The _lastrun file isn't found ==> create the file and start the backup. Important : use printf to avoid carriage return
   if [ ! -f $LASTRUNFILE ]; then printf "1800-0-0 00:00" > $LASTRUNFILE; fi
   
   LASTRUN=`cat $LASTRUNFILE`
   # Split the LASTRUN date/time into two variables
   LASTRUNDATE=$(echo $LASTRUN | awk -F" " '{ print $1 }')
   LASTRUNTIME=$(echo $LASTRUN | awk -F" " '{ print $2 }')
   
   echo $LASTRUNDATE;
}
# -----------------------------------------------------------------------------------------------------------------------------
# Scan the HOMEDIR and find files with a modification file date (of creation file date) that is less than ... (f.i. 60 minutes)
# If found, create a logfile and return a full HTML string 
# -----------------------------------------------------------------------------------------------------------------------------
function findFilesModifications {

   FCT="ioFilesMod"

   # Check : the HOMEDIR variable can't be empty.  This variable should point to the root folder where the scan should start
   ERRORMSG="":
   if [ -z "$HOMEDIR" ]; then
      ERRORMSG="<tr><td colspan='5' style='color:red;font-weight:bold'>The aesecure.json file is incorrect, the homedir configuration setting is empty.   $ROOTFOLDER has been used...</td></tr>";
	  HOMEDIR=$ROOTFOLDER;
   fi

   # Temporary file with the list of files that have been modified
   if [ $SAVELOGS -eq 1 ]; then
      # Check if the folder LOG/filemod/ folder exists; if not, create it
      if [ ! -d "$LOGFOLDER$FCT/" ]; then mkdir $LOGFOLDER$FCT; fi      
      CHANGES=$LOGFOLDER$FCT"/`date +"%Y-%m-%d_%H:%M"`.txt"
   else   
      CHANGES=$TMPDIR$FCT".txt"
   fi   
   
   # Be sure that this temporary file isn't already present (old run)
   rm -f $CHANGES

   # Find all files that have been modified during the last $DURATION minutes
   # Exclude a folder that are specified in $IO_FILEMOD_FOLDERS; like the cache or temp folders
   find $HOMEDIR -type f -mmin -$DURATION -name "*" -exec ls -l {} \; | grep -v -E "$IO_FILEMOD_FOLDERS" > $CHANGES

   # Return the list of changes; if any
   if [ -s $CHANGES ]; then 

      # Store the content of the file in the input variable
      input=$CHANGES
      i=0
	  
	  # Initialize the result string to the error msg if any (to an empty string otherwise)
      RESULT=$ERRORMSG;

      # Process the file line by line to determine if we need to monitor the change or not
      while read chmod tmp1 tmp2 tmp3 filesize month day hour filename
      do

	     # Continue only if the regex isn't matched i.e. if the filename shouldn't be skipped (i.e. matching the IO_FILEMOD_FILES regex)
         if ! [[ $filename =~ $IO_FILEMOD_FILES ]]
         then

	        # The file shouldn't be skipped.
		    # Add this file in the result string that will then be sent by email
            bFound=1
	  
            i=$((i+1));

		    # The filename can be long like /home/myuser/public_html/website1/...
   		    # Since the HOMEDIR (/home/myuser/public_html/) is always the same; don't repeat it again and again.  Keep filenames as shortest as possible.
            # Substitute /home/myuser/public_html/ by an empty string		 
		    filename="${filename/$HOMEDIR\///}"

            RESULT=$RESULT"<tr><td class='nbr'>$i</td><td class='lastmod'>$month&nbsp;$day&nbsp;$hour</td><td class='chmod'>$chmod</td><td class='filename'>$filename</td><td class='filesize'>$filesize</td></tr>"

         fi	  
   
      done < "$input"
	  
      # Check if $i is equal to 0.  If not, we've found at least one file; send a notification email.
      if ! [[ $i -eq 0 ]]; then
      
         if [[ $i -eq 1 ]]; then INTRO="1 file has"; else INTRO="$i files have"; fi
	  
         # Get the HTML mail template (the filename is templates/filesmod.aec i.e. the same filename that this current script; located in the same folder than
	     # the current script but with .aec as file's extension (instead of .sh)
         HTML=`echo $TEMPLATESFOLDER$FCT.aec`
	  
	     # The template contains a lot of variables like HOMEDIR, SERVER, DURATION, ...  Replace all occurences of these variables
	     # with the adhoc variable
         TMP=`cat $HTML` 
         TMP="${TMP//INTRO/$INTRO}"
         TMP="${TMP//RESULT/$RESULT}"
		 
	     echo $TMP
		 
		 # Delete files older than xxx days (see $CLEANAFTER)
         find $(dirname ${CHANGES})/* -mtime +"$CLEANAFTER" -exec rm {} \;		 
      
      fi

   else 
   
      # No changes found
   
      echo ""; 
	  
   fi
   
   # Delete all files of 0 bytes.  This is the case when the "find" instruction here above return nothing; the file is well created with 0 byte
   find $(dirname ${CHANGES})/* -size 0 -delete


}
# -----------------------------------------------------------------------------------------------------------------------------
# Get the list of users added in the database recently and send an email
# -----------------------------------------------------------------------------------------------------------------------------
function dbLastCreatedUsers {

   FCT="dbUsersList"
   
   # Run the check

   LASTRUNDATE=$(getLastRunDate);
   DATE=$(date +"%Y-%m-%d")

   # If $LASTRUNDATE is not equal to $DATE; it means that the lastrun wasn't yet done today => get the list of users 
   if [ ! "$DATE" == "$LASTRUNDATE" ]; then DOIT=1; else DOIT=0; fi
   
   if [ $DOIT -eq 1 ]; then

      if ([ -z "$DBHOST" ] || [ -z "$DBNAME" ] || [ -z "$DBUSER" ]); then
         echo "aesecure.sh - $FCT ERROR : The configuration file is incorrect; at least one of these configuration setting is missing : database server, database name or database user. If you are not using a database, please disable the check for the last added users in your database.";
	  
      else
	  
         # Get the SQL file for getting the list of last created users
         sSQL=`echo $TEMPLATESFOLDER"$FCT.sql"`

         # Read the file and replace the variable DBPREFIX with the table's prefix to use
         SQL=`cat $sSQL` 
         SQL="${SQL//DBPREFIX/$DBPREFIX}"
         # Get the list of users created during the last xxx minutes (f.i. the last 60 minutes)
         SQL="${SQL//DURATION/$DURATION}"

         # Temporary file with the list of files that have been modified
         if [ $SAVELOGS -eq 1 ]; then
            # Check if the folder LOG/filemod/ folder exists; if not, create it
            if [ ! -d "$LOGFOLDER$FCT/" ]; then mkdir $LOGFOLDER$FCT; fi      
            CHANGES=$LOGFOLDER$FCT"/`date +"%Y-%m-%d_%H:%M"`.html"
         else   
            CHANGES=$TMPDIR$FCT".html"
         fi   

         echo $(date +"%Y-%m-%d %H:%M") > $LASTRUNFILE; 
	  
         # Run the query and output the result in the dbUsersList.txt file
         mysql -D$DBNAME -u$DBUSER -p$DBPWD -e "$SQL" --html > $CHANGES

         # Delete all files of 0 bytes.  
         find $(dirname ${CHANGES})/* -size 0 -delete

         if [ -s $CHANGES ]; then 
   
            # Get the list of users from the file   
            RESULT=`cat $CHANGES`
   
            # Remove the <table> and </table> tags; already present in the template
            RESULT="${RESULT//<TABLE BORDER=1>/}"
            RESULT="${RESULT//<\/TABLE>/}"
            # Highlight some words
            #RESULT="${RESULT//Premium+/<strong style='color:red;'>Premium+<strong>}"
            #RESULT="${RESULT//Premium/<strong style='color:red;'>Premium<strong>}"
            #RESULT="${RESULT//WebDeveloper/<strong style='color:red;'>WebDeveloper<strong>}"

            # Get the HTML template and paste the list of users
            HTML=`cat $TEMPLATESFOLDER$FCT.aec`
            HTML="${HTML//RESULT/$RESULT}"
   
            echo $HTML
	  
	        # Delete files older than xxx days (see $CLEANAFTER)
            find $(dirname ${CHANGES})/* -mtime +"$CLEANAFTER" -exec rm {} \;		 
	  
         else
   
            # The query is empty; no record
            echo ""
	  
         fi
      fi # if ([ -z "$DBHOST" ]
	  
    else # if [ $DOIT -eq 1 ]
   
       # The list of user has already be processed today
       echo ""   
	  
   fi # if [ $DOIT -eq 1 ]

}
# -----------------------------------------------------------------------------------------------------------------------------
# Get the list of users added in the database recently and send an email
#
# Warning : The backup will be done max. once by day : even if the job is scheduled every 60 minutes,
# a check will be done with the _lastrun.log file and backup will be done if the last run was prior to the execution date.
# 
# -----------------------------------------------------------------------------------------------------------------------------
function dbBackup {

   FCT="dbBackup"
   # Check if the folder where to store DB Backup exists and if not, create it
   if [ ! -d "$DBBACKUPDIR/" ]; then mkdir $DBBACKUPDIR; fi      

   LASTRUNDATE=$(getLastRunDate);
   DATE=$(date +"%Y-%m-%d")

   # If $LASTRUNDATE is not equal to $DATE; it means that the lastrun wasn't yet done today => make the backup
   if [ ! "$DATE" == "$LASTRUNDATE" ]; then DOIT=1; else DOIT=0; fi
   
   if [ $DOIT -eq 1 ]; then

      if ([ -z "$DBHOST" ] || [ -z "$DBNAME" ] || [ -z "$DBUSER" ]); then
	  
         echo "aesecure.sh - $FCT ERROR : The configuration file is incorrect; at least one of these configuration setting is missing : database server, database name or database user. If you are not    using a database, please disable the check for the last added users in your database.";
	  
      else # if ([ -z "$DBHOST" ] 
   
         # Make the backup once a day
         mysqldump --user=$DBUSER --password=$DBPWD --host=$DBHOST $DBNAME > $DBBACKUPDIR/$DBNAME-$DATE.sql
	  
         # Compress the file and remove the uncompressed one
	     gzip -c $DBBACKUPDIR/$DBNAME-$DATE.sql > $DBBACKUPDIR/$DBNAME-$DATE.sql.gz	
         rm $DBBACKUPDIR/$DBNAME-$DATE.sql
	  
	     echo $(date +"%Y-%m-%d %H:%M") > $LASTRUNFILE; 
	  
         # Delete files older than xxx days (see $CLEANAFTER)
         find $DBBACKUPDIR/* -mtime +"$CLEANAFTER" -exec rm {} \;
	  
	     HTML=`cat $TEMPLATESFOLDER$FCT.aec`
         HTML="${HTML//RESULT/$DBBACKUPDIR/$DBNAME-$DATE.sql.gz}"
   
         echo $HTML
		 
      fi # if ([ -z "$DBHOST" ] 	 
	  
   else 
   
      echo ""   
	  
   fi
   
}
# ------------------------------------
# Send an email
#
# Parameters : 
#    #1 = Subject
#    #2 = HTML mail body
# ------------------------------------
function sendMail {

   # Check if the SendMail configuration item (from the JSON) allow to send emails
   if [ $SENDMAIL -eq 1 ]; then
   (
   
      echo "From: $RECIPIENT " 
      echo "To: $RECIPIENT " 
      echo "MIME-Version: 1.0 "
      echo "Content-Type: text/html " 
      echo "Content-Disposition: inline "
      echo "Subject: aeSecure - $1 - server $SERVER" 
	  
	  # Replace generic variables
	  TMP="$2"
	  TMP="${TMP//SCRIPT_FULLNAME/$SCRIPT_FULLNAME}"
      TMP="${TMP//HOMEDIR/$HOMEDIR}"
      TMP="${TMP//SERVER/$SERVER}"
      TMP="${TMP//DURATION/$DURATION}"
      TMP="${TMP//TIMEZONE/$TIMEZONE}"
      TMP="${TMP//DATE/`date`}"
      TMP="${TMP//YEAR/`date +%G`}"
      TMP="${TMP//DBNAME/$DBNAME}"
      
      echo $TMP
      
   ) | /usr/sbin/sendmail -F $RECIPIENT

   fi
   
}

# -----------
# Entry point
# -----------

   # Initialize variables
   initialize

   #dump_variables
      
   if [ $RUN_IOFILESMOD -eq 1 ]; then
      # Get the list of files that have been modified on the server and if not empty, send an email with the list of changes
      RESULT_FILESMOD=$(findFilesModifications)
      if [ -n "$RESULT_FILESMOD" ]; then sendMail "File monitoring agent" "$RESULT_FILESMOD"; fi
   fi

   if [ $RUN_DBUSERSLIST -eq 1 ]; then
      # Retrieve the list of last added users 
      RESULT_LASTUSERS=$(dbLastCreatedUsers)
      if [ -n "$RESULT_LASTUSERS" ]; then sendMail "Database monitoring agent - List of recent added users" "$RESULT_LASTUSERS"; fi
   fi
   
   if [ $RUN_DBBACKUP -eq 1 ]; then
      RESULT_DBBackup=$(dbBackup)      
      if [ -n "$RESULT_DBBackup" ]; then sendMail "Database backup agent - Daily backup done" "$RESULT_DBBackup"; fi
   fi