We've been using rsync since forever to back up all our servers and it's
worked without a problem. But in a recent security review, we noted that
our specific rsync backup host is using root keys to access the server,
meaning that if the keys on the backup server were leaked/compromised in
any fashion, that would provide r00t access to the servers being backed up.
Since this doesn't seem to be readily documented, I thought I'd provide
it to the community.
After some playing around, we've found it is possible to set up
rsync/ssh so that the connecting server can ONLY run rsync with a
predetermined set of options.
// OBJECTIVES //
1) Make it so the backup server's SSH key can only be used
A) in an rsync read-only. (no write capability to the production
webserver)
B) against a predetermined set of directories and with a
predetermined set of options.
2) Limit the power of the webserver/backup account so that it cannot do
anything other than a read-only rsync.
3) Limit access to the backup account to a specific IP address, EG: only
the backup server
can access the account.
# ON WEBSERVER (note: normal account!)
-------------------------------------
[root] # adduser backupaccount;
# ON WEBSERVER
in /home/backupaccount/.ssh/authorized_keys ("backupserver" must be the
remote, publicly visible IP address of the backup server)
-------------------------------------
from="backupserver" ssh-dss AAAAB3NzaC1kc3MAAACBAKLv/SNIP/
root@backupserver
-------------------------------------
# ON BACKUPSERVER
Verify that root@backupserver can log in normally via ssh without password:
-------------------------------------
[root@backupserver] # ssh backupaccount@webserver
# ON WEBSERVER
In /etc/passwd. (change the shell at the end of the line)
-------------------------------------
backupaccount:x:514:514::/home/backupaccount:/usr/local/bin/backupaccount.sh
# ON WEBSERVER
in /etc/sudoers
-------------------------------------
backupaccount ALL=NOPASSWD: /usr/bin/rsync
Defaults:backupaccount !requiretty
-------------------------------------
# ON WEBSERVER
And in /usr/local/bin/backupaccount.sh
-------------------------------------
#! /bin/sh
# look in this file to see what options were passed, if the rsync
doesn't work.
echo $* > /home/backupaccount/options.passed.sh
# rsync -va backupaccount@WEBSERVER:/home/ /mnt/backup/home/
/usr/bin/sudo /usr/bin/rsync --server --sender -vlogDtpre.iLs . /home/
-------------------------------------
Note that in this solution, it doesn't matter what the backupserver
specifies as the backup location,
it will ALWAYS get /home/ and it may well break if you change the
options any. EG: using "z" for compression, etc. If this happens, look
in options.passed.sh to see what rsync on the backup server tried to
pass and, if it makes sense, modify the backupaccount.sh script with
these options, or modify backupaccount.sh so that it can take any of a
number of source directories after appropriate validation.