The rsync is a great tool for maintaining archives of files across multiple hosts and for making backups. Coupled with tools like rsnapshot, you have a quite powerful backup solution. Of particular value is that each backup image looks like a full backup, while the space taken up is only what would be required for an incremental backup.

Of course there have to be downsides too. From a resource point of view, the most notable ones are that when a small change is made to a big file, the entire new file is stored in the updated image not just the delta; additionally, there is no compression provided unless you're doing that at the filesystem level. But with disks being so cheap, these are fairly minor quibbles.

Setting up rsnapshot (and rsync access) is a little more tricky, however. To perform an rsync with rsnapshot and preserve file ownership and permissions in the backup image, rsnapshot (and hence rsync) must run as root on the backup server. To be able to access all files to run the backup, rsync must run as root on the client machine as well. While you may be happy with running rsync as root, allowing passwordless root ssh logins to your machine is probably not high on your priorities. The plan here is to set up key-based authentication to permit rsync to work across your machines while restricting the IPs from which connections can come and restricting the key to being used with rsync.


For the purposes of this description, server will mean the backup server (e.g. the machine running rsnapshot), and client will mean the remote machine from which files are backed up.

Presumably, you have ssh and rsync already installed at this stage (aptitude install ssh rsync).

Key-based login

To set up passwordless logins (i.e. key-based authentication), log in as root on the server and create an ssh key (ssh-keygen). You will also need to make sure that root's ssh will sue this key so it's a reasonable change to configure ssh at this stage. /root/.ssh/config:

Host  client
   User root
   IdentityFile /root/.ssh/id_dsa

And then copy the key onto the client so that it can be used.

ssh-copy-id -i /path/to/id_dsa myhost

At this stage, ssh client should log you in to the remote machine without prompting you for a password.

Restricting the key-based login

We now want to make sure that this key can only be used for the purposes we want, so on the client, edit /etc/ssh/sshd_config and set:

PermitRootLogin forced-commands-only

See man 5 sshd_config for more details, and remember to restart the ssh server to have that take effect:

invoke-rc.d ssh restart

At this stage, only key-based login is possible and without a forced-command associated with the key, nothing can be done, so ssh client will return a "Permission denied" error.

Allowing key-based login from specific hosts

We now want to permit key-based logins for rsync from our backup server. To do this, we edit /root/.ssh/authorized_keys on the client to:

  1. permit logins only from the backup server
  2. permit only rsync to be used with this key
  3. prevent an other uses of the key such as port forwarding

All of the options for these limitations are documented in man 5 authorized_keys (see the section AUTHORIZED_KEYS FILE FORMAT).

from="",command="/usr/local/bin/secure-rsync",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dss AAAAB3NzaC1..... == root@server

where this is all on one big long line and the key that you already copied into this file earlier using ssh-copy-id is the ssh-dss and what follows.

Restricting commands

The command="/usr/local/bin/secure-rsync" configuration above means that no matter what command is given by the remote user, /usr/local/bin/secure-rsync will be run. You can thus use /usr/local/bin/secure-rsync to sanitise the command: sample script.

With this in place, any command that is not "rsync" will be rejected:

ssh client pwd

scp and sftp will similarly fail, but rsync will work:

rsync -a client:/etc /media/backups/myhost/etc

Additionally, this rsync command will only work from the configured IP address ( in the example above).

Last edited: Wednesday April 22, 2009

Valid XHTML 1.1 Valid CSS 2