using rsync with ssh keys via authorized_keys and command="rsync ..."

By thomas, 29 January, 2010
We often need to keep two directories on different machines synchronised. We would like the rsync to be secure and to only allow the rsync, no shell access. This method uses ssh keys with commands in authorized_keys.

Scenario I

Backup directory /mnt/one from server pris to client directory /home/user/two on client deckard by initiating the the copy from the client deckard. (i.e. send files from the server to the client)

  • create ssh keys using ssh-keygen
    [user@deckard ~]$ cd .ssh [user@deckard .ssh]$ ssh-keygen -t dsa -f deckard Generating public/private dsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in deckard. Your public key has been saved in deckard.pub. The key fingerprint is: 17:f4:69:30:6c:67:5a:73:2e:6f:ba:4b:8b:94:2a:f9 user@deckard.example.com The key's randomart image is: +--[ DSA 1024]----+ | .+ | | .o+=.. | | ..=++ | | .o. . | | S . o | | . . o | | . o .o | | o o o.. | | oE . +o | +-----------------+
  • create a new user for the sync operation and copy the public key you just created to pris
    [root@pris ~]# useradd deckardsync [root@pris ~]# su - deckardsync [deckardsync@pris ~]$ mkdir .ssh [deckardsync@pris ~]$ cd .ssh [deckardsync@pris .ssh]$ scp user@deckard:.ssh/deckard.pub authorized_keys deckard.pub 100% 1194 1.2KB/s 00:00
  • make the /mnt/one directory accessible to deckardsync (or ideally owned by this user)
    [root@pris ~]# chown deckardsync /mnt/one
  • edit authorized_keys and add the commands for rsync into the key
    command="rsync --server --sender -vlogDtprCz . /mnt/one/" ssh-dss AAAAB3NzaC1kc3MAAACBANbyPA4Vkem1tXrBcmkc9+SHeBrgHKbeBdS2MZKMBT/CsPWPSwMFQGg3GzX2KFrIVlZW/+OfkFcrZabMxtLb4CfvFgZsK18hcyYWZobhtpzqfsoolVnWbHdcmxFqyUq9fIK5iPA2UnvLoLRCDuklQNZ+V8o7fiCiPzXw5sqw3weRAAAAFQDKbAINhyt3OzJhP680PqrA9vHNFwAAAIB0mmnu9rfUKnSAH8UV068H28NEaNuIvSzQchvsPpBZmLpN/yr0mUbWdUJtVfFO72fbhQW+gQmEydCoPgehAGCx0g5jcs+0J7nhDlCqCqYAluD/79jJvEr7Tc33u0QTJSEX9My5X6OVtKByGfGPIyeLdhdsM2s70xbXKpfV4j8KpgAAAIEAnbxqsdbxpZ/vKZMJCW4TuHzOk76By5HHHHRb6XIUTsImQmoHrH1T2ioVil6eNp+V02hbYzbs8OuMqj6ne3gLzIyPqIP1OHuusisrLKgtWTC74lZnZ48d9QCyUHI48yZyoISs0HvEvC08LHYqsq1z1ntCHAde4iszE2TAMsYBat4= user@deckard.example.com
    Note: there are no line breaks in the above key... the file has only one line.
  • copy something into /mnt/one on pris
    [root@pris ~]# cd /mnt/one [root@pris one]# cp -a /usr/share/doc/rsync-2.6.8 .
  • start rsync on deckard using the ssh key
    [user@deckard .ssh]$ rsync -e 'ssh -i deckard -l deckardsync' -Cavz pris:/mnt/one /home/user/two/ receiving file list ... done ./ rsync-2.6.8/ rsync-2.6.8/COPYING rsync-2.6.8/README rsync-2.6.8/tech_report.tex sent 98 bytes received 14416 bytes 29028.00 bytes/sec total size is 36507 speedup is 2.52 [user@deckard .ssh]$ ls ~/two rsync-2.6.8

Scenario II

Backup directory /home/user/two from client deckard to server directory /mnt/three on server pris

The steps involved here are essentially the same with only one small change in the authorized_keys, drop the --sender option to rsync (since pris is no longer the sender)

  • create new ssh key for the transfer in this direction.
    [user@deckard .ssh]$ ssh-keygen -t dsa -f pris Generating public/private dsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in pris. Your public key has been saved in pris.pub. The key fingerprint is: 75:67:7a:ca:2f:b2:11:f4:83:50:27:07:50:0b:55:a3 user@deckard.math.ias.edu The key's randomart image is: +--[ DSA 1024]----+ | o+*o= | | o * . | | . E . o | | + + + | | S o + . | | o + | | . o | | .... | | .o .. | +-----------------+
  • copy the key to pris and append it to authorized_keys
    [root@pris .ssh]# scp user@deckard:.ssh/pris.pub . user@deckard's password: pris.pub 100% 617 0.6KB/s 00:00 [root@pris .ssh]# echo -n 'command="rsync --server -vlogDtprCz . /mnt/three" ' >>authorized_keys [root@pris .ssh]# cat pris.pub >>authorized_keys
  • initiate the transfer from deckard, this time acting as the sender not the receiver (flip sender for receiver)
    [user@deckard .ssh]$ rsync -e 'ssh -i pris -l deckardsync' -Cavz /home/user/two/ pris:/mnt/three building file list ... done ./ rsync-2.6.8/ rsync-2.6.8/COPYING rsync-2.6.8/README rsync-2.6.8/tech_report.tex sent 14422 bytes received 98 bytes 29040.00 bytes/sec total size is 36507 speedup is 2.51
Now you just need to put that rsync line in a cronjob and you'll have automatic syncing. (if you do, remember to use the full path for the ssh-keys you generated). The nice thing here is that if the key should be discovered, the only thing the attacker can do is run rsync.