|
|
| (30 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/* |
| | chmod 755 /usr/local/bin/* |
|
| |
|
| * Scaricare [dosdev.zip http://www.ltr-data.se/files/dosdev.zip] | | * Modificare i DISCHI da shadoware: |
| | vi /usr/local/bin/pre-backup.sh |
|
| |
|
| * Copiare in
| | * Creare il file di configurazione: |
| /usr/local/bin
| | vi /etc/backuppc-shadow |
| :i files
| |
| vshadow.exe
| |
| dosdev.exe
| |
| | |
| * Creare lo script: | |
| | |
| vi /usr/local/bin/shadowmountrsync | |
|
| |
|
| <pre> | | <pre> |
| #!/bin/bash
| | DRIVES="c d e" |
| | | ACL=true |
| # Shadowmountrsync
| | SHADOW=true |
| # 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> | | </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,015: |
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,029: |
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,170: |
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,177: |
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,187: |
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] |
Configurazione Client da backuppare
binutils
openssh
rsync
screen
unzip
util-linux
vim
wget
zip
- Impostare Environment Variables
- Right click My Computer, Properties, Advanced, Environment Variables, System Variables
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
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
Client scripts
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
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
vi /etc/rsyncd.secret
Administrator:PASSWORD
Configurazione Server BackupPc
- Copiare la chiave di backuppc sul client
sudo -u backuppc ssh-copy-id Administrator@myclient
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 $@
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
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
sudo invoke-rc.d backuppc restart
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
#
# 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
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
- Client backuppcd (sembra non mantenuto):