Mit Rdiff-backup lokalen Linux Host nach Windows/Linux sichern

ghostadmin

Grand Admiral Special
Mitglied seit
11.11.2001
Beiträge
25.179
Renomée
184
Standort
Dahoam Studios
Da ich selbst nur einen Linux Server habe, der ständig läuft - funktionieren die meisten Backuplösungen schlecht, da meistens die Dateien von einem Backupserver geholt werden. Ich will diese vom Server aus wegschicken, auf entfernte Rechner die nicht ständig an sind. Und das ganze soll automatisch und mit eMail versendeten Logs funktionieren, denn wie schnell vergisst man zu sichern. Eine Sicherung auf eine USB Festplatte kommt für mich nicht in Frage.
Ausserdem will ich mehrere Generationen sichern können mit möglichst wenig Platzbedarf. Rdiff-backup arbeitet blockbasiert und wenn man eine Datei ändert, dann werden beim nächsten Backup nur die Änderungen in dieser Datei gesichert. Dies ist mit rsync und dergleichen nicht ohne aufwendige Scripts möglich.

Mit dem Script kann man ein Passwort geschütztes rar Archiv erzeugen z.B. für Configfiles die auf dem Remotesystem nicht für jedermann lesbar sein sollen.
Diese Archive sollten aber nicht zu groß werden, da dann die Deduplikation von rdiff-backup nur eingeschränkt funktioniert.
Man kann wahlweise auf einen entfernten Windows Host (Option backupwin) oder Linux/Unix Host (backupssh) mehrere Pfade per rdiff-backup sehr platzsparend in mehreren Generationen sichern.
Es kann eingestellt werden, ab welchen Datum alte Backupfiles automatisch verfallen (older than).
Dadurch das gleichzeitig ein Linux und Windows Host angesprochen werden kann, kann man auch doppelt sichern.

Wenn die Variable daycheck aktiv ist, läuft das Script nur max. 1x pro Tag. Dies hat denn Zweck falls der Remote Host z.B. ein Windows PC ist der nicht ständig läuft, man das Script z.B. alle 5min. per cron starten kann, solange bis der PC verfügbar ist. Dies wird per Ping und Datum des Logs überprüft und es gibt einen weiteren Zeitwert mit dem gesteuert wird, nach wie vielen Sekunden das Backup startet ab der Ping response.

Nach erfolgtem Backup kann automatisch eine Mail mit dem Log versendet werden.
Ab einer gewissen warning disk space Grenze wird separat eine Warning Mail versendet und beim critical Wert stoppt das Script vollständig.

Zusätzlich gibt es menügesteuerte Optionen um sich auf dem Windows Share ein ext volume anlegen zu lassen (createloop), welches loopmount gesteuert wird. Dieses Loop mounten ist notwendig, weil Windows Probleme mit dem Dateiformat von Linux hat.

Bei einem entfernten Linux/Unix Host kann man die ssh Konfiguration, durch Option createssh erledigen lassen. Hierbei wird es möglich sich ohne Passwort per ssh zu verbinden, weil beim ssh Befehl kein Passwort mitgeliefert werden kann ist dies leider notwendig.

Die Mount Switches dienen dazu um einen Restore machen zu können. Hierzu lässt sich auch rdiff-web nutzen.

Code:
#!/bin/bash
#rdiffback.sh
PROGVER=2.1
#by xrated 08/2012

########################################################

# What this script does: 
# You can backup your local data to other Windows, Linux or Unix hosts, by using rdiff-backup.
# Rdiff-backup is working on block level, so multiple generations are really small in size.
# If you want to backup to Linux/Unix, then package rdiff-backup needs to exist on the other host and should be the same version if possible.
# Also ssh needs to be configured, this can be done by using the createssh option.
# If Windows is the backup target, then you need to configure SMB and a loop mount. This can be also done by using the createloop option.

# Additionally you can use the backupconfig section, which backup folders to an archive.
# For example: To backup data such as files including passwords, typically /etc folder.
# Please note that block level backup works very limited on archives. So dont use this for big amount of data.

########################################################

#global backup options
FILEOT=1Y #delete files older than
BACKUPFOLDER=/ #folder to backup on local machine, only single folder possible, do not end with /
INCLUDELIST=rdiffbackinclude # !! everything here takes precedence over exlude list !!
EXCLUDELIST=rdiffbackexclude # in your exclude file you can list just ** to exclude everything, so only the include list will work
LOGLEVEL=5 #loglevel 1-9, 3 is default, 5 is showing files
LOGPATH=/var/log/rdiffback # make sure folder exists
RDIFFLOGCONFIG=rdiffback-config #logfile
RDIFFBIN=/usr/bin/rdiff-backup
RDIFFWEBUNLOAD=yes #unload rdiff-web before umount, otherwise umount fails
CAPWARN=85% #warn level in %, send mail when capacity reaches this level
CAPCRIT=98% #critical level in %, backup will not work when reached
#########################################################

# Options for createloop and createssh
RDIFFLOGLOOP=rdiffback-createloop
_temp=/tmp/tmp.rdiffback
DIALOGBIN=/usr/bin/dialog

########################################################

#CIFS share as target for backup
#Section is used only when backupwin option is used!
#SMB needs to be configured on the target host and you need a file on it, which will be loop mounted to an linux fs.
#This is done because linux cannot handle lower/upper case files.
#You can also use the createloop option to let this do for you.
#Instructions: On your SMB share create a big file enough to fit backup, format it with linux file system and change
#script parameters, before using it. Or start script with createloop option.
#If you have problem with corrupted backups, check output of /var/log/kern.log,
#normaly this is related to linux fs mount options.

TIMERVALWIN=1 # seconds to wait before backup starts, to be sure that remote host is up and running, in case you are not sure if its really up because it may still load its services after a successfull ping
RDIFFLOGWIN=rdiffback-win
RDIFFWINDAYCHECK=yes # if set to no, its possible to run the backup again on the same day - yes may be handy, if you dont know when the remote host is up and the script is started multiple times per day via cron to catch it at least one time
SMBSOURCE=192.168.2.103 # host or ip
SMBSHARE=rdiff
CREDFILE=/etc/.smb #contains user,password for smb mount separated by new line: username=youruser password=yourpassword
MOUNTCIFS=rw,soft,forcedirectio,mapchars,nocase,iocharset=utf8,dir_mode=0660,file_mode=0660,credentials=$CREDFILE #changed hard to soft here
SMBTARGET=/mnt/smbvenus #where SMB share should be mounted to, do not end path with /, make sure this folder exists
#Loopmount, contains linux fs
BACKUPFILE=backup.ext3 #backup file on SMB share, this is where all the files go into
MOUNTFS=ext3 #linux filesystem for loopmount
LOOPTARGET=/mnt/loopvenus #path where file should be loop mounted to, do not end path with /
MOUNTWINLINUX=sync,loop,rw,noatime,barrier=1 #mount options for linux fs, use barrier do avoid delayed write, loop makes it possible to use a filesystem on a single file

##########################################################

#Linux/Unix as backup target 
#Section is used only when backupssh option is used!
#Instructions (or simply start script with createssh option)
#step1: configure ssh to work withou password (because ssh has no password option)
#login as specified user
#ssh-keygen -t rsa 
#copy - via scp - the pub file from ~/.ssh to other server into ~/.ssh/authorized_keys file:
#scp ~/.ssh/id_rsa.pub username@host:~/.ssh/authorized_keys
#chmod 600 key files and authorized_keys file on both systems afterwards
#now it should be possible to ssh into other system without password
#step2: to make it possible that user root uses rd_rsa file of that other user
#create /root/.ssh/config file
#enter the following:
#host targethost
#hostname targethost
#user username
#identityfile /home/trechber/.ssh/id_rsa
#finally chmod it 600
TIMERVALSSH=1 # see above in SMB section
RDIFFLOGSSH=rdiffback-ssh
RDIFFSSHDAYCHECK=yes # see above in SMB section
MOUNTNFSOPT=rw,async # mount nfs options
MOUNTNFSVER=4 # mount nfs with version as specified
LINUXHOST=192.168.2.3
LINUXUSER=trechber #user for ssh, normaly root not allowed for ssh
LINUXFOLDER=/data1/public/rdiff #backup target path
LINUXTARGET=/mnt/nfssolaris #this is only to see backed up files in rdiff-web
SCPBIN=/usr/bin/scp # path is local
SSHBIN=/usr/bin/ssh # path is local

###########################################################

#backup config? files will be added to rar file with password on specified location
#Please note: rdiff-backup may create big files if you use it because deduplication does not work well
#User and group permissions will be also stored in archive

RARBIN=/usr/bin/rar
COMPRPWD=$(cat /etc/.comprpwd) # put just one line with password into that file
BACKUPCONFIGFOLDER=/data/Dokumente/debian #do not end path with /, make sure you have also included this folder in rdiff-backup if you need it
COMPRARCHIVES=1 # how many target archives to create, 1 means, dont do COMPRFOLDER2 and COMPRFOLDER3, 0 means dont do any at all
COMPRFOLDER1="/etc" #folder to backup
COMPRFILE1=etc #target file for rar
COMPRFOLDER2="/usr/lib/nagios* /usr/share/nagios* /usr/share/logwatch*"
COMPRFILE22=usr
COMPRFOLDER3="/var/vmail* /var/www* /var/lib/mysql"
COMPRFILE3=var

###########################################################

#email logs?
EMAILWIN=yes # email when rdiff-backup backups to windows host
EMAILSSH=yes # email when rdiff-backup backups to linux/unix host
EMAILCONFIG=yes # email log of backup config, note this will only be used if script is started with backupconfig option
EMAILWARN=yes #email disk space warning/critical
EMAILTO=root

###########################################################

# do not change anything below

#misc parameters
CAPWARN=$(echo $CAPWARN | sed -e 's/[^0-9]//g') #convert to number
CAPCRIT=$(echo $CAPCRIT | sed -e 's/[^0-9]//g')
RDIFFDAYCHECK=$2
PROGNAME=`basename $0`
PROGPATH="$(cd $(dirname $0) && pwd)"


#readout actual date, needed to see if job has been run today
date "+%Y-%m-%d" > $PROGPATH"/rdiffbackactualdate"
rdiffdate1=`head -n 1 $PROGPATH/rdiffbackactualdate`

#check if logfolder exists
if ! test -e $LOGPATH; then
echo "Error: Specified logfolder does not exist!"
fi

#append slash if $BACKUPFOLDER is not root, otherwise resulting path will be messed later
if [ ! "${BACKUPFOLDER,,}" == "/" ]; then
BACKUPFOLDER=$BACKUPFOLDER"/"
fi

funct-listmount ()
{


    case "$1" in
    
    win)
    if mount | grep $LOOPTARGET > /dev/null; then
	df -h $LOOPTARGET
    else
	echo "backupwin target" $LOOPTARGET "is not mounted"
    fi 
    ;;
    ssh)
    echo
    if mount | grep $LINUXTARGET > /dev/null; then
	df -h $LINUXTARGET
    else
	echo "backupssh target" $LINUXTARGET "is not mounted"
    fi
    ;;
    *)
    echo "Error: parameter missing!"
    ;;
    esac



}

funct-mount-win ()
{
	if [ ! "$(mount | grep $SMBTARGET)" ]; then
	    echo "mount" $SMBTARGET
	    mount -t cifs -o $MOUNTCIFS //$SMBSOURCE/$SMBSHARE $SMBTARGET
	    if [ "$(mount | grep $SMBTARGET)" ]; then
		echo "mounting" $SMBTARGET "was successfull, you should see" $BACKUPFILE "here"
	    else
		echo "Error:" $SMBTARGET "could not be mounted!" >> $LOGPATH/$LOGPATH/$RDIFFLOGWIN
		mounterror=1
	    fi
	else
	    echo $SMBTARGET "already mounted"
	fi
	
	if [ ! "${mounterror,,}" == "1" ]; then
	    if [ ! "$(mount | grep $LOOPTARGET)" ]; then
		echo "mount" $LOOPTARGET
		sleep 1
		mount -t $MOUNTFS -o $MOUNTWINLINUX $SMBTARGET/$BACKUPFILE $LOOPTARGET
		if [ "$(mount | grep $SMBTARGET)" ]; then
		    echo "mounting" $LOOPTARGET "was successfull, target path for rdiff-backup"
		else
		    echo "Error:" $LOOPTARGET "could not be mounted!" >> $LOGPATH/$RDIFFLOGWIN
		    mounterror=1
		fi
	    else
		echo $LOOPTARGET "already mounted"
	    fi
	fi
}

funct-mount-ssh ()
{
	if [ ! "$(mount | grep $LINUXTARGET)" ]; then
	    echo "mount" $LINUXTARGET
	    mount -t nfs$MOUNTNFSVER -o $MOUNTNFSOPT $LINUXHOST:$LINUXFOLDER $LINUXTARGET
	    if [ "$(mount | grep $LINUXTARGET)" ]; then
		echo "mounting" $LINUXTARGET "was successfull"
	    else
		echo "Error:" $LINUXTARGET "could not be mounted!" >> $LOGPATH/$RDIFFLOGSSH
		mounterror=1
	    fi
	else
	    echo $LINUXTARGET "already mounted"
	fi
}

funct-mount ()
{
	case "$1" in
	    ssh)
	    funct-mount-ssh
	    ;;
	    win)
	    funct-mount-win
	    ;;
	    *)
	    ;;
	esac
	
	sleep 1
	
	if [ ! "${mounterror,,}" == "1" ]; then
	    if [ ! "$(ps -A | grep rdiff-web)" ]; then
		if test -e /etc/init.d/rdiff-web; then
		    /etc/init.d/rdiff-web start
		    if [ "$(ps -A | grep rdiff-web)" ]; then
			echo "rdiff-web successfully started"
			echo "you can start rdiff-web now on http://<thishostorip>:port, usually port 8080"
		    else
			echo "Error: rdiff-web could not be started!"
		    fi
		else
		    echo "Error: rdiff-web not installed!"
		fi
	    else
	    echo "rdiff-web already started"
	    fi
	fi
}

funct-umount-win ()
{
	if [ "$(mount | grep $LOOPTARGET)" ]; then
	    echo "umount" $LOOPTARGET
	    sleep 1
	    umount $LOOPTARGET
	    if [ "$(mount | grep $LOOPTARGET)" ]; then
		echo "Error:" $LOOPTARGET "is still mounted!" >> $LOGPATH/$RDIFFLOGWIN
		mounterror=1
	    else
	    echo "umounting" $LOOPTARGET "was successfull"
	    fi
	fi
	
	if [ ! "${mounterror,,}" == "1" ]; then
	if [ "$(mount | grep $SMBTARGET)" ]; then
	    echo "umount" $SMBTARGET
	    sleep 1
	    umount $SMBTARGET
	    if [ "$(mount | grep $SMBTARGET)" ]; then
		echo "Error:" $SMBTARGET "is still mounted!" >> $LOGPATH/$RDIFFLOGWIN
	    else
		echo "unmounting" $SMBTARGET "was successfull"
	    fi
	fi
	fi
}

funct-umount-ssh ()
{
	if [ "$(mount | grep $LINUXTARGET)" ]; then
	    echo "umount" $LINUXTARGET
	    sleep 1
	    umount $LINUXTARGET
	    if [ "$(mount | grep $LINUXTARGET)" ]; then
		echo "Error:" $LINUXTARGET "is still mounted!" >> $LOGPATH/$RDIFFLOGSSH
	    else
	    echo "umounting" $LINUXTARGET "was successfull"
	    fi
	fi
}


funct-umount ()
{
	if [ "${RDIFFWEBUNLOAD,,}" == "yes" ]; then
	    if [ "$(ps -A | grep rdiff-web)" ]; then
		/etc/init.d/rdiff-web stop
		sleep 1
		if [ ! "$(ps -A | grep rdiff-web)" ]; then
		    echo "rdiff-web is stopped now"
		else
		    echo "Error: rdiff-web could not be stopped!"
		fi
	    else
	    echo "rdiff-web already stopped"
	    fi
	fi
	
	case "$1" in
	    win)
	    funct-umount-win
	    ;;
	    ssh)
	    funct-umount-ssh
	    ;;
	    *)
	    ;;
	esac

}

funct-spacefree ()

{

case "$1" in

win)

spacefreeperc=`df -h | grep $LOOPTARGET | awk '{ print $5 }' | sed -e 's/[^0-9]//g'`
spacefree=`df -h | grep $LOOPTARGET | awk '{ print $4 }'`

    if [ "${spacefreeperc,,}" -ge $CAPWARN ]; then
	if [ "${spacefreeperc,,}" -ge $CAPCRIT ]; then
	    echo "Error: "$CAPCRIT"% capacity reached" >> $LOGPATH/$RDIFFLOGWIN
	    if [ "${EMAILWARN,,}" == "yes" ] ; then
    		if mail -s "[$PROGNAME] - Rdiff-backup $(hostname) to $SMBSOURCE - disk space critical - "$spacefreeperc"% in use (threshold "$CAPCRIT"%)" $EMAILTO < /dev/null ; then
    		    echo "Mail capacity warning sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGWIN
    		else
    		    echo "Error: Mail capacity warning could not be sent!" >> $LOGPATH/$RDIFFLOGWIN
    		fi
	    fi
	else
	    echo "Warning: "$CAPWARN"% capacity reached" >> $LOGPATH/$RDIFFLOGWIN
	    if [ "${EMAILWARN,,}" == "yes" ] ; then
    		if mail -s "[$PROGNAME] - Rdiff-backup $(hostname) to $SMBSOURCE - disk space warning - "$spacefreeperc"% in use (threshold "$CAPWARN"%)" $EMAILTO < /dev/null ; then
    		    echo "Mail capacity warning sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGWIN
    		else
    		    echo "Error: Mail capacity warning could not be sent!" >> $LOGPATH/$RDIFFLOGWIN
    		fi
	    fi
	fi
    else
	echo "OK: Free capacity on target volume is "$spacefree"/"$spacefreeperc"%, warning level is at "$CAPWARN"%." >> $LOGPATH/$RDIFFLOGWIN
    fi

;;

ssh)

spacefreeperc=`df -h | grep $LINUXTARGET | awk '{ print $4 }' | sed -e 's/[^0-9]//g'`
spacefree=`df -h | grep $LINUXTARGET | awk '{ print $3 }'`

    if [ "${spacefreeperc,,}" -ge $CAPWARN ]; then
	if [ "${spacefreeperc,,}" -ge $CAPCRIT ]; then
	    echo "Error: "$CAPCRIT"% capacity reached" >> $LOGPATH/$RDIFFLOGSSH
	    if [ "${EMAILWARN,,}" == "yes" ] ; then
    		if mail -s "[$PROGNAME] - Rdiff-backup $(hostname) to $LINUXHOST - disk space critical - "$spacefreeperc"% in use (threshold "$CAPCRIT"%)" $EMAILTO < /dev/null ; then
    		    echo "Mail capacity warning sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGSSH
    		else
    		    echo "Error: Mail capacity warning could not be sent!" >> $LOGPATH/$RDIFFLOGSSH
    		fi
	    fi
	else
	    echo "Warning: "$CAPWARN"% capacity reached" >> $LOGPATH/$RDIFFLOGSSH
	    if [ "${EMAILWARN,,}" == "yes" ] ; then
    		if mail -s "[$PROGNAME] - Rdiff-backup $(hostname) to $LINUXHOST - disk space warning - "$spacefreeperc"% in use (threshold "$CAPWARN"%)" $EMAILTO < /dev/null ; then
    		    echo "Mail capacity warning sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGSSH
    		else
    		    echo "Error: Mail capacity warning could not be sent!" >> $LOGPATH/$RDIFFLOGSSH
    		fi
	    fi
	fi
    else
	echo "OK: Free capacity on target volume is "$spacefree"/"$spacefreeperc"%, warning level is at "$CAPWARN"%." >> $LOGPATH/$RDIFFLOGSSH
    fi

;;

*)
;;
esac

}

funct-backupconfig ()

{

    
    if [ "${EMAILCONFIG,,}" == "yes" ]; then
	#move old log, otherwise old logs will be mailed everytime again
    	if test -e $LOGPATH/$RDIFFLOGCONFIG; then
    	    mv $LOGPATH/$RDIFFLOGCONFIG $LOGPATH/$RDIFFLOGCONFIG-$rdiffdate1
    	fi
    fi


    #add information to backup log
    echo "The following folders:" $COMPRFOLDER1 "were compressed into rar to" $BACKUPCONFIGFOLDER "see log below" >> $LOGPATH/$RDIFFLOGCONFIG
    #rar various config folders to backup folder	
    if test -e $RARBIN ; then
	if [ "${COMPRARCHIVES,,}" -ge 1 ]; then
    		if $RARBIN u -hp$COMPRPWD -ow -rr5% $BACKUPCONFIGFOLDER/$COMPRFILE1.rar $COMPRFOLDER1 >> $LOGPATH/$RDIFFLOGCONFIG; then
    		    echo . >> $LOGPATH/$RDIFFLOGCONFIG
    		    echo "RAR OK:" $COMPRFOLDER1 >> $LOGPATH/$RDIFFLOGCONFIG
    		else
    		    echo "Error, maybe just no new files?:" $COMPRFOLDER1 >> $LOGPATH/$RDIFFLOGCONFIG
    		fi
        fi
        
        if [ "${COMPRARCHIVES,,}" -ge 2 ]; then
    		if $RARBIN u -hp$COMPRPWD -ow -rr5% $BACKUPCONFIGFOLDER/$COMPRFILE2.rar $COMPRFOLDER2 >> $LOGPATH/$RDIFFLOGCONFIG; then
    		    echo "RAR OK:" $COMPRFOLDER2 >> $LOGPATH/$RDIFFLOGCONFIG
    		else
    		    echo "Error, maybe just no new files?:" $COMPRFOLDER2 >> $LOGPATH/$RDIFFLOGCONFIG
    		fi
        fi
        
        if [ "${COMPRARCHIVES,,}" -ge 3 ]; then
    		if $RARBIN u -hp$COMPRPWD -ow -rr5% $BACKUPCONFIGFOLDER/$COMPRFILE3.rar $COMPRFOLDER3 >> $LOGPATH/$RDIFFLOGCONFIG; then
    		    echo "RAR OK:" $COMPRFOLDER3 >> $LOGPATH/$RDIFFLOGCONFIG
		else
		    echo "Error, maybe just no new files?:" $COMPRFOLDER3 >> $LOGPATH/$RDIFFLOGCONFIG
		fi
	fi
	
    else
        echo "Error:" $RARBIN "not found!" >> $LOGPATH/$RDIFFLOGCONFIG
        echo "Your system reports it at" && which rar >> $LOGPATH/$RDIFFLOGCONFIG
	backuperror=1
    fi
    echo "#######################################################################################################################" >> $LOGPATH/$RDIFFLOGCONFIG

}

funct-backupsshdaycheck ()

{
if test -e $LOGPATH/$RDIFFLOGSSH; then
ls $LOGPATH/$RDIFFLOGSSH --full-time | awk '{print $6}' > $PROGPATH/rdiffbacklastrunssh
rdiffdate2=`head -n 1 $PROGPATH/rdiffbacklastrunssh`
fi

if [ "$rdiffdate1" != "$rdiffdate2" ]; then
echo "OK: rdiffback has not been run today"
backupssh=1
else
    if [ ! "$RDIFFDAYCHECK" == "--force" ]; then
	echo "INFO: rdiffback was already run today. If you want to run it again use --force switch"
    fi
backupssh=0
fi
}

funct-backupwindaycheck ()

{
if test -e $LOGPATH/$RDIFFLOGWIN; then
ls $LOGPATH/$RDIFFLOGWIN --full-time | awk '{print $6}' > $PROGPATH/rdiffbacklastrunwin
rdiffdate2=`head -n 1 $PROGPATH/rdiffbacklastrunwin`
fi

if [ "$rdiffdate1" != "$rdiffdate2" ]; then
echo "OK: rdiffback has not been run today"
backupwin=1
else
    if [ ! "$RDIFFDAYCHECK" == "--force" ]; then
	echo "INFO: rdiffback was already run today. If you want to run it again, use --force switch"
    fi	
backupwin=0

fi
}


case "$1" in
    backupssh)

    funct-backupsshdaycheck
        
if [ "$backupssh" == "1" ] || [ "$RDIFFDAYCHECK" == "--force" ] ; then

    if [ "$RDIFFDAYCHECK" == "--force" ]; then
	echo "INFO: --force switch is enabled, so the script is allowed to run multiple times per day"
    fi
    
    if [ "$(ping -c 1 $LINUXHOST | grep "1 received")" ]; then
	echo "OK: remote host" $LINUXHOST "is reachable"
	echo "Wait" $TIMERVALSSH "seconds to be sure host is ready and not still booting up..."
	sleep $TIMERVALSSH
	
	funct-mount-ssh
	funct-spacefree ssh
	funct-umount-ssh

	if [ ! "${spacefreeperc,,}" -ge $CAPCRIT ]; then
    
	    #move old log, otherwise old logs will be mailed everytime again
    	    if test -e $LOGPATH/$RDIFFLOGSSH; then
	        if ! mv $LOGPATH/$RDIFFLOGSSH $LOGPATH/$RDIFFLOGSSH-$rdiffdate1; then
		    echo "Error: Could not move old log!" >> $LOGPATH/$RDIFFLOGSSH
	        fi
	    fi
	    
	    if [ "${COMPRARCHIVES,,}" -ge 1 ]; then
	    funct-backupconfig
	    cat $LOGPATH/$RDIFFLOGCONFIG >> $LOGPATH/$RDIFFLOGSSH
	    fi


    
		if test -e $RDIFFBIN; then
		    if $RDIFFBIN -v$LOGLEVEL --remove-older-than $FILEOT $LINUXUSER@$LINUXHOST::$LINUXFOLDER/$(hostname)$BACKUPFOLDER; then
			echo "OK: Rdiff-backup removed files older than" $FILEOT >> $LOGPATH/$RDIFFLOGSSH
		    else
		    	echo "Error: Rdiff-backup could not run --remove-older-than job" >> $LOGPATH/$RDIFFLOGSSH
			backuperror=1
		    fi
		
		    if $RDIFFBIN -v$LOGLEVEL --include-globbing-filelist $PROGPATH/$INCLUDELIST --exclude-globbing-filelist $PROGPATH/$EXCLUDELIST $BACKUPFOLDER $LINUXUSER@$LINUXHOST::$LINUXFOLDER/$(hostname)$BACKUPFOLDER; then
		        echo "OK: Rdiff-backup gave no Error" >> $LOGPATH/$RDIFFLOGSSH
		        if test -e $SCPBIN; then
		    	# copy backup log to local tmp folder, user has no rights on /var/log and its not always possible to use root over ssh
		    	    if sudo -u $LINUXUSER $SCPBIN $LINUXUSER@$LINUXHOST:$LINUXFOLDER/$(hostname)$BACKUPFOLDER"rdiff-backup-data/backup.log" /tmp/backuprdifftemp.log; then
				# copy log from tmp to /var/log
				if cat /tmp/backuprdifftemp.log >> $LOGPATH/$RDIFFLOGSSH; then
				    if test -e $SSHBIN; then
					# delete log on other system
					if ! sudo -u $LINUXUSER $SSHBIN -l $LINUXUSER $LINUXHOST rm $LINUXFOLDER/$(hostname)$BACKUPFOLDER"rdiff-backup-data/backup.log"; then
					    echo "Error: Backup log could not be deleted on other host!" >> $LOGPATH/$RDIFFLOGSSH
					fi
				    else
					echo "Error:" $SSHBIN "not found!" >> $LOGPATH/$RDIFFLOGSSH
				    fi
				else
				    echo "Error: Backup log could not be moved!" >> $LOGPATH/$RDIFFLOGSSH
				fi
			    else
			        echo "Error: Backup log could not be copied from other host!" >> $LOGPATH/$RDIFFLOGSSH
			    fi
			else
			    echo "Error:" $SCPBIN "not found!" >> $LOGPATH/$RDIFFLOGSSH
			fi
		    else
		        echo "Error: Rdiff-backup could not run" >> $LOGPATH/$RDIFFLOGSSH
		        backuperror=1
		    fi
		
		
		else
		    echo "Error:" $RDIFFBIN "not found!" >> $LOGPATH/$RDIFFLOGSSH
	    	    echo "Your system reports it at" && which rdiff-backup >> $LOGPATH/$RDIFFLOGSSH
		    backuperror=1
		fi
	

    
	    if [ "${EMAILSSH,,}" == "yes" ]; then
    		# mail file
		if [ "${backuperror,,}" == "1" ]; then
		
		    if mail -s "[$PROGNAME] Rdiff-backup $(hostname) to $LINUXHOST had errors" $EMAILTO < $LOGPATH/$RDIFFLOGSSH; then
    			echo "Mail sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGSSH
    		    else
    			echo "Error: Mail could not be sent!" >> $LOGPATH/$RDIFFLOGSSH
    		    fi
		
		else
		
    		    if mail -s "[$PROGNAME] Rdiff-backup $(hostname) to $LINUXHOST completed" $EMAILTO < $LOGPATH/$RDIFFLOGSSH; then
    			echo "Mail sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGSSH
    		    else
    			echo "Error: Mail could not be sent!" >> $LOGPATH/$RDIFFLOGSSH
    		    fi
    		fi
	    fi
	    
	    
	    if [ "${backuperror,,}" == "1" ] && [ "${RDIFFSSHDAYCHECK,,}" == "no" ]; then
		#move to old log, so we could run backup again on the same day, but only in case errors
    		if test -e $LOGPATH/$RDIFFLOGSSH; then
    		    if ! mv $LOGPATH/$RDIFFLOGSSH $LOGPATH/$RDIFFLOGSSH-$rdiffdate1; then
    		        echo "Error: Could not move old log!" >> $LOGPATH/$RDIFFLOGSSH
    		    fi
    		fi
    	    fi

	else
	    echo "Error: remote volume on" $LINUXHOST "critial capacity reached!"
	    funct-umount-ssh
	fi
	
    else
        echo "Error: remote host" $LINUXHOST "is not reachable!"
    fi

fi


    ;;

    backupconfig)
    
    if [ "${COMPRARCHIVES,,}" -ge 1 ]; then
    
    funct-backupconfig

    if [ "${EMAILCONFIG,,}" == "yes" ]; then
    	# mail file
    	
    	if [ "${backuperror,,}" == "1" ]; then
	
    	
    	    if mail -s "[$PROGNAME] - RAR Backup on $(hostname) had errors" $EMAILTO < $LOGPATH/$RDIFFLOGCONFIG; then
    		echo "Mail sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGCONFIG
    	    else
    		echo "Error: Mail could not be sent!" >> $LOGPATH/$RDIFFLOGCONFIG
    	    fi
    
	else
	
	    if mail -s "[$PROGNAME] - RAR Backup on $(hostname) completed" $EMAILTO < $LOGPATH/$RDIFFLOGCONFIG; then
    		echo "Mail sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGCONFIG
    	    else
    		echo "Error: Mail could not be sent!" >> $LOGPATH/$RDIFFLOGCONFIG
    	    fi
    	    
	fi
    
    fi

    else
    
    echo "Error: Configure parameters first!" >> $LOGPATH/$RDIFFLOGCONFIG

    fi

    ;;


    backupwin)

funct-backupwindaycheck

if [ "$backupwin" == "1" ] || [ "$RDIFFDAYCHECK" == "--force" ] ; then

    if [ "$RDIFFDAYCHECK" == "--force" ]; then
	echo "INFO: --force switch is enabled, so the script is allowed to run multiple times per day"
    fi


    if [ "$(ping -c 1 $SMBSOURCE | grep "1 received")" ]; then
	echo "OK: remote host" $SMBSOURCE "is reachable"
	echo "Wait" $TIMERVALWIN "seconds to be sure host is ready and not still booting up..."
	sleep $TIMERVALWIN

	funct-mount-win
	funct-spacefree win
	
	if [ ! "${spacefreeperc,,}" -ge $CAPCRIT ]; then
	    
	    #move old log, otherwise old logs will be mailed everytime again
    	    if test -e $LOGPATH/$RDIFFLOGWIN; then
    	        if ! mv $LOGPATH/$RDIFFLOGWIN $LOGPATH/$RDIFFLOGWIN-$rdiffdate1; then
    	        echo "Error: Could not move old log!" >> $LOGPATH/$RDIFFLOGWIN
    	        fi
    	    fi
    	    
    	    if [ "${COMPRARCHIVES,,}" -ge 1 ]; then
    	    funct-backupconfig
    	    cat $LOGPATH/$RDIFFLOGCONFIG >> $LOGPATH/$RDIFFLOGWIN
	    fi
	    
    	    if [ "$(mount | grep $LOOPTARGET)" ]; then
    		# add information to log
    		echo $(date)": rdiff-backup of" $BACKUPFOLDER "to //"$SMBSOURCE/$SMBSHARE/$BACKUPFILE "started." $BACKUPFILE "contains an" $MOUNTFS "filesystem." >> $LOOPTARGET/$(hostname)$BACKUPFOLDER"rdiff-backup-data/backup.log"
    		# delete older than defined in variable FILEOT
    		if test -e $RDIFFBIN; then
    			if $RDIFFBIN -v$LOGLEVEL --remove-older-than $FILEOT $LOOPTARGET/$(hostname)$BACKUPFOLDER; then
    			    echo "rdiff-backup OK: --remove-older-than" $FILEOT $LOOPTARGET/$(hostname)$BACKUPFOLDER >> $LOGPATH/$RDIFFLOGWIN
    			else
    			    backuperror=1
    			fi
			# start backup
    			if $RDIFFBIN -v$LOGLEVEL --include-globbing-filelist $PROGPATH/$INCLUDELIST --exclude-globbing-filelist $PROGPATH/$EXCLUDELIST $BACKUPFOLDER $LOOPTARGET/$(hostname)$BACKUPFOLDER; then
    			    echo "rdiff-backup OK:" $BACKUPFOLDER $LOOPTARGET/$(hostname)$BACKUPFOLDER
    			else
    			    backuperror=1
    			fi
		else
		    echo "Error:" $RDIFFBIN "not found!" >> $LOGPATH/$RDIFFLOGWIN
		    echo "Your system reports it at" && which rdiff-backup >> $LOGPATH/$RDIFFLOGWIN
		    backuperror=1
		fi
		# copy rdiff-backup log to script logfile because will not be available when unmounted
    		cat $LOOPTARGET/$(hostname)$BACKUPFOLDER"rdiff-backup-data/backup.log" >> $LOGPATH/$RDIFFLOGWIN
    		if [ "${EMAILWIN,,}" == "yes" ]; then
    		    # delete backup log, otherwise old logs get mailed again
    		    if ! rm $LOOPTARGET/$(hostname)$BACKUPFOLDER"rdiff-backup-data/backup.log"; then
    		    echo "Error: Could not delete old log on loopmount!" >> $LOGPATH/$RDIFFLOGWIN
    		    fi
    		fi
    	    else
    		echo "Error:" $LOOPTARGET "not mounted, cannot continue with rdiff-backup!" >> $LOGPATH/$RDIFFLOGWIN
    		backuperror=1
    	    fi
    	    
	    funct-umount-win
    
	    if [ "${EMAILWIN,,}" == "yes" ]; then
    		# mail file
    		
    		if [ "${backuperror,,}" == "1" ]; then
    		
    		    if mail -s "[$PROGNAME] - Rdiff-backup $(hostname) to $SMBSOURCE had errors" $EMAILTO < $LOGPATH/$RDIFFLOGWIN; then
    			echo "Mail sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGWIN    		    
    		    else
    			echo "Error: Mail could not be sent!" >> $LOGPATH/$RDIFFLOGWIN
    		    fi
    		
    		else
    		
    		    if mail -s "[$PROGNAME] - Rdiff-backup $(hostname) to $SMBSOURCE completed" $EMAILTO < $LOGPATH/$RDIFFLOGWIN; then
    			echo "Mail sent to " $EMAILTO >> $LOGPATH/$RDIFFLOGWIN
    		    else
    			echo "Error: Mail could not be sent!" >> $LOGPATH/$RDIFFLOGWIN
    		    fi
    		
    		fi
	    fi

	    if [ "${backuperror,,}" == "1" ] && [ "${RDIFFWINDAYCHECK,,}" == "no" ]; then
	        #move to old log, so we could run backup again on the same day, but only in case errors
    		if test -e $LOGPATH/$RDIFFLOGWIN; then
    		    if ! mv $LOGPATH/$RDIFFLOGWIN $LOGPATH/$RDIFFLOGWIN-$rdiffdate1; then
    			echo "Error: Could not move old log!" >> $LOGPATH/$RDIFFLOGWIN
    		    fi
    		fi
    	    fi

	else
	    echo "Error: remote volume on" $SMBSOURCE "critical capacity reached!"
	    funct-umount-win
	fi

    else
	echo "Error: remote host" $SMBSOURCE "is not reachable!"
    fi


fi

    ;;

    mount)

    	case "$2" in
	    win)
	    funct-mount win
	    funct-listmount win
	    ;;
	    ssh)
	    funct-mount ssh
	    funct-listmount ssh
	    ;;
	    *)
	    echo "Error: No valid target given!"
	    ;;
	esac

    ;;

    umount)
    
    	case "$2" in
	    win)
	    funct-umount win
	    ;;
	    ssh)
	    funct-umount ssh
	    ;;
	    *)
	    echo "Error: No valid target given!"
	    ;;
	esac

    ;;

    listmount)
    
	case "$2" in
	    win)
	    funct-listmount win
	    ;;
	    ssh)
	    funct-listmount ssh
	    ;;
	    *)
	    echo "Error: No valid target given!"
	    ;;
	esac
    
    
    ;;
    
    createssh)

if test -e $DIALOGBIN; then

$DIALOGBIN --ok-label "Submit" --title "Create SSH" --form "The next step will setup the ssh connection to the remote host. Found the settings below. If you need to change them, you need to modify parameters inside the script later" 15 60 0 \
"Linux/Unix Host:" 1 1 "$LINUXHOST" 1 20 100 0 \
"SSH User:" 2 1 "$LINUXUSER" 2 20 100 0 2>$_temp

    if [ $? -eq 0 ]; then


	if [ "$(ping -c 1 $LINUXHOST | grep "1 received")" ]; then

	    LINUXHOST=`cat $_temp | sed -ne '1p'`
	    LINUXUSER=`cat $_temp | sed -ne '2p'`
	
	    if sudo -u $LINUXUSER yes|ssh-keygen -t rsa -f /home/$LINUXUSER/.ssh/id_rsa -N ''; then
		chmod 600 /home/$LINUXUSER/.ssh/id_rsa
		chmod 600 /home/$LINUXUSER/.ssh/id_rsa.pub
		
		echo "Please enter "$LINUXUSER"'s password if it will be requested:"
		
		if su -c "scp /home/$LINUXUSER/.ssh/id_rsa.pub $LINUXUSER@$LINUXHOST:/home/$LINUXUSER/.ssh/authorized_keys" $LINUXUSER; then
		    su -c "echo host $LINUXHOST" root > /root/.ssh/config
		    su -c "echo hostname $LINUXHOST" root >> /root/.ssh/config
		    su -c "echo user $LINUXUSER" root >> /root/.ssh/config
		    su -c "echo identityfile /home/$LINUXUSER/.ssh/id_rsa" root >> /root/.ssh/config
		    chmod 600 /root/.ssh/config
		    $DIALOGBIN --title "Create SSH" --msgbox "All done! Users $LINUXUSER and root are now able to ssh into $LINUXHOST without password. You can start backup now with 'rdiffback.ssh backup ssh'." 10 60
		else
		    echo "Error: could not copy id_rsa.pub to remote system!"
		fi
	    else
		echo "Error: could not create local ssh key!"
	    fi
	else
	    $DIALOGBIN --title "Create SSH" --msgbox "Error: Remote Host is not responding!" 10 60
	fi
    
    else
	$DIALOGBIN --title "Create SSH" --msgbox "Operation canceled on user request!" 10 60
    fi


else
echo "dialog not found, is it installed?"
fi

    ;;

    createloop)

if test -e $DIALOGBIN; then

$DIALOGBIN --ok-label "Submit" --title "Create Loop" --form "WARNING: THE NEXT STEPS WILL CREATE NEW BACKUPFILE. Found the settings below. If you need to change them, you need to modify parameters inside the script later" 15 60 0 \
"CIFS Host:" 1 1 "$SMBSOURCE" 1 20 100 0 \
"CIFS Share:" 2 1 "$SMBSHARE" 2 20 100 0 \
"CIFS mounted on:" 3 1 "$SMBTARGET" 3 20 100 0 \
"CIFS mount options:" 4 1 "$MOUNTCIFS" 4 20 200 0 \
"Backupfile:" 5 1 "$BACKUPFILE" 5 20 100 0 \
"Filesystem:" 6 1 "$MOUNTFS" 6 20 100 0 \
"Mounted on:" 7 1 "$LOOPTARGET" 7 20 100 0 2>$_temp


    if [ $? -eq 0 ]; then
 

	SMBSOURCE=`cat $_temp | sed -ne '1p'`
	SMBSHARE=`cat $_temp | sed -ne '2p'`
	SMBTARGET=`cat $_temp | sed -ne '3p'`
	MOUNTCIFS=`cat $_temp | sed -ne '4p'`
	BACKUPFILE=`cat $_temp | sed -ne '5p'`
	MOUNTFS=`cat $_temp | sed -ne '6p'`
	LOOPTARGET=`cat $_temp | sed -ne '7p'`

	echo "do clean umount to make sure there is no loopmount active"
	funct-umount win
     if [ ! "$(mount | grep $SMBTARGET)" ]; then
	    echo "mount" $SMBTARGET
	    echo "execute: mount -t cifs -o $MOUNTCIFS //$SMBSOURCE/$SMBSHARE $SMBTARGET" 
	    mount -t cifs -o $MOUNTCIFS //$SMBSOURCE/$SMBSHARE $SMBTARGET
	
	if [ "$(mount | grep $SMBTARGET)" ]; then
		if test -e $SMBTARGET/$BACKUPFILE; then
		    $DIALOGBIN --title "Create Loop" --inputbox "WARNING: $BACKUPFILE ALREADY EXISTS, DO YOU REALLY WANT TO OVERWRITE IT? Type in the word AGREE" 10 60 2>$_temp
		    result=`cat $_temp`
		    if [[ $result =~ agree|AGREE ]]; then
			$DIALOGBIN --title "Create Loop" --inputbox "How big the $MOUNTFS formatted file should be? This operation can take a while. Enter size in MB:" 10 60 2>$_temp
			result=`cat $_temp`
			if [ -z "$(echo $result|tr -d '[:digit:]')" ] && [ $? == 0 ]; then
			    if [ "$(mount | grep $LOOPTARGET)" ]; then
				$DIALOGBIN --title "Create Loop" --msgbox "Error: $LOOPTARGET is still mounted, cannot continue!" 10 60
			    else
				echo "Overwrite File" $BACKUPFILE "this may take a while, do not cancel"
				dd if=/dev/zero of=$SMBTARGET/$BACKUPFILE bs=1M count=$result
		
				if test -e $SMBTARGET/$BACKUPFILE; then
				    echo "Format existing" $BACKUPFILE " with Filesystem" $MOUNTFS
				    mkfs.$MOUNTFS $SMBTARGET/$BACKUPFILE
				    $DIALOGBIN --title "Create Loop" --msgbox "Format new file $BACKUPFILE with $result MB and filesystem $MOUNTFS finsihed successfully!" 10 60
				else
				    $DIALOGBIN --title "Create Loop" --msgbox "Error: $BACKUPFILE could not be create!" 10 60
				fi
			    fi
			else
			    $DIALOGBIN --title "Create Loop" --msgbox "Error: Value is not in digits!" 10 60
			fi
		    else
		    $DIALOGBIN --title "Create Loop" --msgbox "Operation canceled on user request!" 10 60
		    fi
		else
		    $DIALOGBIN --title "Create Loop" --inputbox "Couldnt find existing backupfile $BACKUPFILE so i will create a new one. Enter size in MB:" 10 60 2>$_temp
		    result=`cat $_temp`
		    if [ -z "$(echo $result|tr -d '[:digit:]')" ] && [ $? == 0 ]; then
		    dd if=/dev/zero of=$SMBTARGET/$BACKUPFILE bs=1M count=$result
			if test -e $SMBTARGET/$BACKUPFILE; then
			    echo "Format new file " $BACKUPFILE "with Filesystem" $MOUNTFS
			    mkfs.$MOUNTFS $SMBTARGET/$BACKUPFILE
			    $DIALOGBIN --title "Create Loop" --msgbox "Format new file $BACKUPFILE with $result MB and filesystem $MOUNTFS finished successfully!" 10 60
			else
			    $DIALOGBIN --title "Create Loop" --msgbox "Error: $BACKUPFILE could not be created!" 10 60
			fi
		    else
			$DIALOGBIN --title "Create Loop" --msgbox "Error: Value is not in digits!" 10 60 
		    fi
		fi
	else
	    $DIALOGBIN --title "Create Loop" --msgbox "Error: $SMBTARGET could not be mounted, cannot continue!" 10 60
	fi
	
     else
        $DIALOGBIN --title "Create Loop" --msgbox "Error: There was an error during umount!" 10 60
     fi

    else
	$DIALOGBIN --title "Create Loop" --msgbox "Operation canceled on user request!" 10 60
    fi



else
echo "dialog not found, is it installed?"
fi
    ;;

    *)

	echo
	echo -e "\033[33m\033[44MSPROGPATH/$PROGNAME \033[0m Version $PROGVER"
	echo "Makes it possible to backup local folders to an remote Linux/Unix or Windows host."
	echo "Usage: $PROGNAME [backupssh [--force]|backupwin [--force]|backupconfig|createloop|createssh|mount [win|ssh]|umount [win|ssh]|listmount [win|ssh]]"
	echo -e "\033[31mMake sure you change settings inside $PROGNAME to your needs before you run first backup!\033[0m"
	echo
	echo -e "\033[4mMain Options\033[0m"
	echo
	echo -e "\033[1mbackupssh\033[0m: rdiff-backup to other linux/unix host over ssh. Make sure the access is not denied on the remote host."
	echo -e "If --force is used, it can be run multiple times per day if RDIFFSSHDAYCHECK is enabled."
	echo -e "\033[1mbackupwin\033[0m: rdiff-backup to other win host over CIFS/SMB. Use --force to override RDIFFWINDAYCHECK parameter."
	echo "Because Windows cannot handle different files with lower/upper case, a loop mount" 
	echo "to an linux fs on that CIFS share will be used."
	echo -e "\033[1mbackupconfig\033[0m: RAR specified folders to local file system, included also in above options."
	echo
	echo -e "\033[4mHelper Options\033[0m"
	echo
	echo -e "\033[1mcreateloop\033[0m: Starts prompted script for creation of Linux filesystem on SMB Share."
	echo -e "\033[1mcreatessh\033[0m: Starts prompted script for ssh setup to remote ssh machine."
	echo
	echo -e "\033[1mmount win\033[0m: Mounts SMB Share and loop mounts an Linux filesystem on it so you can access the backup files."
	echo -e "\033[1mumount win\033[0m: Same as above with unmount and unloading of Rdiff-web."
	echo -e "\033[1mmount ssh\033[0m: Mounts Unix/Linux share over NFS in order to see backed files in rdiff-web."
	echo -e "\033[1mumount ssh\033[0m: Same as above with unmount and unloading of Rdiff-web."
	echo -e "\033[1mlistmount\033[0m: Lists if above paths are mounted."
	exit 1
	;;

esac

Beispiel: rdiffbackinclude
Code:
/data
/usr/lib/nagios*
/usr/share/nagios*
/usr/share/logwatch
/var/vmail
/var/www*
/var/lib/mysql

Beispiel: rdiffbackexlude
Code:
**
 
Zuletzt bearbeitet:
Zurück
Oben Unten