[CentOS] Howto: Extremely tight security rsync shell for backups

Mon Sep 23 19:57:01 UTC 2013
Lists <lists at benjamindsmith.com>

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 at backupserver
-------------------------------------


# ON BACKUPSERVER
Verify that root at backupserver can log in normally via ssh without password:
-------------------------------------
[root at backupserver] # ssh backupaccount at 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 at 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.