Monday, November 17, 2014

Rsync files between two machines over SSH and limit read access

From time to time I need to get contents from a remote machine to my local workstation. The data sometimes is big and I don't want to start all over again if something fails. Further the transmission should be secure and the connection should be limited to syncing only this path and its sub-directories. So I've setup a way to do this using rsync and ssh and I'm going to describe this setup.

Consider you have already created a SSH key, say ~/.ssh/key_rsa together with ~/.ssh/key_rsa.pub, and on the remote machine there is an SSH server running allowing to login by a public key and rsync is available. Lets further assume the following:

  • the remote machine is rsync.domain.tld
  • the path on the remote machine that holds the data is /path/mydata
  • the user on the remote machine being able to read /path/mydata and to login via SSH is remote_user
  • the path on the local machine to put the data is /path/mydest
  • the user on the local machine being able to write /path/mydest is local_user
  • the user on the local machine has the private key ~local_user/.ssh/key_rsa and the public key ~local_user/.ssh/key_rsa.pub

Now the public key ~local_user/.ssh/key_rsa.pub is added to the remote users ~remote_user/.ssh/authorized_keys file. The file will then probably look like this (there is just one very long line with the key, here cut out by [..]):

ssh-rsa [..]= user@domain.tld

Now I would like to limit the abilities for a user logging in with this key to only rsync the special directory /path/mydata. I therefor preceed the key with a command prefix, which is explained in the manual page sshd(8). The file then looks like this:

command="/usr/bin/rsync --server --sender -vlogDtprze . /path/mydata",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa [..]= user@domain.tld

I then can rsync the remote directory to a local location over SSH by running:

rsync -avz -P --delete -e 'ssh remote_user@rsync.domain.tld' rsync.domain.tld:/path/mydata/ /path/mydest

That's it.

4 comments:

  1. Interesting. I usually use rrsync for this job. On Debian, you can find it in /usr/share/doc/rsync/scripts/rrsync.gz. That has the advantage that users can still sync subdirectories of the "permitted root", and one does not have to fear some of these flags changing in future versions. Did you try rrsync and discard it for some reason? If yes, I'd be interested to learn why.

    ReplyDelete
    Replies
    1. Hi and thanks for the hint. I didn't know it. From a quick look: it seems, rrsync runs on the remote machine and sets the command=".." stuff similar to my solution by using an SSHD_* environment variable. I cannot find much differences except for that in my setup the command is directly written into .ssh/authorized_keys whereas for rrsync an extra script is used to achieve almost the same (result). Another difference is, that one has to keep the rrsync script up-to-date by hand.

      What do you think is the advantage of using rrsync over my setup?

      Delete
  2. There is also authprogs https://github.com/daethnir/authprogs, which can a bit simplify the setup described above.

    ReplyDelete