Backup di client Windows con BackupPC: Difference between revisions

From RVM Wiki
Jump to navigation Jump to search
mNo edit summary
 
(29 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Stub}}
==Configurazione Client da backuppare==
 
==Configurazione Client==


* Installare cygwin con
* Installare cygwin con
binutils
  openssh
  openssh
  rsync
  rsync
screen
unzip
  util-linux
  util-linux
vim
wget
zip


* Impostare Environment Variables
* Impostare Environment Variables
: Right click My Computer, Properties, Advanced, Environment Variables, System Variables
: Right click My Computer, Properties, Advanced, Environment Variables, System Variables
** add a Variable:  
** Aggiungere:  
  CYGWIN = ntsec tty
  CYGWIN = ntsec
** edit Variable
** Modificare il PATH aggiungendo
  PATH, add: ;c:\cygwin\bin
  ;c:\cygwin\bin
 
** Just to be sure reboot.


* Make sure every Windows user has a password set (System Preference / User Accounts) and Make sure every Windows user has done the following at least once (this will create home directories for every user):
* Make sure every Windows user has a password set (System Preference / User Accounts) and Make sure every Windows user has done the following at least once (this will create home directories for every user):
** Login in as Administrator
** also start cygwin terminal


* Configurare ssh come Administrator, aprendo un cygwin terminal in locale:
* Configurare ssh come Administrator, aprendo un cygwin terminal in locale:
  ssh-host-config
  ssh-host-config --yes --cygwin ntsec




* Rispondere si a tutte le domande, e When stop and question:
* Se lo si fa invece manualmente, rispondere si a tutte le domande, e settare quando richiesto
  environment variable CYGWIN =
  CYGWIN = ntsec
:type in:
ntsec tty
 


** If you get an error message (Windows XP)
** If you get an error message (Windows XP)
Line 36: Line 32:
: >> Change permissions:  
: >> Change permissions:  
  chmod 775 /var
  chmod 775 /var
* Se non ci si riesce a loggare, e l'utente Windows usato per il servizio è di dominio, bisogna aggiungergli la policy locale di ''Create token object'':
gpedit.msc
local computer policy\computer configuration\windows settings\security settings\local policies\user rights assignment
look for 'create a token object'
add DOMAINNAME\cyg_server user


* Start ssh with:  
* Start ssh with:  
Line 45: Line 47:
  mkgroup --local > /etc/group
  mkgroup --local > /etc/group


* Creare le directory di ssh
* Creare le directory di ssh (a volte è necessario forzare lo username con la "A" maiuscola):
  ssh localhost
  ssh Administrator@localhost


* Disabilitare il firewall
* Disabilitare il firewall


* Test SSH while in Cygwin:  
===Client scripts===
  ssh Administrator@$myclient
* Installare i programmi:
cd
wget -O backuppc-shadow.zip http://support.rvmgroup.it/download/backuppc-shadow.zip
cd /usr/local/bin
unzip -ox ~/backuppc-shadow.zip && rm -f ~/backuppc-shadow.zip
  cp vshadow-CYGWIN_NT-5.2.exe vshadow-CYGWIN_NT-5.2-WOW64.exe


* (Verificare se serve) Installare Volume [http://www.microsoft.com/downloads/details.aspx?FamilyID=0B4F56E4-0CCC-4626-826A-ED2C4C95C871&displaylang=en Shadow Copy Service SDK 7.2]
* Sistemare le permission
 
chgrp Administrators /usr/local/bin/*
* Scaricare [dosdev.zip http://www.ltr-data.se/files/dosdev.zip]
  chmod 755 /usr/local/bin/*
 
* Copiare in
  /usr/local/bin
:i files
vshadow.exe
dosdev.exe


* Creare lo script:
* Modificare i DISCHI da shadoware:
vi /usr/local/bin/pre-backup.sh


  vi /usr/local/bin/shadowexec.cmd
* Creare il file di configurazione:
  vi /etc/backuppc-shadow


<pre>
<pre>
REM Shadowexec.cmd
DRIVES="c d e"
REM Version 0.4.5 (November 2009)
ACL=true 
REM This cmd.exe script file should be in the same directory as the
SHADOW=true
REM bash script: shadowmountrsync
@echo OFF
C:\cygwin\bin\bash.exe -c "$(cygpath.exe '%~p0\shadowmountrsync') -3 %ARGS%"
</pre>
</pre>
* Creare lo script:
vi /usr/local/bin/shadowmountrsync
<pre>
#!/bin/bash
# Shadowmountrsync
# Copyright Jeffrey J. Kosowsky 2008, 2009
# Version 0.4.5.2 (November 2009)
##############################################################################
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
##############################################################################
### DESCRIPTION:
# Automagically sets up (and takes down) shadow copies,
# shadow mounts, and the rsyncd daemon to allow you to seamlessly
# rsync to shadow copies of all the active modules in your current
# rsyncd.conf file WITHOUT any configuration changes or added settings
# to your existing setup non-shadow copy rsyncd setup. In particular,
# the program determines which shadows to create based upon the
# modules in your existing /etc/rsyncd.conf combined with what mounts
# actually exist.
### USAGE: (see below for more detailed usage)
# shadowmountrsync
#      Sets up shadow copies, mounts shadows, and launches rsync
# shadowmountrsync -d
#      Terminates rsync, kills shadow copies, unmounts, and cleans up
#
# If using as pre/post commands in BackupPC, try something like:
#$Conf{DumpPreUserCmd} =
#        '$sshPath -q -x -l <username> $hostIP /usr/local/bin/shadowmountrsync';
#
#        $Conf{DumpPostUserCmd} =
#            '$sshPath -q -x -l <username> $hostIP /usr/local/bin/vshadow-scripts/shadowmountrsync -d';
#
# Note: using shadows doesn't make sense for the Restore commands
# since clearly shadow copies CANNOT be restored to since by
# definition they are read-only. However, you still might want to use
# this script to launch rsyncd.
### WARNING: This is beta software which has only been tested to work
# so far on my own XP sp3 setup in a limited number of situations. In
# particular, it may not work on other Windows versions since the
# nature of shadow copy (and vshadow and dosdev) in particular has
# changed radically for Windows versions both prior to and post
# WinXP. Given the nature of shadow copy, it *should* (theoretically)
# not be capable of doing anything destructive to the source disk, so
# it's likely that the worse that would happen is that your backups
# would fail (or potentially be incomplete/corrupted). Feedback, bug
# reports, and enhancements are always welcome!!!
#
### PREREQUISITES:
# NOTE: both this script and the companion 1-liner 'shadowexec.cmd'
# file MUST be stored in the SAME directory on each Windows CLIENT
# machine that you want to backup using volume shadow service
# (VSS). Also, both files need to be in the $ADMINGRP group (typically
# 'Administrators' or 'root') group and set with group permissions +rx
#
# REQUIRES:
#  vshadow.exe
#      Available from Microsoft downloads (make sure you get the
#      right version for your Windows OS release!)
#      http://www.microsoft.com/downloads/details.aspx?FamilyID=0B4F56E4-0CCC-4626-826A-ED2C4C95C871&displaylang=en
#
#  dosdev.exe
#      Again available from Microsoft downloads (as part of their
#      reporting tools). Also, be careful of the version since
#      different verssions seem to have different command line
#      interfaces. I obtained my copy from:
#        http://www.ltr-data.se/files/dosdev.zip
#
#  cygwin (a base install should be sufficient)
#      This or an equivalent unix-like environment on Windows is
#      required to provide the Bash shell and basic gnu utilities
#      such as sed, date, cat, etc. As detailed below, you should
#      also install the sshd (ssh server) and rsync packages.
#
#  rsyncd (may be easiest to use the cygwin package version)
#      Note rsyncd does not need to be set up as a windows or cygwin
#      service since the script will launch and kill the rsyncd daemon
#      as appropriate
#
#  sshd (i.e. ssh server - use the cygwin version)
#      This is required to allow the Backuppc server to login to the
#      Windows client and run this script. Technically, you could use
#      any remote shell that allows you to run commands remotely,
#      though this script is specialized to get around the user id
#      limitations of cygwin ssh.
#
#  [optional] subinacl.exe
#      Only required if backing up ACLs and you want to use this
#      method instead of or in addition to 'getfacl'. The program is a
#      free download from Microsoft (note I found that the older
#      version included with the Windows Server 2003 toolkit didn't
#      work on XP but the following version did):
#      http://www.microsoft.com/downloads/details.aspx?FamilyID=E8BA3E56-D8FE-4A91-93CF-ED6985E3927B
#
#  Note the above executables need to be in the default path for the
#  SYSTEM and ADMINISTRATOR users (I put them in /usr/local/bin or
#  equivalently in C:\cygwin\usr\local\bin) either as specified by the
#  PATH variable below or by explicitly adding the path to each
#  executable variable as defined below. Of course, thes programs need
#  to be readable and executable by the above-mentioned users.
### HOW-IT-WORKS
# The program recurses through this routine 3 times because of
# the limitations first of ssh and then of vshadow. An additional
# '0th' pass is used to terminate the shadow copy & clean up. 
#
# In particular, cygwin ssh logins lack the authority to create shadow
# copies or set up dos devices since it is not a true authenticated
# user login. In particular, under ssh, $USERNAME=SYSTEM.
# On the other hand, vshadow is quite crippled in XP since
# it cannot create shadow copies nor can they be easily
# mounted. Dosdev is necessary because cygwin does not (yet) allow
# direct mounting of shadow copy devices since they lie in the kernel
# namespace.
#
# Since the program recurses both under the login user and under the
# SYSTEM user (for ssh), you need to be attentive to permissions. The
# program tries to detect and log such errors, but in particular:
# vshadow, dosdev, this bash script (and its cmd.exe companion), the
# log & pid lock files, and the shadowdir should all be readable (and
# where appropriate writable & executable) by the $ADMINGRP (typically
# 'Administrators' or 'root' group). Note also that the drive letter
# string $ALLDRIVES can be restricted if you are likely to be
# mounting/unmounting temporary devices (like cds, dvds) requiring a
# fixed drive letter assignment during the rsync time. You do not need
# to restrict it for fixed drives (e.g. C:) since they are
# automatically avoided if present at the time of shadow creation.
#
# The recursion operates as follows:
# First, since the ssh login lacks the authority to create shadow
# copies or to set up dos devices, the program schedules an 'at' job
# (for the next minute) to recurse again through this routine. (If not
# launched from 'ssh' then for parallelism, the recursion is directly
# launched with cmd.exe).
#
# Then, 'vshadow' calls the routine a third time once the shadow copy
# has been set up to commplete the post-processing, including setting
# up device letters and mounting them and then starting the rsyncd
# daemon on an appropriately modified version of the original
# rsyncd.conf. This shadow -exec script needs a a 1-line helper bash
# cmd script since the -exec script can't take arguments and must be
# either a .cmd or .exe file. The shadow exec script (3rd pass) also
# works to keep the shadow copy alive (mimicking persistence) by
# launching the rsync daemon with the no-detach option.
#
# Finally, when the transfer is completed and rsyncd is killed, the
# whole recursion unwinds and everything gets cleaned up
# appropriately.
# Note that pass #2 which sets up the shadow copies (which is also
# visible as the 'at' job if under ssh) and pass #3 (which is the
# script that mounts the shadow copies and launches rsync) remain
# alive until rsyncd is terminated. Pass #1 which kicks off the
# recursion hangs around until either a setup error is detected or
# until the setup is completed with the launch of the rsync daemon, at
# which time it returns and signals the result to the calling
# process. In particular, this initial pass returns '0' on success and a
# positive error code [1-8] on error.
#
# Indeed, the easiest/cleanest/best way to unwind the recursions and
# cause everything to reset gracefully is to kill the final 'rsync'
# process for which everything else ends up waiting. The '-d' option
# first tries to clean up gracefully like this but if it fails then it
# uses brute force to kill rsyncd, delete mounts, shutdown shadow
# copies, and remove pid lock files.
#
# Given the complexity of the multiple recursions, the program has
# been instrumented with plentiful (but optional) logging turned on by
# setting the LOG variable to the log file you want to use. Indeed,
# the logging is fun and instructive to watch ;)
### KEY USER VARIABLES
# The value of $USESHADOWS determines what happens if shadow copies
# cannot be created. If set to 0, then rsyncd is used without
# shadows. If 1, then shadows are attempted and the program exits on
# error if they can't (or shouldn't -- see $EXPIRELOCKS) be
# created. If 2, then shadows are first attempted but if not possible
# then rsync is run alone without shadows.
#
# The value of $EXPIRELOCKS determines whether the routine aborts or
# proceeds when it encounters pre-existing rsync process, shadow
# copies (if using shadows) and their corresponding pid lock
# files. When set to < 0, it always aborts. When set to 0, it always
# kills existing processes and proceeds.  When set to >1, it proceeds
# only if the processes and pid lock files are greater than
# $EXPIRELOCKS minutes old. It's probably a good idea to set it to
# either -1 or to a large positive number unless you are sure that you
# won't be colliding with another shadow copy process. The downside is
# that if something is stuck, then the routine will abort (and
# optionally log the result) rather than forcing a clean up.
#
# By setting the variable ACL or command line -A (--ACL) it is
# possible to have the script dump the ACLs of each desired backup
# drive for inclusion in the backup. The ACLS are generated either by
# 'getfacl' (ACL=1) or more comprehensively by 'subinacl' (ACL=2) or
# by both (ACL=3) The dumps are gzipped but in a format that can be
# restored by 'setfacl' and 'subinacl' respectively. Note that
# 'subinacl' runs slower but dumps the full ntfs file ACLs while
# 'getfacl' only does the cygwin subset.  Additionally, the variable
# $ACLFINDPRUNE contains a list of files/directories to exclude from
# the 'getfacl' dump (typically temp folders, analogous to ones you
# wouldn't backup either. Similary, $ACLSUBINACLEXCLUDE is a list of
# paths to exclude for the 'subinacl' dump.  Note to read the subinacl
# files as plain text you may need to pipe the uncompressed version
# onto: iconv -f UTF-16LE -t UTF-8 | tr -d '\r'
#
# The array $ALLDRIVES lists all the drive letters that 'dosdeve.exe'
# can use to find a free letter. The default is A-Z. The array
# $SHADOWDRIVES lists the subset of drives that you want to
# shadow. Actual shadows are determined by AND'ing this list with the
# list of shares found in rsyncd.conf and the list of actually mounted
# drives.
#
# Finally, note that by setting the appropriate rsyncd.conf parameters
# (either in the $RSYNCDCONF file or in the script variables below or
# on the input line), one can have this version of rsyncd.conf run
# completely independently of your normal 'rsyncd' process.
###  EXIT/RETURN CODES:
# 0 = success
# 1 = wrong input arguments
# 2 = pid lock file exists
# 3 = rsync daemon already running
# 4 = active shadow copies already exist
# 5 = shadow routines (e.g, dosdev, vshadow, shadowexec.cmd) not accessible
# 6 = shadow permissions error
# 7 = shadow copies created not equal to requested
# 8 = not enough free drive letters
# 9 = timeout error waiting for shadows and mounts to set up
# 10 = rsync daemon failed to start properly
# 11 = unknown/unspecified error
### TROUBLESHOOTING
#  - Check permissions and path/locations for: this script, $DOSDEV, $SHADOW,
#    $SHADOWEXECCMD, $SHADOWDIR, $RSYNC, $RSYNCDCONF (and other variables
#    as appropriate)
#  - Check for presence of pid lock files for 'rsync' ($RSYNCPID) and
#    'vshadow' ($SHADOWPID), for active shadows ($SHADOW -q) and for running
#    'rsync' and 'vshadow' processes (ps -e | grep "$RSYNC\|$VSHADOW)
#  - Turn on logging (LOG=1) and look at 'tail -f $LOG' as it unfolds
#  - Try running 'shadowmountrsync -e0' (forces clean-up) via ssh login console
#  - Try running 'shadowmountrsync -e0 -u0 (no shadows; rsync only) via ssh login
#  - Try the above from a direct console login
#  - Try launching shadows from a direct console login: $VSHADOW -wait C:
#  - If all else fails, post to the BackupPC mailing list with details on
#    your setup, the errors, and the results of the above troubleshooting steps.
### CHANGELOG
# 0.4.0 Updated for new Cygwin 1.7 which doesn't like Win32 paths
# 0.4.1 Allow arbitrary cygdrive path prefixes ${CYGDRIVEPREFIX}
# 0.4.5 Add option to backup ACL's on each volume pre shadow/rsync launch
#      Changed '--strict' option to '--expire' -- see details
#      Bug fixes, code cleanup, additional logging instrumentation
# 0.4.5.2 Added ability to backup ACLs using 'subinacl' in addition to 'getfacl'
#        Added 'Troubleshooting' section and additional usage error checking
#        Changed $ACL variable and -A|--ACL paramater format.
#        Added $ACLSUBINACLEXCLUDE in addition to $ACLFINDPRUNE
#
##############################################################################
##############################################################################
##### USER MODIFIABLE VARIABLES
##############################################################################
PATH=/bin:/usr/bin:/usr/local/bin
CYGDRIVEPREFIX=$(mount -p | sed -ne "s/\(.*\S\)  \+\(user\|system\)  \+.*/\\1/p")
PATH=$PATH:${CYGDRIVEPREFIX}/c/WINDOWS/System32
ADMINGRP=Administrators  #Note some people may need to use 'root' instead
USESHADOWS=2  #0=no shadows, use straight rsync only;
              #1=use shadows with rsync, error if shadows not available
              #2=try to use shadows first, if not available use straight rsync
              #Also settable from command line with -u (useshadows) option
LOG=/var/log/shadow.log #Set if you want logging (advisable at least to start)
DOSDEV=dosdev                  #Name of 'dosdev' executable
VSHADOW=vshadow                #Name of 'vshadow' executable
SHADOWEXECCMD=shadowexec.cmd    #Name of 1-liner helper script
                                #Must be in same directory as this script
SHADOWPID=/var/run/shadow.pid  #Name of shadow pid lock file
SHADOWDIR=/shadow              #Directory where shadow mounts are set up
  #MUST NOT be any dir where any other drives are mounted
  # (e.g. $CYGDRIVEPREFIX or /)
  #Note this counts as part of file name length so don't make path too long
ACL=0        #Set variable here or with -A (--ACL) command option to backup ACLs
              #0=no ACL dumps
              #1=dump using 'getfacl'
              #2=dump using 'subinacl'
              #3=dump using both 'getfacl' and 'subinacl'
ACLFILE="ACL" #Name stem (with optional path) for the ACL dump file relative
              #to root of each drive. ACL Files will be stored as
              #appropriate as:
              #  ${CYGDRIVEPREFIX}/<drive letter>/$ACLFILE-getfacl-<drive letter>.gz
              #  ${CYGDRIVEPREFIX}/<drive letter>/$ACLFILE-subinacl-<drive letter>.gz
SUBINACL=subinacl.exe #Needed only if using Windows-type ACL's
ACLFINDPRUNE="\(
-regex '//Documents and Settings\/[^/]*/Local Settings/Temp/.*' -o  \
-regex '//Documents and Settings/[^/]*/Local Settings/Temporary Internet Files/Content.IE5/.*' -o \
-regex '//Documents and Settings/[^/]*/Local Settings/Temporary Internet Files/Content.MSO/.*' -o \
-regex '//Documents and Settings/[^/]*/Local Settings/Application Data/Mozilla/Firefox/Profiles/[^/]*/Cache/.*' -o \
-regex '//System Volume Information/catalog.wci/.*' -o \
-iregex '//windows/system32/spool/printers/.*' -o \
-iregex '//windows/temp/.*' -o \
-wholename '//pagefile.sys' -o \
-wholename '//hiberfil.sys' -o \
-iwholename '//recycler/*' \
\) -prune -o"
            #'Prune' expression to insert in find to exclude various files
            #and directories. The default here excludes common temp files.
            #Note later in the routine, any path beginning with "//" is
            #replaced by "<share mount path>/".
            #Other paths are left as-is and should be absolute from root.
            #Note each path should be enclosed in '' or "" with a space
            #preceding it
ACLSUBINACLEXCLUDE="/pathexclude=\\System Volume Informaton\\catalog.wci \
/pathexclude=\\windows\\system32\\spool\\printers \
/pathexclude=\\pagefile.sys \
/pathexclude=\\hiberfil.sys \
/pathexclude=\\recycler"
            #'Pathexclude' expressions to insert in 'subinacl' call.
            #Note: since "*" is greedy across the entire path, we don't
            #want to use it in the middle of paths
            #Note later in the routine itself "/pathexclude=\\" is replaced by
            #"/pathexclude=<drive letter>:\\"
            #In particular, paths starting with a drive letter are left as-is
EXPIRELOCKS=1000  #Set to -1 (or anything < 0) if you want to always abort with
            #error if rsync process running or rsync.pid exists or if shadows
            #already exist (if $USESHADOWS > 0).
            #Set '0' if you want to ignore (and kill) existing rsync
            #and/or rsync processes
            #Set to 'N>1' if you want to ignore any existing rsync or
            #shadow processes provided that they are at least N minutes old
            #Also settable from command line with -e (--expire) option
TIMEOUT=300  #Time in seconds 1st pass waits for setting up before timing out
SHORTTIME=30 #Time in seconds to wait for cleanup to finish & rsync to set up
ALLDRIVES=$(echo {Z..A}) #Reverse alphabetical (all-caps)
            #Constrain to subset if you want to 'reserve' some positions
SHADOWDRIVES=$(echo {A..Z}) #List of drives to shadow (all-caps)
            #Constrain here or set with -l (--leters) command line option
            #if you *don't* want to shadow shares on certain drives
#Rsync variables:
RSYNC=rsync                  #Name of 'rsync' executable
RSYNCDCONF=/etc/rsyncd.conf  # Your original (non-shadow) version of rsyncd.conf
  #Note paths are expected to be in one of the following 2 forms:
  # path = /<drive letter>[/optional-rest-of-path>] [#optional comment]
  # path = ${CYGDRIVEPREFIX}[/<optional-rest-of-path>] [#optional comment]
RSYNCDCONF_SHADOW=$SHADOWDIR/rsyncd.shadow.conf #Location for modified version
                                        #of rsyncd.conf (auto-generated)
#The following allow additional (optional) params to be passed to rsync daemon
RSYNCDPID=  #Should be set in rsyncd.conf file as "pid file" (override here)
RSYNCDADDRESS=  #Or use command line option -a (--address)
RSYNCDPORT=    #Or use command line option -p (--port)
RSYNCDBWLIMIT=  #Or use command line option -b (--bwlimit)
RSYNCDOTHER=    #List of other user-settable rsync options
##############################################################################
##### Nothing below this line should ordinarily be user-modifiable
##############################################################################
##### Define some helper functions
#Parse options and determine pass number
function parse_opts ()
{
local OPTS
OPTS=`getopt -o 0123dA:a:b:c:e:hl:p:qu: --long delete,ACL:,address:,bwlimit:,conf:,help,letters:,port:,quiet,expire:,useshadows: -- "$@"`
if [ $? -ne 0 ] ; then
usage
[ -n "$LOG" ] && echo -e "ERROR: Illegal command line option: ${0##*/} $@\n" >> $LOG
exit 1
fi
local PARAMS=("$@")
eval set -- "$OPTS"
unset PASSNUM
while true; do
case "$1" in
#Set PASSNUM based on *first* use
-0|-d|--delete)
PASSNUM=${PASSNUM:-0}
if [ ${#PARAMS[@]} -gt 1 ]; then
[ -n "$LOG" ] && echo -e "ERROR: -d (--delete) option takes no other parameters\n" >> $LOG
usage
exit 1
fi
;;
-1 ) PASSNUM=${PASSNUM:-1};;
-2 ) PASSNUM=${PASSNUM:-2};;
-3 ) PASSNUM=${PASSNUM:-3};;
-A|--ACL) ACL=$2; shift;;
-a|--address) RSYNCDADDRESS=$2; shift;;
-b|--bwlimit) RSYNCDBWLIMIT=$2; shift;;
-c|--conf) RSYNCDCONF=$2; shift;;
-e|--expire) EXPIRELOCKS=$2; shift;;
-h|--help) usage; exit;;
-l|--letters) SHADOWDRIVES="$(echo $2 | tr 'a-z' 'A-Z')"; shift;;
-p|--port) RSYNCDPORT=$2; shift;;
-q|--quiet) unset LOG;;
-u|--useshadows) USESHADOWS=$2; shift;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
shift
done
PASSNUM=${PASSNUM:-1} #Default to pass 1 if not set
if ! [[ "$PASSNUM" =~ ^[0-3]$ ]] || \
! [[ "$ACL" =~ ^[0-3]$ ]] || \
! [[ "$EXPIRELOCKS" =~ ^-?[0-9]+$ ]] || \
! [[ "$SHADOWDRIVES" =~ ^[\ A-Z]+$ ]] || \
! [[ "$USESHADOWS" =~ ^[0-2]$ ]]
then
usage
[ -n "$LOG" ] && echo -e "ERROR: Illegal command line option: ${0##*/} ${PARAMS[@]}\n" >> $LOG
exit 1
fi
PASS="[Pass #$PASSNUM]"
if [ $PPID -ne 1 -a $PASSNUM -gt 1 ] ; then
usage
[ -n "$LOG" ] && echo -e "ERROR: passes 2 & 3 cannot be called directly...\n" >> $LOG
exit 1
fi
}
#Usage message
function usage ()
{
    cat <<EOF
Usage: (see below for more detailed usage)
    ${0##*/} [options]
      Sets up shadow copies, mounts shadows, and launches rsync
    ${0##*/} [-0|-d|--delete] [options]
      Terminates rsync, kills shadow copies, unmounts, and cleans up
  NOTE: all of the above options can be set to defaults in the
  script itself.  The options are there to allow you to override the
  defaults. Also, only the [-u|--useshadows]option  makes sense for the
  terminate [-d] usage.
    [-h|--help]
    [-a|--address] [address]  Override rsyncd.conf file to use given IP address
    [-b|--bwlimit] [kbps]    Override rsyncd.conf file to limit I/O bandwidth
    [-l|--letters] [ABC..]    Only create shadows for given letters (no spaces)
    [-p|--port] [port]        Override rsyncd.conf file to use given port
    [-q|--quiet]              Disable logging
[-r|--rsyncconf] [file]  Rsyncd.conf file location
    [-e|--expire] [N] where: [default = $EXPIRELOCKS]
            N=0 Proceed and start new process even if there are  existing
                shadow copies, rsyncd daemons, and pid lock files
            N>1 Proceed only if the above haven't been modified in >N minutes
            N<0 Exit with error if any of the above exist
    [-u|--useshadows] [0|1|2] where:
            0: Bypass shadow copy code and just start regular rsync daemon
            1: Create shadow copy and mounts - abort on error
            2: Try to create shadow copies, but revert to regular rsync daemon
                if not successful [default]
            In the -d case, setting N=0 means that it won't attempt to kill
            any existing shadow copies.
    [-A|--ACL] [0|1|2|3] Dump ACLs to gzipped files on each mount
            0: Don't dump ACLs [default]
            1: Dump with 'getfacl' to: <drive>:\\${ACLFILE}-getfacl-<drive>.gz
            2: Dump with 'subinacl' to: <drive>:\\${ACLFILE}-subinacl-<drive>.gz
            3: Dump with both 'getfacl' and 'subinacl' methods
  Description: automagically sets up (and takes down) shadow copies,
  shadow mounts, and the rsyncd daemon to allow you to seamlessly
  rsync to shadow copies of all the active modules in your current
  rsyncd.conf file WITHOUT any configuration changes or added settings
  to your existing non-shadow copy rsyncd setup
EOF
}
# Launches passed input via 'at' to get around $USERNAME=SYSTEM
# problem under ssh login where the shell lacks permsisions to run
# commmands like vshadow or dosdev
function at_launch ()
{
    local h m s wait command
command=$@
    set -- $(date +"%H %M %S")
h=$((10#$1))  #Note explicitly use base 10 so that 08 and 09 not interpreted as bad octal
m=$((10#$2 +1)) #Advance minutes by 1
s=$((10#$3))
wait=$((60 - $s))
    [ $s -gt 55 ] && let "m += 1" "wait += 60" # Make sure >5 seconds left
    [ $m -ge 60 ] && let "m %= 60" "h += 1" #Overflow minutes
    let "h %= 24"
at $h:$m $(cygpath -w $(which bash.exe)) -c \"$command\" > /dev/null
return $wait
}
#Return 0 if $SHADOWPID, $RSYNCDPID, and all the shadow images are older
#than $1 (where $1 is in minutes)
#Returns 1 otherwise or if $1 < 0 (i.e. strict error checking)
function is_older_than ()
{
[ $1 -eq 0 ] && return 0  # Trivial case  of zero age
[ $1 -lt 0 ] && return 1  # "Infinite age"
AGE=$(( $(date +%s) - 60*$1 ))
get_rsyncdpidfile
[ -e "$RSYNCDPID" ] && \
[ $(( $(stat -c %Y $RSYNCDPID) - AGE )) -gt 0 ] && return 1
if [ $USESHADOWS -gt 0 ] ; then
[ -e "$SHADOWPID" ] && \
[ $(( $(stat -c %Y $SHADOWPID) - AGE )) -gt 0 ] && return 1
( IFS=$'\n'
for date in $($VSHADOW -q | sed -ne "s/.*- Creation Time: \(.*M\) *$/\1/p"); do
[ $(( $(date -d "$date" +%s) - AGE )) -gt 0 ] && return 1
done
)
fi
return 0
}
# Populate SHADOWMOUNT with all drive letters (plus colon) that are present
# in rsyncd.conf and are actually mounted and are part of SHADOWDRIVES list
function get_shadowmounts ()
{
[ -n "$SHADOWMOUNT" ] && return # Don't run again if already populated
#Extract list of drive letter (followed by :) from rsyncd.conf,
    #converting to uppercase
local RSYNCMOUNTS=$(sed -ne "s%^[ \t]*path[ \t]*=[ \t]*\($CYGDRIVEPREFIX\)\?/\([A-Za-z]\)\([ \t]*$\|[ \t]*#\|/\).*%\u\2%p" $RSYNCDCONF | sort | uniq | sed -e "s|$|:|")
SHADOWMOUNT=()
for mount in $RSYNCMOUNTS ; do #Eliminate mounts that are not actually present
[ -d $(cygpath -u $mount) ] && [[ "$SHADOWDRIVES" =~ ${mount%:} ]] && \
SHADOWMOUNT=("${SHADOWMOUNT[@]}" "$mount") #array
    #Note as of Bash 3.2, RHS of =~ not quoted
done
}
# Populate FREEDRIVES with $1 *free* drive letters starting from list ALLDRIVES
function get_freedrives ()
{
FREEDRIVES=()
for letter in $ALLDRIVES ; do
mount | egrep -q "^$letter:" || \
FREEDRIVES=("${FREEDRIVES[@]}" "$letter") #array
[ ${#FREEDRIVES[@]} -eq $1 ] && return
done
}
# If not set manually, then get name of rsyncd pid file from rsyncd.conf
function get_rsyncdpidfile ()
{
[ -z "$RSYNCDPID" ] && RSYNCDPID=$(sed -ne "s/[ ]*pid file[ ]*=[ ]*\(.*[^ ]\)[ ]*\(#.*\|$\)/\1/p" $RSYNCDCONF)
}
# Kill rsyncd process
function kill_rsyncd ()
{
# Note we only want to kill rsync daemons that are bound to our rsync pid
# file. In particular, we don't want to kill regular rsync processes
# or even rsync daemons with an alternative rsync pid file that may be
# associated with another conf file (and different port/address).
get_rsyncdpidfile
[ -e "$RSYNCDPID" ] || return #No running rsyncd with our pid file
local PID=$(< "$RSYNCDPID") # Read in PID
if [ -n $PID ]; then
ps -e | grep -q "^[^0-9]*${PID}.*${RSYNC}$" && kill -TERM $PID && sleep 1
ps -e | grep -q "^[^0-9]*${PID}.*${RSYNC}$" && kill -KILL $PID && sleep 1
fi
[ -e "$RSYNCDPID" ] && rm -f "$RSYNCDPID" #Shouldn't be necessary...
}
# Delete shadows, unmount shadow mounts, and remove drive letters
function remove_shadows ()
{
local shadowmounts letter
( echo Y | $VSHADOW -da ) > /dev/null 2>&1 #Delete shadow copies and as a
        #positive side effect kills shadow process and spawned routines
shadowmounts=$(mount | sed -ne "s|^\([A-Za-z]\): on $SHADOWDIR/[A-Za-z] type.*|\1|p")
for letter in $shadowmounts ; do
umount $SHADOWDIR/$letter 2> /dev/null #Unmount
$DOSDEV /D "${letter}:" 2> /dev/null
        # Note dosdev doesn't work from ssh due to permissions and probably
# not necessary after shadows killed, but good hygiene
done
}
#If possible, gracefully unwind shadows by killing the shadowexec.cmd process
#Return 0 if unwinds successfully
function unwind_shadows ()
{
if [ "$USESHADOWS" -gt 0 -a -e $SHADOWPID ]; then
SCRIPTPID=$(< $SHADOWPID)
if [[ -n "$SCRIPTPID" && $SCRIPTPID -gt 0 ]]; then
[ -n "$LOG" ] && echo "--Attempting to clean up gracefully by unwinding shadow recursion...$PASS" >> $LOG
ps -e | grep -q "^[^0-9]*$SCRIPTPID.*/usr/bin/bash$" \
&& kill -TERM $SCRIPTPID && sleep 1
ps -e | grep -q "^[^0-9]*$SCRIPTPID.*/usr/bin/bash$" \
&& kill -KILL $SCRIPTPID && sleep 1
for ((WAIT=1; WAIT <=SHORTTIME; WAIT++)) ; do
            #Wait for unwinding recursion to clean up by itself
if [ ! -e "$SHADOWPID" ]; then #Successfully cleaned up by itself
[ -n "$LOG" ] && echo  "--Successfully unwound shadow recursion...$PASS" >> $LOG
return 0
fi
sleep 1
done
fi
fi
return 1 #Not able to clean up by unwinding recursion
}
#Clean up manually by killing rsync daemon & shadow processes and removing locks
function clean_up ()
{
kill_rsyncd
[ $USESHADOWS -gt 0 ] && remove_shadows
rm -f $RSYNCDCONF_SHADOW $SHADOWPID
[ -n "$LOG" ] && echo "..Finished clean_up... $PASS" >> $LOG
}
#Dump ACLs for each drive using either 'getfacl' or 'subinacl'
function backup_acls ()
{
get_shadowmounts
    [ -n "$LOG" ] && echo "--Starting ACL backup for volumes: ${SHADOWMOUNT[@]} $PASS" >> $LOG
for mount in ${SHADOWMOUNT[@]}; do
local mountpath="$(cygpath -u $mount)"
if [ $CYGVERTOT -ge 1007000 ] ; then
mount | egrep -i "^$mount on .* type ntfs \("  > /dev/null \
|| continue #Needs to be type ntfs (need cygwin >= 1.7)
fi
if [ $ACL -eq 1 -o $ACL -eq 3 ]; then # dump via 'getfacl'
ACLMOUNTFILE=$mountpath/$ACLFILE-getfacl-${mount/%:/}.gz
if touch $ACLMOUNTFILE 2> /dev/null ; then
chown $USER.$ADMINGRP $ACLMOUNTFILE
chmod 640 $ACLMOUNTFILE
ACLFINDPRUNE=${ACLFINDPRUNE// \'\/\// \'$mountpath/}
ACLFINDPRUNE=${ACLFINDPRUNE// \"\/\// \"$mountpath/}
#Add '$mountpath/' to beginning of each path that starts with //
# NOTE: skip links since setfacl/getfacl follow the link target anyway
# eval find $mountpath -xdev $ACLFINDPRUNE ! -type l -exec  getfacl {} /+ | gzip >| $ACLMOUNTFILE
# eval find $mountpath -xdev $ACLFINDPRUNE ! -type l -print0 | xargs -0 getfacl  | gzip >| $ACLMOUNTFILE
    #Use the following because assures newline always added
eval find $mountpath -xdev $ACLFINDPRUNE ! -type l -print0 | xargs -0 sh -c 'getfacl "$@"; echo' sh | gzip >| $ACLMOUNTFILE
else
[ -n "$LOG" ] && echo "ERROR: Can't write ACL file to: $ACLMOUNTFILE...$PASS" >> $LOG
fi
fi
if [ $ACL -eq 2 -o $ACL -eq 3 ]; then # dump via 'subinacl'
ACLMOUNTFILE=$mountpath/$ACLFILE-subinacl-${mount/%:/}.gz
if ! [ -x "`which $SUBINACL 2>/dev/null`" ] ; then
#Note only go here once...
[ $ACL -eq 2 ] && ACL=0
[ $ACL -eq 3 ] && ACL=1
[ -n "$LOG" ] && echo "ERROR: No valid executable for 'subinacl' ACL backup...$PASS" >> $LOG
elif touch $ACLMOUNTFILE 2> /dev/null ; then
chown $USER.$ADMINGRP $ACLMOUNTFILE
chmod 640 $ACLMOUNTFILE
ACLSUBINACLEXCLUDE=${ACLSUBINACLEXCLUDE//\/pathexclude=\\//pathexclude=$mount\\}
$SUBINACL /noverbose /nostatistic /subdirectories ${mount}\\\*\.\* $ACLSUBINACLEXCLUDE /display 2> /dev/null | gzip >| $ACLMOUNTFILE
else
[ -n "$LOG" ] && echo "ERROR: Can't write ACL file to: $ACLMOUNTFILE...$PASS" >> $LOG
fi
fi
if [ -n "$LOG" ] ; then
if [ "$mount" = ${SHADOWMOUNT[0]} ] ; then
echo -n "..Finished ACL backup for volumes: $mount" >> $LOG
else
echo -n " $mount" >> $LOG
fi
fi
done
    [ -n "$LOG" ] && echo " $PASS" >> $LOG
}
##############################################################################
##### MAIN CODE
##############################################################################
# Setup and parse input parameters
CYGVER=($(uname -r | sed -ne "s/\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\).*/\1 \2 \3/p"))
CYGVERTOT=$((CYGVER[0] * 1000000 + CYGVER[1] * 1000 + CYGVER[2]))
#Allow up to 3 digits for each major/minor number
parse_opts "$@"
[ -n "$LOG" ] && echo -e "\n[$(date +"%m/%d/%y %H:%M:%S")] [$PPID|$$][$USER|$USERNAME|$(id -un)|$(id -run)] $0 $* $PASS" >> $LOG #Log and timestamp each pass
# Check permissions each time through since (potentially) different user context
# i.e. make sure vshadow, dosdev and shadowexec.cmd are accessible
if [ $USESHADOWS -gt 0 ]; then
VSHADOW=$(which $VSHADOW 2>/dev/null)
DOSDEV=$(which $DOSDEV 2>/dev/null)
# SHADOWEXECCMDWIN=$(cygpath -w $( (cd -P $(dirname $0) && pwd ))/$SHADOWEXECCMD)
SHADOWEXECCMD=$(which $SHADOWEXECCMD 2>/dev/null)
SHADOWEXECCMDWIN=$(cygpath -w $SHADOWEXECCMD 2>/dev/null)
if [ -z "$VSHADOW" -o -z "$DOSDEV" -o -z "$SHADOWEXECCMD"  \
-o -z "$SHADOWEXECCMDWIN"] > /dev/null 2>&1 ; then
[ -n "$LOG" ] && echo -e "ERROR: Can't access either '$VSHADOW' or '$DOSDEV' or '$SHADOWEXECCMD'...\n" >> $LOG
if [ $PPID -eq 1 ]; then
echo -5 >| $SHADOWPID #Signal error to calling routine
exit 5
elif [ $USESHADOWS -eq 1 ]; then
exit 5# Shadows required so unrecoverable error
else
USESHADOWS=0 # Default to not using shadows
fi
fi
fi
##############################################################################
### PASS=0: Clean_up/termination (just a single pass independent of the others)
if [ $PASSNUM -eq 0 ] ; then # Terminate & clean up
[ -n "$LOG" ] && echo "***Terminating and cleaning up shadows, mounts, and locks (PID=$$)...$PASS" >> $LOG
unwind_shadows # Try first to unwind recursion gracefully
if [ $? -ne 0 ] ; then
[ -n "$LOG" ] && echo "--Manually clean up...$PASS" >> $LOG
clean_up  #Didn't clean up by unwinding recursion, so call manually
fi
[ -n "$LOG" ] && echo -e "--Termination completed...$PASS\n" >> $LOG
exit 0
##############################################################################
### PASS=1: Initial time through
elif [ $PASSNUM -eq 1 ] ; then #Launch initial recursion & wait for setup to complete
[ -n "$LOG" ] && echo "***Initial pass through (PID=$$)...$PASS" >> $LOG
get_rsyncdpidfile
#First do some tests...
is_older_than $EXPIRELOCKS
if [ $? -eq 1 ] ; then
# Proceed with strict checking if locks not expired...
if [ -e $SHADOWPID ] ; then  #Pid lock file exists
[ -n "$LOG" ] && echo -e "ERROR: Shadow pid lock file exists...$PASS\n" >> $LOG
exit 2 # Shadow pid lock file exists
elif [ -e $RSYNCDPID ] ; then #Rsync running
[ -n "$LOG" ] && echo -e "ERROR: Rsync daemon already running...$PASS\n" >> $LOG
exit 3 # Rsync daemon already running
elif [ $USESHADOWS -gt 0 ] && \
! $VSHADOW -q | grep -q "There are no shadow copies in the system" ; then
[ -n "$LOG" ] && echo -e "ERROR: Active shadow copies exist...$PASS\n" >> $LOG
exit 4 # Active shadow copies already exist
fi
fi
    # Force clean up if needed (may be redundant but good hygeine)
unwind_shadows || clean_up
#Check permissions on files we call. Also touch SHADOWPID
# Set up SHADOWDIR and check their permissions
if [ $USESHADOWS -gt 0 ] && touch $SHADOWPID && \
! ( stat -c %A $0 | grep -q "^....r.x" && \
[ $(stat -c %G $0 ) = "$ADMINGRP" ] && \
stat -c %A $SHADOWEXECCMD | grep -q "^....r.x" && \
[ $(stat -c %G $SHADOWEXECCMD) = "$ADMINGRP" ] && \
mkdir -m 775 -p $SHADOWDIR && \
chown $USER.$ADMINGRP $SHADOWDIR $SHADOWPID $LOG && \
chmod g+rw $SHADOWPID $LOG ) ; then
[ -n "$LOG" ] && echo "ERROR: Permissions error with '$0' or '$SHADOWEXECCMD' or '$SHADOWDIR' or '$SHADOWPID' or '$LOG'....$PASS" >> $LOG && echo >> $LOG
rm $SHADOWPID #Not using shadows
if [ $USESHADOWS -eq 1 ]; then #Shadows required so exit with error
exit 6 # Shadow permissions error
else
USESHADOWS=0 # Fall back to not using shadows
fi
fi
    #Write compressed ACL file to each mount as last step pre shadow/rsync launch
[ $ACL -gt 0 ] && backup_acls
if [ $USESHADOWS -gt 0 ] ; then
RELAUNCHCMD="$( (cd -P $(dirname $0) && pwd ))/${0##*/} -2 $*"
if [ "$USERNAME" == "SYSTEM" ] ; then
        #Relaunch using 'at' if you have only SYSTEM privileges (e.g. if
#come in via ssh because then you won't have privileges
#to run vshadow and dosdev
at_launch "$RELAUNCHCMD" #Recurse
RET=$?
[ -n "$LOG" ] && echo "--Relaunching as SYSTEM user via 'at' in $RET seconds...$PASS" >> $LOG
else #Just relaunch directly (for consistency with recursion above)
cmd.exe /C $(cygpath -w $(which bash.exe)) -c "$RELAUNCHCMD" &
[ -n "$LOG" ] && echo "--Relaunching via 'cmd.exe'...$PASS" >> $LOG
fi
[ -n "$LOG" ] && echo "--Initial pass going into background waiting for setup to complete...$PASS" >> $LOG
while ((TIMEOUT--)) ; do #Wait for setup completion or timeout
[ -s "$SHADOWPID" ] && break
sleep 1
done
if [ -s "$SHADOWPID" ] ; then #Check to see if returned with errors
RETURN=$((-$(< $SHADOWPID))) #Undo negative of error codes
else
[ -n "$LOG" ] && echo -e "ERROR: Shadow setup timed-out...$PASS\n" >> $LOG
RETURN=9 #Timeout error
fi
if [ $RETURN -ge 7 -a $USESHADOWS -eq 2 ] ; then
USESHADOWS=0 # Fall back to trying rsync without shadows
clean_up  #Clean up any partially set up shadows before trying rsync
fi
fi
    if [ $USESHADOWS -eq 0 ] ; then #Launch rsync without shadows
for ((WAIT=1; WAIT <=SHORTTIME; WAIT++)) ; do
        # Wait for any potential unwinding shadows to clean up
[ -e $SHADOWPID ] || break #Stop waiting when shadow pid lock deleted
sleep 1
done
[ -e $SHADOWPID  -o -e $RSYNCDPID ] && clean_up # Just in case...
$RSYNC --daemon --config=${RSYNCDCONF} ${RSYNCDADDRESS:+--address=$RSYNCDADDRESS} ${RSYNCDPORT:+--port=$RSYNCDPORT} ${RSYNCDBWLIMIT:+--bwlimit=$RSYNCDBWLIMIT} ${RSYNCDOTHER}
RETURN=$?
[ -n "$LOG" ] && echo "--Starting rsyncd daemon (WITHOUT shadow mounts) in background...$PASS" >> $LOG
[ -n "$LOG" ] && echo "..Rsyncd Params: Conf=$RSYNCDCONF Address=$RSYNCDADDRESS Port=$RSYNCDPORT BWLimit=$RSYNCDBWLIMIT Other=$RSYNCDOTHER...$PASS" >> $LOG
fi
if [ $RETURN -le 0 ] ; then  #No error
for ((WAIT=1; WAIT <=SHORTTIME; WAIT++)) ; do # Wait for rsync to set up
if [ -e "$RSYNCDPID" ]; then
[ -n "$LOG" ] && echo -e "..Rsyncd started successfully (PID=$(< $RSYNCDPID))...$PASS\n" >> $LOG
exit 0 # Exit 0 on success
fi
sleep 1
done
[ -n "$LOG" ] && echo -e "--Rsyncd failed to start...$PASS\n" >> $LOG
RETURN=10 # Rsyncd failed to start
fi
clean_up # Clean up on failure...
exit $RETURN # Return failure code
##############################################################################
### PASS=2: Called by at or cmd.exe from initial recursion
elif [ $PASSNUM -eq 2 ] ; then #Determine shadow mounts and launch vshadow
trap clean_up HUP TERM
    [ -n "$LOG" ] && echo "**Running inital shadow setup (PID=$$)...$PASS" >> $LOG
get_shadowmounts
( echo Y | $VSHADOW -da ) > /dev/null 2>&1 #Delete old shadow copies
        # This should be redundant, but just in case...
[ -n "$LOG" ] && echo "--Starting shadow copy and waiting for 'exec' script to terminate...$PASS" >> $LOG
export ARGS="$@" #Need to export to cmd.exe subshell since can't pass
$VSHADOW -exec="$SHADOWEXECCMDWIN" ${SHADOWMOUNT[@]} > /dev/null 2>&1
#NOTE: vshadow doesn't finish until $SHADOWEXECCMDWIN script completed
[ -n "$LOG" ] && echo "--Vshadow terminated: cleaning up...$PASS" >> $LOG
clean_up # Should already be mostly cleaned up by unwinding of recursion
[ -n "$LOG" ] && echo -e "[$(date +"%m/%d/%y %H:%M:%S")] Done! Clean up completed...$PASS\n" >> $LOG
exit 0
##############################################################################
### PASS=3: Called by -exec command of vshadow
elif [ $PASSNUM -eq 3 ] ; then #Mount shadows & launch rsync
[ -n "$LOG" ] && echo "**Running exec command spawned by vshadow (PID=$$)...$PASS" >> $LOG
get_shadowmounts
#Create paired array of the drive letter and the windows shadow path
SHADOWPAIRS=( `$VSHADOW -q | sed -ne "s/\( *- Original Volume name:.*\[\([A-Z]\):.*\)\| *- Shadow copy device name: */\2/p"` )
NUMSHADOWS=$((${#SHADOWPAIRS[@]}/2))
if [ $NUMSHADOWS -ne ${#SHADOWMOUNT[@]} ] ; then
[ -n "$LOG"] && echo -e "ERROR: Shadows created $NUMSHADOWS not equal to shadows requested (${#SHADOWMOUNT[@]})...$PASS\n" >> $LOG
echo -7 >| $SHADOWPID
exit 7
fi
get_freedrives $NUMSHADOWS
[ -n "$LOG" ] && echo "..Drive letters=${FREEDRIVES[@]}  $PASS" >> $LOG
if [ $NUMSHADOWS -gt ${#FREEDRIVES[@]} ] ; then
[ -n "$LOG" ] && echo -e "ERROR: Not enough free drive letters...$PASS\n" >> $LOG
echo -8 >| $SHADOWPID
exit 8
fi
cp -f $RSYNCDCONF $RSYNCDCONF_SHADOW
[ -n "$LOG" ] &&  echo "..Shadow mounts=${SHADOWMOUNT[@]}  $PASS" >> $LOG
for (( index=0 ; index < $NUMSHADOWS; index+=1 )) ; do
# Create drive letter corresponding to shadow mount
$DOSDEV "${FREEDRIVES[$index]}:" "${SHADOWPAIRS[2*$index+1]}"
# Mount drive letter
mount -f "${FREEDRIVES[$index]}:" $SHADOWDIR/${FREEDRIVES[$index]}
[ -n "$LOG" ] &&  echo "    ${FREEDRIVES[$index]}:->${SHADOWPAIRS[2*$index]}:  ${SHADOWPAIRS[2*$index+1]}" >> $LOG
[ -n "$LOG" ] && (echo -en "        " ; mount | grep "^${FREEDRIVES[$index]}:") >> $LOG
#Rewrite rsyncd.conf substituting shadow paths where appropriate
sed -i -e "s%^\([ \t]*path[ \t]*=[ \t]*\)\($CYGDRIVEPREFIX\)\?/${SHADOWPAIRS[2*$index]}\([ \t]*$\|[ \t]*#\|/\)%\1$SHADOWDIR/${FREEDRIVES[$index]}\3%i" $RSYNCDCONF_SHADOW
done
kill_rsyncd #Should already be dead but kill again just in case...
[ -n "$LOG" ] && echo "--Starting rsyncd daemon (with shadow mounts) and waiting for file transfer to complete...$PASS" >> $LOG
[ -n "$LOG" ] && echo "..Rsyncd Params: Conf=$RSYNCDCONF Address=$RSYNCDADDRESS Port=$RSYNCDPORT BWLimit=$RSYNCDBWLIMIT Other=$RSYNCDOTHER...$PASS" >> $LOG
echo $$ >| $SHADOWPID #Put shell PID in lockfile & signal successful setup
$RSYNC --daemon --no-detach --config=${RSYNCDCONF_SHADOW} ${RSYNCDADDRESS:+--address=$RSYNCDADDRESS} ${RSYNCDPORT:+--port=$RSYNCDPORT} ${RSYNCDBWLIMIT:+--bwlimit=$RSYNCDBWLIMIT} ${RSYNCDOTHER}
RET=$?
#Rsync runs until shell or rsync killed (note we typically kill the shell)
[ -n "$LOG" ] && echo "--Rsync terminated($RET): exiting & returning control to PASS=2...$PASS" >> $LOG
exit $RET  #Returns exit of rsync
fi
##############################################################################
exit 11 #Shouldn't get here...
</pre>
* Sistemare le permission
chgrp Administrators /usr/local/bin/*
chmod 755 /usr/local/bin/*
* Make sure to replace with the correct values for your setup:
**host allow
**auth users


* Create a file /etc/rsyncd.conf on your client:
* Create a file /etc/rsyncd.conf on your client:
Line 1,028: Line 96:
</pre>
</pre>


* Create a file on your client:
* Make sure to replace with the correct values for your setup:
 
host allow
  vi /etc/rsyncd.secret
  auth users


Administrator:mysecretpass
* Creare il file
vi /etc/rsyncd.secret


Administrator:PASSWORD


==Configurazione Server==
==Configurazione Server BackupPc==


* Copiare la chiave di backuppc sul client
* Copiare la chiave di backuppc sul client
Line 1,042: Line 112:
* Verificare se si accede:
* Verificare se si accede:
  sudo -u backuppc ssh Administrator@myclient
  sudo -u backuppc ssh Administrator@myclient
===File di configurazione per backup Pc Desktop===


* Creare il file di configurazione del client:
* Creare il file di configurazione del client:
Line 1,183: Line 255:
</pre>
</pre>


===File di Configurazione per backup Pc Server===
* Creare il file di configurazione del server. In questo caso lo script a termine lavoro disattiva la vss e richiama poi lo script di notifica:
sudoedit /etc/backuppc/myclient.pl
<pre>
#
# Rsync over ssh Backup
#
$Conf{BackupsDisable} = 1;
# Minimum period in days between full and incremental backups:
# 1 Full alla settimana
$Conf{FullPeriod} = 6.97;
# almeno un incr al giorno
$Conf{IncrPeriod} = 0.49;
# Number of full and incremental backups to keep:
$Conf{FullKeepCnt} = 12;
$Conf{IncrKeepCnt} = 63;
# Note that additional fulls will be kept for as long as is necessary
# to support remaining incrementals.
# What transport to use backup the client [smb|rsync|rsyncd|tar|archive]:
$Conf{XferMethod} = 'rsync';
# The file system path or the name of the rsyncd module to backup when
# using rsync/rsyncd:
$Conf{RsyncShareName} = [
        '/cygdrive/c/shadow/c/cygwin/bin',
        '/cygdrive/c/shadow/d/tmp',
];
# If this is defined only these files/paths will be included in the backup:
#$Conf{BackupFilesOnly} = undef;
# These files/paths will be excluded from the backup:
$Conf{BackupFilesExclude} = {
  #Windows 7/Vista specific!
  '*' => [
        #7/Vista junction points
        '/Documents and Settings',
        '/ProgramData/Application Data',
        '/ProgramData/Desktop',
        '/ProgramData/Documents',
        '/ProgramData/Favorites',
        '/ProgramData/Start Menu',
        '/ProgramData/Templates',
        '/Users/All Users',
        '/Users/Users/Default User',
        '/Users/Users/All Users/Application Data',
        '/Users/Users/All Users/Desktop',
        '/Users/All Users/Documents',
        '/Users/All Users/Favorites',
        '/Users/All Users/Start Menu',
        '/Users/All Users/Templates',
        #Junction points common to every user profile
        '/Users/*/Application Data',
        '/Users/*/Cookies',
        '/Users/*/Local Settings',
        '/Users/*/My Documents',
        '/Users/*/NetHood',
        '/Users/*/PrintHood',
        '/Users/*/Recent',
        '/Users/*/SendTo',
        '/Users/*/Start Menu',
        '/Users/*/Templates',
        '/Users/*/AppData/Local/Application Data',
        '/Users/*/AppData/Local/History',
        '/Users/*/AppData/Local/Temporary Internet Files',
        '/Users/*/Documents/My Music',
        '/Users/*/Documents/My Pictures',
        '/Users/*/Documents/My Videos',
        #Temporary and in-use user data
        #'/Users/*/AppData/Local/Microsoft/Windows/Temporary Internet Files',
        #'/Users/*/AppData/Local/Temp',
        #'/Users/*/NTUSER.DAT*',
        #'/Users/*/ntuser.dat*',
        #'/Users/*/AppData/Local/Microsoft/Windows/UsrClass.dat*',
        #'/Users/*/AppData/Local/Microsoft/Windows Defender/FileTracker',
        #'/Users/*/AppData/Local/Microsoft/Windows/Explorer/thumbcache_*.db',
        #'/Users/*/AppData/Local/Microsoft/Windows/WER',
        #'/Users/*/AppData/Local/Mozilla/Firefox/Profiles/*/Cache',
        #'/Users/*/AppData/Local/Mozilla/Firefox/Profiles/*/OfflineCache',
        #'/Users/*/AppData/Roaming/Microsoft/Windows/Cookies',
        #'/Users/*/AppData/Roaming/Microsoft/Windows/Recent',
        #'ProgramData/Microsoft/Search',
        #'ProgramData/Microsoft/Windows Defender',
        #'*.lock',
        #'Thumbs.db',
        #'IconCache.db',
        #'Cache*',
        #'cache*',
        #Installation folders and system data
        #'/Program Files',
        #'/Windows',
        #'/$Recycle.Bin',
        #'/MSOCache',
        #'/System Volume Information',
        #'/Boot',
        #'/autoexec.bat',
        #'/bootmgr',
        #'/BOOTSECT.BAK',
        #'/config.sys',
        'c/hiberfil.sys',
        'c/pagefile.sys',
        'd/hiberfil.sys',
        'd/pagefile.sys',
        'e/hiberfil.sys',
        'e/pagefile.sys',
  ]
};
# Level of verbosity in Xfer log files:
$Conf{XferLogLevel} = 1;
# Commands to run for client backups:
# Note the use of SSH's -C attribute. This enables compression in SSH.
#$Conf{RsyncClientCmd} = '$sshPath -C -x -l administrator -o PreferredAuthentications=publickey $host $rsyncPath $argList+';
# Commands to run for client direct restores:
# Note the use of SSH's -C attribute. This enables compression in SSH.
#$Conf{RsyncClientRestoreCmd} = '$sshPath -C -q -x -l administrator $host $rsyncPath $argList+';
# Compression level to use on files. 0 means no compression. See notes
# in main config file before changing after backups have already been done.
$Conf{CompressLevel} = 9;
# The backup may occur over vpn. Avoid "ping too slow" errors.
$Conf{PingMaxMsec} = 150;
# Timeout if backing up large files ?
$Conf{ClientTimeout} = 3600*8;      # 6 Hours!!
$Conf{RsyncClientCmd} = '$sshPath -q -x -l Administrator $host $rsyncPath $argList+';
$Conf{RsyncClientRestoreCmd} = '$sshPath -q -x -l Administrator $host $rsyncPath $argList+';
$Conf{DumpPreUserCmd} =  '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/pre-backup.sh';
$Conf{DumpPostUserCmd} = '/usr/local/bin/BackupPC_DumpPostUserCmd.vss $type $xferOK $client $host $hostIP $user $moreUsers $XferMethod $sshPath $cmdType';
#$Conf{DumpPreUserCmd} =  '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/shadowmountrsync -u 1 -A 1';
#$Conf{DumpPostUserCmd} = '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/shadowmountrsync -d';
</pre>
===Configurazione del Job di backup===
* Sistemare le permission del file di configurazione:
sudo chown backuppc:www-data /etc/backuppc/myclient.pl
* Creare lo script post job:
sudoedit /usr/local/bin/BackupPC_DumpPostUserCmd.vss
<pre>
#!/bin/bash
# 2013022801
# Script server per lanciare post-backup
#
#
set -x
type="$1"
xferOK="$2"
client="$3"
host="$4"
hostIP="$5"
user="$6"
moreUsers="$7"
share="$8"
shares="$9"
XferMethod="${10}"
sshPath="${11}"
cmdType="${12}"
cat <<EOFile
Parameters are:
type=$1
xferOK=$2
client=$3
host=$4
hostIP=$5
user=$6
moreUsers=$7
share=$8
shares=$9
XferMethod=${10}
sshPath=${11}
cmdType=${12}
sshUser=${13}
EOFile
if [ -n $sshUser ]
then
sshUser="Administrator"
fi
$sshPath -q -x -l $sshUser $hostIP /usr/local/bin/post-backup.sh
/usr/local/bin/BackupPC_DumpPostUserCmd $@
</pre>
* Renderlo eseguibile:
  sudo chmod +x /usr/local/bin/BackupPC_DumpPostUserCmd.vss
* Assicurarsi che ci sia lo script di notifica esito backup:
sudoedit /usr/local/bin/BackupPC_DumpPostUserCmd
<pre>
#!/bin/bash
# 2013022801
# /usr/local/bin/BackupPC_DumpPostUserCmd
# Script di notifica esito backup
#
set -x
type="$1"
xferOK="$2"
client="$3"
host="$4"
hostIP="$5"
user="$6"
moreUsers="$7"
XferMethod="$8"
sshPath="$9"
cmdType=${10}
user="${11}"
$sshPath -q -x -l root $hostIP /usr/local/bin/post-backup.sh
if [ $xferOK -eq 1 ]
then
        SUBJECT="Backup Succesful of $client"
        MSG=$(cat <<EOFile
The backup of $client was succesfull.
Parameters are:
type=$1
xferOK=$2
client=$3
host=$4
hostIP=$5
user=$6
moreUsers=$7
share=$8
shares=$9
XferMethod=${10}
sshPath=${11}
cmdType=${12}
EOFile
)
else
        SUBJECT="Backup UNSUCCESSFUL of $client"
        MSG=$(cat <<EOFile
The backup of $client was UNSUCCESFUL.
Parameters are:
type=$1
xferOK=$2
client=$3
host=$4
hostIP=$5
user=$6
moreUsers=$7
share=$8
shares=$9
XferMethod=${10}
sshPath=${11}
cmdType=${12}
EOFile
)
fi
echo -e $MSG
echo -e $MSG | mail -s "${SUBJECT}" $moreUsers
</pre>
* Renderlo eseguibile:
sudo chmod +x /usr/local/bin/BackupPC_DumpPostUserCmd
* Inserire l'host nella configurazione di backuppc:
sudoedit /etc/backuppc/hosts
myclient  0      backuppc, email@example.com
* Riavviare backuppc:
sudo invoke-rc.d backuppc restart
* Testare il backup
sudo -u backuppc /usr/share/backuppc/bin/BackupPC_dump -v -f myclient
===Schedulazione del Backup===
* Verificare che backuppc poss ainviare correttamente email:
sudo -u backuppc /usr/share/backuppc/bin/BackupPC_sendEmail -u recipient@example.com
* Creare il file crontab, che
:# Testa se backuppc è attivo
:# Fa un backup incrementale da Lun a Ven alle 23:00
:# Fa un backup completo il Sabato alle 23:00
sudoedit /etc/cron.d/backuppc
<pre>
#
# Regular cron jobs for backuppc
#
#min    hours  DayOfMonth      Month  DayOfWeek user    command
# Check if backuppc is running. If not, send a warning email
00      *      *              *      *          backuppc /usr/share/backuppc/bin/BackupPC_sendEmail -c > /dev/null
# Incr backup mon-fri
00      23      *              *      1-5        backuppc /usr/local/sbin/BackupPcBackup 0 > /dev/null
# Full backup sat
00      23      *              *      6          backuppc /usr/local/sbin/BackupPcBackup 1 > /dev/null
</pre>
* Creare lo script per l'esecuzione dei backup
sudoedit /usr/local/sbin/BackupPcBackup
<pre>
#!/bin/bash
TYPE=$1
# TYPE=0 Incremental
# TYPE=1 Full
/usr/share/backuppc/bin/BackupPC_serverMesg backup myclientip  myclientname  backuppc $TYPE
#/usr/share/backuppc/bin/BackupPC_serverMesg backup 5.6.7.8  myclient2  backuppc $TYPE
</pre>
* Rendere eseguibile:
sudo chmod +x /usr/local/sbin/BackupPcBackup
* Testare il submit del job manualmente:
sudo -u backuppc /usr/share/backuppc/bin/BackupPC_serverMesg backup myclientip  myclientname  backuppc 1
* Testare il submit del job del backup completo:
sudo -u backuppc /usr/local/sbin/BackupPcBackup 1
==Riferimenti==
==Riferimenti==
*[http://majentis.com/2011/01/03/backuppc-with-sshrsyncvss-on-windows-server/comment-page-1/#comment-1036 BackupPC with ssh/rsync/VSS on Windows Server « majentis technologies]
*[http://users.softlab.ntua.gr/~ttsiod/win32backup.html Optimal backups for Windows machines]
*[http://edgylogic.com/blog/vshadow-exe-versions/ vshadow.exe versions // blog.edgylogic]


*Ufficiale sito backuppc:
*Ufficiale sito backuppc:
Line 1,190: Line 606:
* Client backuppcd (sembra non mantenuto):
* Client backuppcd (sembra non mantenuto):
**[http://www.rkeene.org/oss/backuppcd/ Keene Enterprises :: Open Source :: BackupPCd]
**[http://www.rkeene.org/oss/backuppcd/ Keene Enterprises :: Open Source :: BackupPCd]


*[http://www.cs.umd.edu/~cdunne/projs/backuppc_guide.html#Separate%20Hard%20Drive%20for%20the%20Pool%20(Optional)%20TOC BackupPC Install Guide for Windows 7/Vista/XP Clients & Ubuntu Server]
*[http://www.cs.umd.edu/~cdunne/projs/backuppc_guide.html#Separate%20Hard%20Drive%20for%20the%20Pool%20(Optional)%20TOC BackupPC Install Guide for Windows 7/Vista/XP Clients & Ubuntu Server]
Line 1,200: Line 615:
*[http://www.backupcentral.com/phpBB2/two-way-mirrors-of-external-mailing-lists-3/backuppc-21/fwd-complete-cygwin-vss-rsync-solution-for-windows-backup-106193/ Backup Central Forums :: View topic - Fwd: Complete cygwin/VSS/rsync solution for Windows Backup]
*[http://www.backupcentral.com/phpBB2/two-way-mirrors-of-external-mailing-lists-3/backuppc-21/fwd-complete-cygwin-vss-rsync-solution-for-windows-backup-106193/ Backup Central Forums :: View topic - Fwd: Complete cygwin/VSS/rsync solution for Windows Backup]
*[http://www.goodjobsucking.com/?p=62 Backing Up Open Files on Windows with Rsync (and BackupPC) | Good Job Sucking]
*[http://www.goodjobsucking.com/?p=62 Backing Up Open Files on Windows with Rsync (and BackupPC) | Good Job Sucking]
*[http://www.microsoft.com/download/en/details.aspx?id=23510 Download: SubInACL (SubInACL.exe) - Microsoft Download Center - Download Details]

Latest revision as of 17:29, 21 July 2014

Configurazione Client da backuppare

  • Installare cygwin con
binutils
openssh
rsync
screen
unzip
util-linux
vim
wget
zip
  • Impostare Environment Variables
Right click My Computer, Properties, Advanced, Environment Variables, System Variables
    • Aggiungere:
CYGWIN = ntsec
    • Modificare il PATH aggiungendo
;c:\cygwin\bin
  • Make sure every Windows user has a password set (System Preference / User Accounts) and Make sure every Windows user has done the following at least once (this will create home directories for every user):
  • Configurare ssh come Administrator, aprendo un cygwin terminal in locale:
ssh-host-config --yes --cygwin ntsec


  • Se lo si fa invece manualmente, rispondere si a tutte le domande, e settare quando richiesto
CYGWIN = ntsec
    • If you get an error message (Windows XP)
>> ERROR: Problem with /var directory. Exiting.
>> Change permissions:
chmod 775 /var
  • Se non ci si riesce a loggare, e l'utente Windows usato per il servizio è di dominio, bisogna aggiungergli la policy locale di Create token object:
gpedit.msc
local computer policy\computer configuration\windows settings\security settings\local policies\user rights assignment
look for 'create a token object'
add DOMAINNAME\cyg_server user
  • Start ssh with:
net start sshd
  • Synchronize User-Accounts with Cygwin. Login as Administrator, start a Cygwin Shell:
mkpasswd -cl > /etc/passwd
mkgroup --local > /etc/group
  • Creare le directory di ssh (a volte è necessario forzare lo username con la "A" maiuscola):
ssh Administrator@localhost
  • Disabilitare il firewall

Client scripts

  • Installare i programmi:
cd
wget -O backuppc-shadow.zip http://support.rvmgroup.it/download/backuppc-shadow.zip
cd /usr/local/bin
unzip -ox ~/backuppc-shadow.zip && rm -f ~/backuppc-shadow.zip 
cp vshadow-CYGWIN_NT-5.2.exe vshadow-CYGWIN_NT-5.2-WOW64.exe
  • Sistemare le permission
chgrp Administrators /usr/local/bin/*
chmod 755 /usr/local/bin/*
  • Modificare i DISCHI da shadoware:
vi /usr/local/bin/pre-backup.sh
  • Creare il file di configurazione:
vi /etc/backuppc-shadow
DRIVES="c d e"
ACL=true   
SHADOW=true
  • Create a file /etc/rsyncd.conf on your client:
vi /etc/rsyncd.conf
gid = users
read only = true
use chroot = false
transfer logging = false
log file = /var/log/rsyncd.log
log format = %h %o %f %l %b
hosts allow = 192.168.0.0/16
hosts deny = 0.0.0.0/0
strict modes = false
[root]
path = /cygdrive/
auth users = Administrator
secrets file = /etc/rsyncd.secret
  • Make sure to replace with the correct values for your setup:
host allow
auth users 
  • Creare il file
vi /etc/rsyncd.secret
Administrator:PASSWORD

Configurazione Server BackupPc

  • Copiare la chiave di backuppc sul client
sudo -u backuppc ssh-copy-id Administrator@myclient
  • Verificare se si accede:
sudo -u backuppc ssh Administrator@myclient

File di configurazione per backup Pc Desktop

  • Creare il file di configurazione del client:
sudoedit /etc/backuppc/myclient.pl
#
# Rsync over ssh Backup
#
$Conf{BackupsDisable} = 0;
$Conf{WakeupSchedule} = [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
# Minimum period in days between full and incremental backups:
# 1 Full alla settimana
$Conf{FullPeriod} = 6.97;
# almeno un incr al giorno
$Conf{IncrPeriod} = 0.49;

# Number of full and incremental backups to keep:
$Conf{FullKeepCnt} = 12;
$Conf{IncrKeepCnt} = 63;
# Note that additional fulls will be kept for as long as is necessary
# to support remaining incrementals.

# What transport to use backup the client [smb|rsync|rsyncd|tar|archive]:
$Conf{XferMethod} = 'rsync';

# The file system path or the name of the rsyncd module to backup when
# using rsync/rsyncd:
$Conf{RsyncShareName} = [ 
        '/cygdrive/c',
        '/cygdrive/d',
];

# If this is defined only these files/paths will be included in the backup:
#$Conf{BackupFilesOnly} = undef;

# These files/paths will be excluded from the backup:
$Conf{BackupFilesExclude} = {
  #Windows 7/Vista specific!
  '*' => [
        #7/Vista junction points
        '/Documents and Settings',
        '/ProgramData/Application Data',
        '/ProgramData/Desktop',
        '/ProgramData/Documents',
        '/ProgramData/Favorites',
        '/ProgramData/Start Menu',
        '/ProgramData/Templates',
        '/Users/All Users',
        '/Users/Users/Default User',
        '/Users/Users/All Users/Application Data',
        '/Users/Users/All Users/Desktop',
        '/Users/All Users/Documents',
        '/Users/All Users/Favorites',
        '/Users/All Users/Start Menu',
        '/Users/All Users/Templates',

        #Junction points common to every user profile
        '/Users/*/Application Data',
        '/Users/*/Cookies',
        '/Users/*/Local Settings',
        '/Users/*/My Documents',
        '/Users/*/NetHood',
        '/Users/*/PrintHood',
        '/Users/*/Recent',
        '/Users/*/SendTo',
        '/Users/*/Start Menu',
        '/Users/*/Templates',
        '/Users/*/AppData/Local/Application Data',
        '/Users/*/AppData/Local/History',
        '/Users/*/AppData/Local/Temporary Internet Files',
        '/Users/*/Documents/My Music',
        '/Users/*/Documents/My Pictures',
        '/Users/*/Documents/My Videos',

        #Temporary and in-use user data
        '/Users/*/AppData/Local/Microsoft/Windows/Temporary Internet Files',
        '/Users/*/AppData/Local/Temp',
        '/Users/*/NTUSER.DAT*',
        '/Users/*/ntuser.dat*',
        '/Users/*/AppData/Local/Microsoft/Windows/UsrClass.dat*',
        '/Users/*/AppData/Local/Microsoft/Windows Defender/FileTracker',
        '/Users/*/AppData/Local/Microsoft/Windows/Explorer/thumbcache_*.db',
        '/Users/*/AppData/Local/Microsoft/Windows/WER',
        '/Users/*/AppData/Local/Mozilla/Firefox/Profiles/*/Cache',
        '/Users/*/AppData/Local/Mozilla/Firefox/Profiles/*/OfflineCache',
        '/Users/*/AppData/Roaming/Microsoft/Windows/Cookies',
        '/Users/*/AppData/Roaming/Microsoft/Windows/Recent',
        'ProgramData/Microsoft/Search',
        'ProgramData/Microsoft/Windows Defender',
        '*.lock',
        'Thumbs.db',
        'IconCache.db',
        'Cache*',
        'cache*',

        #Installation folders and system data
        '/Program Files',
        '/Windows',
        '/$Recycle.Bin',
        '/MSOCache',
        '/System Volume Information',
        '/Boot',
        '/autoexec.bat',
        '/bootmgr',
        '/BOOTSECT.BAK',
        '/config.sys',
        '/hiberfil.sys',
        '/pagefile.sys'
  ]
};

# Level of verbosity in Xfer log files:
$Conf{XferLogLevel} = 1;

# Commands to run for client backups:
# Note the use of SSH's -C attribute. This enables compression in SSH.
#$Conf{RsyncClientCmd} = '$sshPath -C -x -l administrator -o PreferredAuthentications=publickey $host $rsyncPath $argList+';

# Commands to run for client direct restores:
# Note the use of SSH's -C attribute. This enables compression in SSH.
#$Conf{RsyncClientRestoreCmd} = '$sshPath -C -q -x -l administrator $host $rsyncPath $argList+';

# Compression level to use on files. 0 means no compression. See notes
# in main config file before changing after backups have already been done.
$Conf{CompressLevel} = 9;

# The backup may occur over vpn. Avoid "ping too slow" errors.
$Conf{PingMaxMsec} = 150;

# Timeout if backing up large files ?
$Conf{ClientTimeout} = 3600*8;      # 6 Hours!!

$Conf{RsyncClientCmd} = '$sshPath -q -x -l Administrator $host $rsyncPath $argList+';
$Conf{RsyncClientRestoreCmd} = '$sshPath -q -x -l Administrator $host $rsyncPath $argList+';


$Conf{DumpPreUserCmd} =  '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/shadowmountrsync -u 1 -A 1';
$Conf{DumpPostUserCmd} = '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/shadowmountrsync -d';

File di Configurazione per backup Pc Server

  • Creare il file di configurazione del server. In questo caso lo script a termine lavoro disattiva la vss e richiama poi lo script di notifica:
sudoedit /etc/backuppc/myclient.pl
#
# Rsync over ssh Backup
#
$Conf{BackupsDisable} = 1;
# Minimum period in days between full and incremental backups:
# 1 Full alla settimana
$Conf{FullPeriod} = 6.97;
# almeno un incr al giorno
$Conf{IncrPeriod} = 0.49;

# Number of full and incremental backups to keep:
$Conf{FullKeepCnt} = 12;
$Conf{IncrKeepCnt} = 63;
# Note that additional fulls will be kept for as long as is necessary
# to support remaining incrementals.

# What transport to use backup the client [smb|rsync|rsyncd|tar|archive]:
$Conf{XferMethod} = 'rsync';

# The file system path or the name of the rsyncd module to backup when
# using rsync/rsyncd:
$Conf{RsyncShareName} = [ 
        '/cygdrive/c/shadow/c/cygwin/bin',
        '/cygdrive/c/shadow/d/tmp',
];

# If this is defined only these files/paths will be included in the backup:
#$Conf{BackupFilesOnly} = undef;

# These files/paths will be excluded from the backup:
$Conf{BackupFilesExclude} = {
  #Windows 7/Vista specific!
  '*' => [
        #7/Vista junction points
        '/Documents and Settings',
        '/ProgramData/Application Data',
        '/ProgramData/Desktop',
        '/ProgramData/Documents',
        '/ProgramData/Favorites',
        '/ProgramData/Start Menu',
        '/ProgramData/Templates',
        '/Users/All Users',
        '/Users/Users/Default User',
        '/Users/Users/All Users/Application Data',
        '/Users/Users/All Users/Desktop',
        '/Users/All Users/Documents',
        '/Users/All Users/Favorites',
        '/Users/All Users/Start Menu',
        '/Users/All Users/Templates',

        #Junction points common to every user profile
        '/Users/*/Application Data',
        '/Users/*/Cookies',
        '/Users/*/Local Settings',
        '/Users/*/My Documents',
        '/Users/*/NetHood',
        '/Users/*/PrintHood',
        '/Users/*/Recent',
        '/Users/*/SendTo',
        '/Users/*/Start Menu',
        '/Users/*/Templates',
        '/Users/*/AppData/Local/Application Data',
        '/Users/*/AppData/Local/History',
        '/Users/*/AppData/Local/Temporary Internet Files',
        '/Users/*/Documents/My Music',
        '/Users/*/Documents/My Pictures',
        '/Users/*/Documents/My Videos',

        #Temporary and in-use user data
        #'/Users/*/AppData/Local/Microsoft/Windows/Temporary Internet Files',
        #'/Users/*/AppData/Local/Temp',
        #'/Users/*/NTUSER.DAT*',
        #'/Users/*/ntuser.dat*',
        #'/Users/*/AppData/Local/Microsoft/Windows/UsrClass.dat*',
        #'/Users/*/AppData/Local/Microsoft/Windows Defender/FileTracker',
        #'/Users/*/AppData/Local/Microsoft/Windows/Explorer/thumbcache_*.db',
        #'/Users/*/AppData/Local/Microsoft/Windows/WER',
        #'/Users/*/AppData/Local/Mozilla/Firefox/Profiles/*/Cache',
        #'/Users/*/AppData/Local/Mozilla/Firefox/Profiles/*/OfflineCache',
        #'/Users/*/AppData/Roaming/Microsoft/Windows/Cookies',
        #'/Users/*/AppData/Roaming/Microsoft/Windows/Recent',
        #'ProgramData/Microsoft/Search',
        #'ProgramData/Microsoft/Windows Defender',
        #'*.lock',
        #'Thumbs.db',
        #'IconCache.db',
        #'Cache*',
        #'cache*',

        #Installation folders and system data
        #'/Program Files',
        #'/Windows',
        #'/$Recycle.Bin',
        #'/MSOCache',
        #'/System Volume Information',
        #'/Boot',
        #'/autoexec.bat',
        #'/bootmgr',
        #'/BOOTSECT.BAK',
        #'/config.sys',
        'c/hiberfil.sys',
        'c/pagefile.sys',
        'd/hiberfil.sys',
        'd/pagefile.sys',
        'e/hiberfil.sys',
        'e/pagefile.sys',
  ]
};

# Level of verbosity in Xfer log files:
$Conf{XferLogLevel} = 1;

# Commands to run for client backups:
# Note the use of SSH's -C attribute. This enables compression in SSH.
#$Conf{RsyncClientCmd} = '$sshPath -C -x -l administrator -o PreferredAuthentications=publickey $host $rsyncPath $argList+';

# Commands to run for client direct restores:
# Note the use of SSH's -C attribute. This enables compression in SSH.
#$Conf{RsyncClientRestoreCmd} = '$sshPath -C -q -x -l administrator $host $rsyncPath $argList+';

# Compression level to use on files. 0 means no compression. See notes
# in main config file before changing after backups have already been done.
$Conf{CompressLevel} = 9;

# The backup may occur over vpn. Avoid "ping too slow" errors.
$Conf{PingMaxMsec} = 150;

# Timeout if backing up large files ?
$Conf{ClientTimeout} = 3600*8;      # 6 Hours!!

$Conf{RsyncClientCmd} = '$sshPath -q -x -l Administrator $host $rsyncPath $argList+';
$Conf{RsyncClientRestoreCmd} = '$sshPath -q -x -l Administrator $host $rsyncPath $argList+';

$Conf{DumpPreUserCmd} =  '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/pre-backup.sh';
$Conf{DumpPostUserCmd} = '/usr/local/bin/BackupPC_DumpPostUserCmd.vss $type $xferOK $client $host $hostIP $user $moreUsers $XferMethod $sshPath $cmdType';

#$Conf{DumpPreUserCmd} =  '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/shadowmountrsync -u 1 -A 1';
#$Conf{DumpPostUserCmd} = '$sshPath -q -x -l Administrator $hostIP /usr/local/bin/shadowmountrsync -d';

Configurazione del Job di backup

  • Sistemare le permission del file di configurazione:
sudo chown backuppc:www-data /etc/backuppc/myclient.pl
  • Creare lo script post job:
sudoedit /usr/local/bin/BackupPC_DumpPostUserCmd.vss
#!/bin/bash
# 2013022801
# Script server per lanciare post-backup
#
#
set -x

type="$1"
xferOK="$2"
client="$3"
host="$4"
hostIP="$5"
user="$6"
moreUsers="$7"
share="$8"
shares="$9"
XferMethod="${10}"
sshPath="${11}"
cmdType="${12}"

cat <<EOFile
Parameters are:
type=$1
xferOK=$2
client=$3
host=$4
hostIP=$5
user=$6
moreUsers=$7
share=$8
shares=$9
XferMethod=${10}
sshPath=${11}
cmdType=${12}
sshUser=${13}
EOFile

if [ -n $sshUser ]
then
	sshUser="Administrator"
fi

$sshPath -q -x -l $sshUser $hostIP /usr/local/bin/post-backup.sh

/usr/local/bin/BackupPC_DumpPostUserCmd $@
  • Renderlo eseguibile:
 sudo chmod +x /usr/local/bin/BackupPC_DumpPostUserCmd.vss
  • Assicurarsi che ci sia lo script di notifica esito backup:
sudoedit /usr/local/bin/BackupPC_DumpPostUserCmd
#!/bin/bash
# 2013022801
# /usr/local/bin/BackupPC_DumpPostUserCmd
# Script di notifica esito backup
#
set -x

type="$1"
xferOK="$2"
client="$3"
host="$4"
hostIP="$5"
user="$6"
moreUsers="$7"
XferMethod="$8"
sshPath="$9"
cmdType=${10}
user="${11}"

$sshPath -q -x -l root $hostIP /usr/local/bin/post-backup.sh

if [ $xferOK -eq 1 ]
then
        SUBJECT="Backup Succesful of $client"
        MSG=$(cat <<EOFile
The backup of $client was succesfull.

Parameters are:
type=$1
xferOK=$2
client=$3
host=$4
hostIP=$5
user=$6
moreUsers=$7
share=$8
shares=$9
XferMethod=${10}
sshPath=${11}
cmdType=${12}
EOFile
)

else
        SUBJECT="Backup UNSUCCESSFUL of $client"
        MSG=$(cat <<EOFile
The backup of $client was UNSUCCESFUL.

Parameters are:
type=$1
xferOK=$2
client=$3
host=$4
hostIP=$5
user=$6
moreUsers=$7
share=$8
shares=$9
XferMethod=${10}
sshPath=${11}
cmdType=${12}
EOFile
)
fi

echo -e $MSG
echo -e $MSG | mail -s "${SUBJECT}" $moreUsers
  • Renderlo eseguibile:
sudo chmod +x /usr/local/bin/BackupPC_DumpPostUserCmd
  • Inserire l'host nella configurazione di backuppc:
sudoedit /etc/backuppc/hosts 
myclient  0       backuppc, email@example.com
  • Riavviare backuppc:
sudo invoke-rc.d backuppc restart
  • Testare il backup
sudo -u backuppc /usr/share/backuppc/bin/BackupPC_dump -v -f myclient

Schedulazione del Backup

  • Verificare che backuppc poss ainviare correttamente email:
sudo -u backuppc /usr/share/backuppc/bin/BackupPC_sendEmail -u recipient@example.com
  • Creare il file crontab, che
  1. Testa se backuppc è attivo
  2. Fa un backup incrementale da Lun a Ven alle 23:00
  3. Fa un backup completo il Sabato alle 23:00
sudoedit /etc/cron.d/backuppc 
#
# Regular cron jobs for backuppc
#
#min    hours   DayOfMonth      Month   DayOfWeek user     command
# Check if backuppc is running. If not, send a warning email
00      *       *               *      *          backuppc /usr/share/backuppc/bin/BackupPC_sendEmail -c > /dev/null
# Incr backup mon-fri
00      23      *               *      1-5        backuppc /usr/local/sbin/BackupPcBackup 0 > /dev/null
# Full backup sat
00      23      *               *      6          backuppc /usr/local/sbin/BackupPcBackup 1 > /dev/null
  • Creare lo script per l'esecuzione dei backup
sudoedit /usr/local/sbin/BackupPcBackup 
#!/bin/bash
TYPE=$1
# TYPE=0 Incremental
# TYPE=1 Full
/usr/share/backuppc/bin/BackupPC_serverMesg backup myclientip  myclientname  backuppc $TYPE
#/usr/share/backuppc/bin/BackupPC_serverMesg backup 5.6.7.8  myclient2   backuppc $TYPE
  • Rendere eseguibile:
sudo chmod +x /usr/local/sbin/BackupPcBackup 
  • Testare il submit del job manualmente:
sudo -u backuppc /usr/share/backuppc/bin/BackupPC_serverMesg backup myclientip  myclientname  backuppc 1
  • Testare il submit del job del backup completo:
sudo -u backuppc /usr/local/sbin/BackupPcBackup 1

Riferimenti