Zimbra FOSS User Backup

From vwiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

The following script is a modified version of one that can found on the Zimbra Forum here by LHammonds - http://www.zimbra.com/forums/installation/53227-my-notes-installing-zimbra-7-1-3-ubuntu-server-10-04-3-lts-2.html#post230528. The post in general is effectively a start to finish account of getting Zimbra FOSS up and running in an enterprise environment. Its well worth browsing through the whole chain, it covers everything!

My script is still a work in progress, but so far I've made the following modifications

  • Added ability to FTP backup's off to remote server
    • Requires lftp, install with apt-get lftp
  • Added logging output to end of script email

The script performs an online backup of all user accounts, which you can perform daily (or even more frequently), and maybe perform a full offline backup weekly or monthly.

#!/bin/bash
########################################################################
# Name          : zm-user-backup.sh
# Version       : 0.2
# Date          : 2011-10-29
# Author        : LHammonds
# Modifier      : SStrutt
# Compatibility : Ubuntu 10.04.3 LTS, Zimbra 7.1.2 - 7.1.3
# Purpose       : Backup individual mailbox accounts.
# Exit Codes    : (if multiple errors, value is the addition of codes)
#   0 = success
#   1 = failure
################ CHANGE LOG ##########################################
# DATE       WHO WHAT WAS CHANGED
# ---------- --- ----------------------------
# 2011-10-23 LTH Created script.
# 2011-10-29 LTH Various improvements. (yes, I forgot what)
# 2012-03-01 SSS Added remote FTPS option (requires lftp, backup retained locally for 5 days)
#		 Updated logging to log to email,
#####################################################################
# TO DO !!
# Add time-out to lftp command
# Improve error detection/handling around user export
# Add mechanism to allow monitoring of sucess.failure by Nagios

# Email notification options
EMAILFROM="admin@domain.com"
EMAILTO="someone@domain.com"

# Email account NOT to backup
EXCEPTIONS="spam.t1ml2qhoo@domain.com;ham.w5adcmdphn@domain.com;virus-quarantine.lzab8c2m_@domain.com"

# Paths and file defs, probably nothing for you to change
TEMPDIR="/backup"
LOGFILE="${TEMPDIR}/zm-user-backup.log"
SOURCEDIR="/opt/zimbra"
TARGETDIR="${TEMPDIR}/zmusers"
ARCHIVEFILE="`date +%Y-%m-%d_%H-%M`_zmusers.tar"
MAILFILE="${TEMPDIR}/zm-user-backup-mail.$$"
MAILLOG="${TEMPDIR}/zm-user-backup-mail-log.$$"
FTPLOG="${TEMPDIR}/zm-user-backup-ftp-log.$$"

# Remote NFS mount
REMOTESITE="/mnt/zmbackup"
REMOTETESTFILE="${REMOTESITE}/online.txt"

# Remote FTPS server
FTP="yes"				# To FTP or not to FTP, if no, copy to NFS will be performed
FTPSERVER="ftp.domain.com"		# FTP server to copy backup to
FTPUSER="backup"			# FTP account username
FTPPASS="backup"			# FTP account password
FTPDIR="/backups/mail"			# Directory on FTP server to place backup into

# Nothing to change here, move along
HOSTNAME=$(hostname -f)
SCRIPTNAME=${0}
RETURNVALUE=0
UCOUNT=0
ERRORFLAG=0

#######################################
##            FUNCTIONS              ##
#######################################

function f_sendmail()
{
  # Purpose: Send email message.
  # Parameter #1 = Subject
  # Parameter #2 = Body
  echo "From: ${EMAILFROM}" > ${MAILFILE}
  echo "To: ${EMAILTO}" >> ${MAILFILE}
  echo "Subject: ${1}" >> ${MAILFILE}
  echo "" >> ${MAILFILE}
  echo ${2} >> ${MAILFILE}
  echo "" >> ${MAILFILE}
  cat ${MAILLOG} >> ${MAILFILE}
  echo "" >> ${MAILFILE}
  cat ${FTPLOG} >> ${MAILFILE}
  echo "" >> ${MAILFILE}
  echo "Server: ${HOSTNAME}, Program: ${SCRIPTNAME}" >> ${MAILFILE}
  ${SOURCEDIR}/postfix/sbin/sendmail -t < ${MAILFILE}
}

function f_cleanup()
{
  rm ${MAILFILE}
  rm ${MAILLOG}
  rm ${FTPLOG}
  # Remove backup's older then 5 days
  find ${TEMPDIR}/*.tar -mtime +5 -exec rm {} \;
}

function f_log()
{
  # Handles logging of messages
  # Parameter #1 = Log Message
  STAMP=`date '+%Y-%m-%d %H:%M:%S'`
  echo "${STAMP} ${1}"
  echo "${STAMP} ${1}" >> ${LOGFILE}
  echo "${STAMP} ${1}" >> ${MAILLOG}
}


#######################################
##           MAIN PROGRAM            ##
#######################################

echo "---------------------------------------------------" >> ${LOGFILE}
f_log "- zm user backup started."
if [ -d "${TARGETDIR}" ]; then
  # Purge existing archives.
  rm ${TARGETDIR}/*.tgz 1>/dev/null 2>&1
else
  # Make the folder if it does not exist.
  mkdir -p ${TARGETDIR} 1>/dev/null 2>&1
fi
f_log "-- Getting list of user accounts"
for ACCT in `su - zimbra -c "zmprov -l gaa"`
do
  # Check to see if current account should be skipped.
  if echo "${EXCEPTIONS}" | grep -q ${ACCT}
  then
    # Exception found, skip this account.
    echo "" > /dev/null
  else
    # Backup user account.
    UCOUNT=$((UCOUNT+1))
    f_log "--- Backing up user ${ACCT}"
    ${SOURCEDIR}/bin/zmmailbox -z -m ${ACCT} getRestURL "//?fmt=tgz" > ${TARGETDIR}/${ACCT}.tgz
    RETURNVALUE=$?
    if [ ! ${RETURNVALUE} -eq 0 ]; then
      # Something went wrong.
      f_log "---- Error on ${ACCT}, exit code ${RETURNVALUE}"
      ERRORFLAG=$((ERRORFLAG+1))
    fi
  fi
done
f_log "-- ${UCOUNT} accounts processed."

# Comment out the below line if you do not want to receive statistic emails.
#f_sendmail "Zimbra User Mailbox Backup" "${UCOUNT} accounts backed up."

f_log "--- Setting file permissions on ${TARGETDIR}/*.tgz"
chmod 0600 ${TARGETDIR}/*.tgz
f_log "--- Creating a single archive ${TEMPDIR}/${ARCHIVEFILE}"
tar -cf ${TEMPDIR}/${ARCHIVEFILE} ${TARGETDIR} 1>/dev/null 2>&1
RETURNVALUE=$?
if [ ! "${RETURNVALUE}" -eq "0" ]; then
  # Something went wrong.
  f_log "--- Error creating ${TEMPDIR}/${ARCHIVEFILE}, Return Value: ${RETURNVALUE}"
  ERRORFLAG=$((ERRORFLAG+1))
fi

if [ "$FTP" = "yes" ]
then
        # Do FTPS copy to FTP site
        f_log "-- Starting FTPS copy to ${FTPSERVER}"
        lftp -u ${FTPUSER},${FTPPASS} -e "set ftp:ssl-force true,ftp:ssl-protect-data true,net:max-retries 5; cd ${FTPDIR}; put ${TEMPDIR}/${ARCHIVEFILE}; exit" ${FTPSERVER}
        RETURNVALUE=$?
        if [ "${RETURNVALUE}" == "0" ]
        then
                f_log "--- FTPS upload completed successfully"
        else
                f_log "--- FTPS upload FAILED, exit code ${RETURNVALUE}"
                ERRORFLAG=$((ERRORFLAG+1))
        fi
else
        # Do copy to remote file store

        if [ -f ${TEMPDIR}/${ARCHIVEFILE} ]; then
          # Copy archive to remote site.
          if [ -f ${REMOTETESTFILE} ]; then
            # Remote site is online / available.
            cp ${TEMPDIR}/${ARCHIVEFILE} ${REMOTESITE}/${ARCHIVEFILE} 1>/dev/null 2>&1
          else
            # Remote site is offline / unavailable.
            f_log "--- Error: Remote site is unavailable: ${REMOTESITE}"
            ERRORFLAG=$((ERRORFLAG+1))
          fi
        fi

        if [ -f ${REMOTESITE}/${ARCHIVEFILE} ]; then
          # Remote copy worked.  Remove local archive.
          rm ${TEMPDIR}/${ARCHIVEFILE}

          # Uncomment the following 2 lines if you do not wish to have a local copy of individual mailboxes.
          #rm ${TARGETDIR}/*.tgz
          #rmdir ${TARGETDIR}
        else
          # Remote copy failed.
          f_log "--- Error creating ${TEMPDIR}/${ARCHIVEFILE}, Return Value: ${RETURNVALUE}"
          ERRORFLAG=$((ERRORFLAG+1))
        fi
fi

f_log "- zm user backup complete. exit code: ${ERRORFLAG}"

if [ "${ERRORFLAG}" -ne "0" ]; then
  f_sendmail "Zimbra Mailbox Backup Error - ${HOSTNAME}" "${ERRORFLAG} errors detected in ${HOSTNAME} ${SCRIPTNAME}"<${MAILLOG}
else
  f_sendmail "Zimbra User Mailbox Backup - ${HOSTNAME}" "${UCOUNT} accounts backed up."<${MAILLOG}
fi

# Perform cleanup routine.
f_cleanup
# Exit with the combined return code value.
exit ${ERRORFLAG}