This repo documents a simple backup strategy and contains some somewhat reusable scripts.
These scripts are used on TMC production servers but are generic enough to be usable elsewhere.
This is a reasonably simple and secure strategy for daily full backups. It doesn't account for incrementality.
On the production server, there are scripts to create backups of databases and other live things
into /backup/staging
. The scripts move finished backups to /backup/ready
.
This two-stage setup has the following benefits.
- When backing up plain files, one can keep a copy in the staging dir
and incrementally
rsync
it up to speed. This reduces the amount of copying needed. - It prevents anyone from reading half-finished backups. Only an absurdly unlikely potential race condition of seeing a missing file remains.
The production server has a user+group called backupreader
.
The backup server shall have passwordless SSH access to this user.
The production server's /etc/ssh/sshd_config
limit this user to
SFTP only and chroot it to /backup/ready
with the following configuration block.
Match User backupreader
ChrootDirectory /backup/ready
AllowTcpForwarding no
X11Forwarding no
ForceCommand internal-sftp
The backup script should chgrp backupreader
and chmod g+rX
everything it puts in /backup/ready
,
or ensure it as a suitable umask, to make sure the backups are readable.
Now the backup server has a cron'ed script like the following to fetch daily backups.
#!/bin/sh
cd `dirname "$0"`
TIMESTAMP=`date +%Y%m%d`
DEST=backups/$TIMESTAMP
mkdir -p $DEST
lftp -c "open sftp://backupreader:@my-server.com/; lcd $DEST; mirror"
# After a week, get rid of every two backups.
# After two weeks, only keep monday's and friday's backups.
/path/to/backup-scripts/thin-backups.rb backups 7:1,3,5,7 14:1,5
Security. If the production server is compromised, the attacker can (in theory) compromise previous backups.
A setup wizard that generates some backup scripts into /backups/scripts and sets up a backupreader
user.
It probably only works on Debian-based systems.
Removes old daily backups. Can be configured to e.g. keep only every monday's and friday's backups when they are over two weeks old and to keep only weekly backups when they are over a month old.
Run it without arguments for instructions.
To be included by other scripts on the production server. Read it to see what it does, it's quite short.
Usage example:
#!/bin/sh -e
BACKUP_NAME=redmine
. `dirname "$0"`/common.sh
mysqldump -u redmine -predmine redmine | gzip > "$STAGING/redmine.sql.gz"
rsync -av --delete /home/redmine/srv/redmine-2.1/files/ "$STAGING/files"
rm -f "$STAGING/files.tar.gz"
tar -C "$STAGING" -cpzf "$STAGING/files.tar.gz" files
ready files.tar.gz redmine.sql.gz