Rsync over SSH – Keeping file ownerships and permissions

One of the simplist and most secure way of backing up your data across the network has got to be with rsync via ssh. A tool I’m sure you’re already aware of.

One of the most frustrating things, however, is restoring your much needed backup to find the file permissions and ownership is that of which ever ssh user was used to call the rsync. This can be a disaster if restoring system files or some ones web site with all sorts of custom chmods.

Why does this happen? The answer simply is that rsync was connecting to the backup server as root (or a user with root privileges).

Unless you are ssh’ing as root, which I’m sure you’re not as we all know how silly allowing root ssh to the server is, right? So we need a secure solution, so here comes sudo to save the day!

Consider the following rsync command:

# rsync -a /usr/local/www ssh-user@backup-server.tld:/usr/backup_dir/

This will copy the /usr/local/www directory from the server we are running rsync from to the backup server as user ‘ssh-user’. It wont keep any special permissions or ownerships, just the default umask and owned by ssh-user, ssh-user does not have the access, just try sshing in as that user and doing a chown root:wheel www. If you can’t do it rsync can’t do it, we use sudo to give us the rights.

First you’ll need to have the following in your sudoers config.

# visudo
Cmnd_Alias      RSYNC = /usr/local/bin/rsync

ssh-user        ALL = NOPASSWD: RSYNC

Now we have the rights we need to tell rsync how to use sudo, and therefor keep permissions. Simply done like this:

# rsync -a --rsync-path="sudo rsync" /usr/local/www ssh-user@backup-server.tld:/usr/backup_dir/

The extra flag, –rsync-path, tells rsync to run `sudo rsync` when it gets to the backup server instead of `rsync`.

Hope this is of use to someone out there!

You may also like...

  • GG

    doesn’t this pose a security risk???
    Users can execute rsync as root, meaning they can access all root can access.
    This means on a backup server used by various users and companies, that they would be able to access other users if they ran rsync from shell.

    Please share your thought on this

  • GG

    Cmnd_Alias RSYNC = /usr/local/bin/rsync
    ssh-user ALL = NOPASSWD: RSYNC
    use –rsync-path=”sudo rsync” (does not work on debian armel I tried )

    I wish to reply to myself and any other reader, so if the poster does not reply my findings are shared.
    Often ssh login is automated via authorized_keys with no password. Restrict commands issuable from user or worse root to avoid the non passworded key-holder from doing all it wants.

    Read this:

    AND use rrsync
    cd ~ && cp /usr/share/doc/rsync/scripts/rrsync.gz && gunzip rrsync.gz && less rrsync
    # Purpose: Restricts rsync to subdirectory declared in .ssh/authorized_keys

    Yuk… In the end I should allow root access to my backup site (shivers) in order to get owner and group rsynced, but I can
    – use knockd to open the non standard ssh port
    – limit the rsa key / root login to one specific command and from one IP/hostname (fairly narrowed, if no vulnerabilities stick up)
    – limit rsync to one directory via rrsync

    Hectic, sending, this article must deal a few more things if I did not miss something huge..

  • GG

    Last comment:

    to allow rsync users to keep their permissions, rsync must run as sudo.
    #visudo /etc/sudoers
    ; Cmnd alias specification
    Cmnd_Alias RSYNC = /usr/bin/rsync # find / -name “rsync” before to see where is rsync
    ; User privilege specification
    specific-ssh-username ALL = NOPASSWD: RSYNC


    #use this command additional parameters to rsync
    rsync -a –rsync-path=”sudo rsync” source destination
    –super does not help but I use that too


    then to restrict rsync from that key, add -v to rsync command -e “ssh -v”
    debug1: Sending command: bla bla bla

    /home/user/.ssh or /root/.ssh/ authorized_keys
    from=”PTRhostnameOrIP”,command=”rsync bla bla bla” ssh-rsa AAABBBBla

    END test rsync :) keeping owners, root super limited to 1 rsync command and 1 IP

  • kameha

    Magnifique, cela m’a bien servi. J’avais ce problème de droits pour garder à la destination les user et group owner après réplication par rsync. C’est ici que j’ai trouvé la solution.
    Merci beaucoup.

  • kameha

    Magnifique, cela m’a bien servi. J’avais ce problème de droits pour garder à la destination les user et group owner après réplication par rsync. C’est ici que j’ai trouvé la solution.
    Merci beaucoup.

  • swonder


  • swonder


  • Darwin

    Thats stupid!

    ssh-user can now do this

    “rsync -a –rsync-path=”sudo rsync” /you-are-so-fucked/etc/ ssh-user@backup-server.tld:/etc/”.

  • Darwin

    Thats stupid!

    ssh-user can now do this

    “rsync -a –rsync-path=”sudo rsync” /you-are-so-fucked/etc/ ssh-user@backup-server.tld:/etc/”.

  • This example mainly demonstrates a way to get round having to ssh to the target server as the root user. I understand in the wrong hands this could get messy.

    GG left some comments below suggesting a way to make this more secure by adding some additional options into the public key file.

  • gare

    Thanks for writing this post. Yours combined with some others was just what I needed. I ‘d like to respond to the 2 posters asking about security. There is not a greater security risk; this post shows how to be more secure by not having to use root on the remote machine. The need for this use case is to be able to have sudo or root access to files that you do not have access to as a regular user so you can move them. You are giving this sudo access to 1 user account so that you do not have to use the root account on the remote machine. That is more secure.

    Thanks again.

  • random blogger

    This is insecure – the remote user can now use rsync to dowload, modify. and replace /etc/passwd /etc/shadow /etc/crontab /etc/ssh/sshd_config /root/.ssh etc… with such access I can think of about
    4 different ways to get “root”. as such it is no better than just connecting to remote server as root.

    Perhaps theres’s something safer in the ‘rrsync’ example in the rsync docs.

  • Chris M Lewis


    I have this permissions keeping problem. I don’t get the solution, and it seems not to work for me. given below, what am I missing.

    Fedora 21 on a desktop, with a spare disk, headless rpi with a disk as house wide file server, server cifs and nfs. Trying a backup scrypt with rsync running on the desktop to backup/mirror the shared files on the rpi to the spare disk in the destop. Getting lots of permission errors on the desktop, mostly because the user running the rsync changes the owner. If I change them back then the next time the script-running-user runs it fails on permissions.

    I found this: which as the man pages do require me to run rsync as root to maintain owner. Which is what you say here.

    What I don’t understand: if you put the visudo entry in on the local machine then use the –rsync-path=”sudo rsync” flag, then you have told the remote machine to run “sudo rsync” where the remote machine still has no direction to use rsync passwordlessly. Presumably when changing the visudo you mean on the remote machine?

    Trying as above with all changes on the local machine lead to errors as before.

    Could you give a bit more detail about which user is being used where, and which machine the changes are on?
    many thank

  • Johannes Linkels

    Thanks for the explanation. I had found out about the “rsync-path=”sudo rsync”. That worked, but only because I am allowed to sudo without password. On other servers where I am not allowed to sudo without password this didn’t work. Thanks for your tip to allow me to run rsync passwordless, and only rsync, not everyhting.
    However, I am wondering about the –fake-super option. According to the rsync manual, this option would preserve owner attributes during rsync. To avoid exactly having to be root or sudo while rsyncing. It is clear –fake-super doesn’t work, and it is also understandably why: only root can set owner attributes. But for what is –fake-super good then?

  • This works well enough for me to back up my server to my backup server, neither of which have other users on them.