Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am using rsync --rsh "ssh" to push to a mirror. Setting the necessary file system permissions on the mirror requires rsync to run with root privileges on the mirror. However, the mirrored files are under a single hierarchy and I would like to allow rsync to access only that hierarchy and nothing else on the mirror.

How would I allow rsync to set permissions while also limiting access?

Is there possibly some combination of rsync --rsh "???" and the command="???" option in authorized_keys that might do the trick? The rsync command is already using a dedicated key in authorized_keys.

Or is there a way for rsync to connect as an unprivileged user, be jailed, and then gain access to set file system permissions? Jailing the process is easy, but allowing the remote rsync to gain privileges seems difficult, and allowing a jailed process to gain any permissions seems risky. (Of course, right now the process has root and any degree of restriction would be an improvement, even if only to mitigate accidents.)

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

You should be running rsync from your mirror with your original as the source.

Depending on your use case you should either run it as a cronjob (periodic) or an sshkey command (push initiated pull, effectively a push).

share|improve this answer
That was my first thought as well, but the push is coming from transient data in a temporary directory. –  Daniel Kauffman Oct 5 '13 at 7:54
Wait a minute... using the sshkey command I could use the SSH_ORIGINAL_COMMAND environment variable to pass the temporary directory from the push script to the pull script. Thank you! –  Daniel Kauffman Oct 5 '13 at 8:05
@DanielKauffman If you're going to use SSH_ORIGINAL_COMMAND remember to escape or strip out dangerous characters (e.g. ;). –  84104 Oct 5 '13 at 13:54
Thanks, yes, absolutely, I'll be doing positive validation, in my case using Python argparse and os.path.commonprefix. I won't be using SSH_ORIGINAL_COMMAND to pass any sort of command, only the parameters for the command. –  Daniel Kauffman Oct 5 '13 at 16:09
add comment

To rsync a remote location to a local location:

rsync -avze ssh user@source:/dir destination

To rsync a local location to a remote location:

rsync -avz source -e ssh user@destination:/dir

From the manpage (http://linux.die.net/man/1/rsync):

-a archive mode; e.g. copies permissions
-v verbose; in case you want to log what gets copied
-z compress during transfer
-e specify the remote shell to use; let's you use ssh

To get rsync to work without prompting for a password, you'll need to configure a trust between the source and destination servers by generating rsa-keys and entering them into their respective authorized keys. Here's a good tutorial:


share|improve this answer
I understand how to use rsync... I am trying to use rsync to set file system permissions while also limiting access. –  Daniel Kauffman Oct 4 '13 at 20:09
What are you trying to accomplish with setting file system permissions and limiting access? –  CIA Oct 4 '13 at 20:57
On both counts, purpose is to increase security and to minimize potential for accidents. –  Daniel Kauffman Oct 5 '13 at 8:19
add comment

The solution in my particular case is to use rsync --rsh "ssh" to connect as the user who should own the files being mirrored and to use the ssh configuration to chroot that user to the proper hierarchy.

Recipe something like this, on destination server:

useradd user
mkdir /home/user/srv/service
chown -R root:root /home/user

Grant user write permission to /srv/service

nano /etc/fstab

/srv/service /home/user/srv/service none bind 0 0

mount /srv/service

nano /etc/ssh/sshd_config

Match User user
ChrootDirectory %h

service ssh reload

nano /home/user/.ssh/authorized_keys

Add public key for remote user.

Finally, from remote system, as unprivileged user, push data to mirror:

rsync --archive --rsh "ssh" --compress /srv/service/ user@server:/srv/service/
share|improve this answer
A recipe like the above would work in my particular situation but 84104's solution allows for destination-side validation and additional flexibility; no reason I can see not to choose that instead. –  Daniel Kauffman Oct 5 '13 at 8:13
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.