Chronicle - Snapshot Backup Tool
Chronicle is set of BASH shell scripts that use Rsync to back up data to a
remote host. Rsync can be used in either daemon mode or with SSH transport.
A number of snapshots are rotated and copies can be made by creating hard
links to minimize disk usage.
FEATURES
* Differential backups (using Rsync) minimize bandwidth and backup time
* Hard links enable multiple snapshots while minimizing storage requirements
* Backups are initiated by the client, i.e. "pushed"
* Each backup appears as a complete copy of the source data.
* Any number of snapshots can be maintained
* Multiple backup periods can be maintained
* Root or user level backups
* Items removed from the backup schedule rotate out naturally
* A command can be executed before and after Rsync processes
* Each host can have have it's own backup schedule
* Each host and each backup source item can have it's own exclusions
REQUIREMENTS
* Bash required on client and server
* SSH, required on client and server
* rsync required on client
* rsync, required on the server only when using rsync in daemon mode
SERVER SETUP
Chronicle is installed on clients only, it is not necessary to install
on the backup server. Though if multiple backup periods are used, you will
need to copy chronicle-rotate.sh to the backup server.
SSH_USER must exist on the backup server, it's recommended to use
the user "chronicle" if root is not used. The password should be set as "!!"
or "*".
useradd -d /var/chronicle -s /bin/bash -c 'Chronicle Backup' chronicle
Using Chronicle with an Rsync server requires further setup. See RSYNC SETUP
CLIENT SETUP
1) Unpack chronicle-<version>.tar.gz
2) Copy "chronicle.conf.default" to "chronicle.conf" and edit as needed
3) Set up SSH keys, see SSH KEY SETUP
Chronicle is called without options or arguments unless an alternate
configuration file is used using the "-f" option to chronicle.sh.
SSH KEY SETUP
1) Generate an SSH keypair as the user you intend to call chronicle.sh with.
ssh-keygen -t dsa
Save to "~/.ssh/id_dsa_chronicle"
If a passphrase is used, it will need to be managed separately.
3) Append an entry to ~/.ssh/config specifying which private key to use when
connecting to the backup server
Host backup01.example.com
IdentityFile ~/.ssh/id_dsa_chronicle
4) Append the public key to the "authorized_keys" file on
the server for the user specified as SSH_USER
At this point, SSH_USER should be able to SSH to the backup server as user
"chronicle" without a password. Use the name specified in ~/.ssh/config
when connecting.
If there are problems connecting, check permissions
# on the client
chmod g-w ~
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_dsa_chronicle
# on the server (assuming "/var/chronicle" is the home dir of SSH_USER)
chmod g-w /var/chronicle
chmod 700 /var/chronicle/.ssh
chmod 600 /var/chronicle/.ssh/authorized_keys
RSYNC SERVER SETUP
Edit /etc/rsyncd.conf. If you want to preserve file ownership and mode, run
rsyncd as root and set "uid = root".
uid = root
gid = root
use chroot = no
read only = false
strict modes = true
secrets file = /etc/rsyncd.secret
For each host being backed up, create a module
[host01.example.com]
path = /var/chronicle/backups/host01.example.com
comment = Backups: host01.example.com
auth users = chronicle
hosts allow = host01.example.com
max connections = 5
Passwords are kept in plain text in files that must be readable only by root
or the user running rsyncd. Edit the file /etc/rsyncd.secret.
chronicle:youllneverguessthis
Then, on the client, edit the file /etc/rsync.pwd, this should only be
readable by the user running chronicle.
youllneverguessthis
Start the Rsync daemon on the backup server with the following command or an
appropriate init script.
rsync --daemon
CONFIGURATION
Options that are commented out in the default configuration file are defaults
and do not need to be specified if not changed.
The user specified with the setting 'SSH_USER' should own and must have write
access to the backup directory.
Restrict permissions on chronicle.sh and the configuration file.
Chronicle is often run by root and you don't want users having the ability to
modify the script or configuration.
Backup Files & Directories
Specify backup source files or directories and respective exclusions one per
line. Each line must begin with "#backup", elements can be separated by any
whitespace. These lines may be anywhere in the configuration file and will be
operated on in top down order. Each line starting with "#backup" is a
separate Rsync process.
Rules regarding a trailing slash on the source and leading and trailing
slashes on exclusions are inherited from Rsync, see the Rsync man page for
more detail.
A trailing slash on the source argument will copy the contents of the
specified directory (like cp -R /etc/*), without the slash, the specified
directory itself will be copied (like cp -R /etc/).
A trailing slash on exclusions only excludes matching directories.
A leading slash on exclusions anchors it to the root of the source argument
(making it generally and absolute path). Use a leading slash to exclude
specific files or directories. Without a leading slash any matching patterns
in the backup hierarchy will be excluded.
A file may be used to specify exclusions also by specifying
"--exclude-file <FILE>" in RSYNC_OPTIONS. Exclusions specified in this way
apply to all source items.
Unique Basenames and Rsync's "--relative/-R" option
If Rsync's "--relative/-R" option is not used, unique basenames must be used
for items specified as sources to prevent overwriting. If for example both
"/home/janedoe" and "/var/spool/mail/janedoe" are given as sources on a
single machine, the backup for the item listed first would be overwritten by
the second with the same name.
The "--relative/-R" option saves the entire source path eliminating the need
for unique basenames.
Examples
Backup "/etc" with no exclusions or exclusions specified in RSYNC_OPTIONS
#backup /etc
Backup "/var" but not any file or directory with names containing either the
string "log" or "spool". When using Rsync's "--relative" option, the pattern
matching is applied to the whole path not just the last element.
#backup /var log spool
Backup "/home" but not the directory "/home/jamie/tmp"
#backup /home /jamie/tmp/
Backup "/home" but not the directory "/home/jamie/tmp" when using Rsync's
"--relative" option.
#backup /home /home/jamie/tmp/
Using Sudo
Setting the USE_SUDO variable to "yes" causes several commands to be
called with sudo. This may be needed to escalate privileges for rotation
if SSH_USER is not set to root and/or rsyncd is not being run as root. For
now enable it's use with all commands without a password. In the future
we should be able to specify allowed commands.
If using SSH transport, either set SSH_USER as 'root' or enable the USE_SUDO
option and make sure the user specified as SSH_USER can use sudo without a
password.
PRESERVATION OF OWNERSHIP AND MODE
Preservation of file ownership and permissions can be accomplished by using
the "-p", "-o", and "-g" options or alternatively the "-a" option to rsync
specified in RSYNC_OPTS. This makes permissions issues much more likely. See
the following section for recommended configurations which are less likely to
have issues
Permissions issues are also likely if chronicle.sh is called
by a user with more privileges to backup files then the user rotating the
files (SSH_USER).
Recommended Configurations
Note that these configurations are not guaranteed to work. This section
will improve as Chronicle is tested more thoroughly.
For SSH transport
# preserve ownership and permissions
SSH_USER='root'
USE_SUDO='no'
RSYNC_OPTS='--numeric-ids -RrlptgoDH --delete --delete-excluded'
# No root SSH, don't preserve ownership and permissions
SSH_USER='chronicle'
USE_SUDO='yes'
RSYNC_OPTS='--numeric-ids -RrltDH --delete --delete-excluded'
For Rsync transport
Wnen using with an Rsync server, it's recommended to run the rsync daemon
as root if you intend to preserve permissions on your backups.
# preserve ownership and permissions
SSH_USER='root'
RSYNC_USER='chronicle'
USE_SUDO='no'
RSYNC_OPTS='--numeric-ids -RrlptgoDH --delete --delete-excluded'
# No root SSH, don't preserve ownership and permissions
SSH_USER='chronicle'
RSYNC_USER='chronicle'
USE_SUDO='no'
RSYNC_OPTS='--numeric-ids -RrltDH --delete --delete-excluded'
PRE AND POST
Chronicle will look at the value of PRE_COMMAND for a program to execute
just before the rsync operation. This program will send all output to the
configured log file. Chronicle can be configured to fail or continue if the
specified command fails using the FAIL_IF_PRE_FAILS configuration option.
Take care that only authorized users can modify any specified scripts as they
are executed by the user calling chronicle.sh which may have more privileges
then the user modifying the script.
These following varibles are available to programs called in PRE_RSYNC_HOOK
SSH_USER
RSYNC_USER
BACKUP_SERVER
BACKUP_DIR
LOG_DIR
NAME
REAL_PATH
MULTIPLE BACKUP PERIODS
The chronicle.sh script only deals with synchronizing data and rotation of a
single period. Schedule chronicle-rotate.sh to run on the backup server for
rotation of multiple periods.
Here's an example of a daily, weekly, and monthly periods using a
"grandfather-father-son" strategy.
1) Edit chronicle.conf to keep 7 snapshots.
BACKUP_QTY="7"
optionally change the name of the backup subdirectories to something
appropriate...
NAME="daily"
2) Schedule the client to run chronicle.sh daily at 7PM, expecting it to be
complete by 11:PM
--> Now we have our dailies
3) Copy chronicle-rotate.sh to the backup server
4) Schedule the backup server run chronicle-rotate.sh once every week
before the daily executes that day. We'll allow 1 hour for this to
complete which should be fine for all but the largest backups.
# Every Saturday @ 6:00 PM for host01.example.com
00 18 * 6 * /opt/chronicle-rotate.sh -d \
/var/chronicle/backups/host01.example.com
--> Now we have our weeklies
5) Schedule the backup server run chronicle-rotate.sh once every month
before the daily executes that day.
# 1st of every month @ 5:00 PM for host01.example.com
0 17 1 * * /opt/chronicle-rotate.sh -d \
/var/chronicle/backups/host01.example.com -s weekly -l monthly -x 4 -y 12
Now we have a years worth of backups!
Alternate method: Using Separate Configuration Files
Another way to get multi-period backups is by calling chronicle.sh with the
"-f" option which allows for the use of alternate configuration files. In
each configuration file, make the value of "NAME" unique. Then schedule
backups with each period using it's own configuration file. This method
performs separate sync operations for each period.
LOGGING
The log directory is be specified in chronicle.conf. Chronicle will attempt
to create the log directory and file if they do not exist.
All log events are prefixed with the value of the LOG_PREFIX variable. A
timestamp is added to log entries using the TIMESTAMP variable. The value
of this variable can be the 'date' command (see documentation for `date`) or
the path to the "tai64n" command if installed to produce a TAI64N format
timestamp as shown in this example.
TIMESTAMP='/bin/date +%Y%m%d-%T'
or
TIMESTAMP='/usr/local/bin/tai64n'
NOTE
The local filesystem can be the backup destination by specifying
"localhost" or "127.0.0.1" as the remote host.
The user specified as SSH_USER must have write privileges on all files and
directories being backed up to allow for rotation. This can be problematic,
try setting SSH_USER as "root" or enabling the USE_SUDO option.
Boolean options in the configuration file may be specified in any mix of
capitalization of yes/no, true/false, 0/1, or enable/disable
Backups using an Rsync daemon are not encrypted before transfer, use only on
trusted networks or for non-secure data.
Use `ls -l` to show the creation date of the snapshot directories, this is
the date of backup
Use the `ls -i` to display a file's inode number, this can be used to
demonstrates that unchanged files across any number of snapshots are
actually the same file.
Use `du -l` to count each hard linked file separately; this shows how much
space would be used if each link was a separate file.
Rsync 3 and Incremental File Lists
Rsync versions prior to 3 used a single file list for the rsync process and
had trouble with very large numbers of files. Newer Rsync versions use
incremental file lists and can effectively deal with very large numbers of
files.
TESTED ON
* CentOS 5
* Arch Linux
FILES
* chronicle.sh
* chronicle.conf.default
* chronicle-rotate.sh
* README
* CHANGELOG
* COPYING
BUGS
Please send comments or report bugs - jamie.carranza@gmail.com