I'm running a rsync via apache to sync an assets directory

rsync -avz -e 'ssh -l rsync -i /home/rsync/.ssh/rsync -o StrictHostKeyChecking=no' /var/www/html/site/Uploads centos@$IP:/var/www/html/site/Uploads

This works correctly but the ownership changes from apache to centos as it's the user. I could setup the keys for the apache user however that user can't be logged in so that doesn't work.

How can I get rsync to either run as apache to preserve the ownership or run as the centos user and maintain the owner as apache (cron won't work for my case).

  • @roaima missed one at the beginning. It's in PHP but isn't really relevant for the question. – Rudiger Nov 20 '16 at 23:16
  • @roaima fair point that its not a shell script however wouldn't it be the same outcome independent of the language as long as apache is the executing process? – Rudiger Nov 21 '16 at 0:42
  • 1
    @roaima Command updated to show it as executed. – Rudiger Nov 21 '16 at 9:57

Rsync has an option numeric-ids, that you may be able to leverage here.

Two things though: make sure, on both your servers, that your apache user has the same numeric ID; and make sure the user running rsync can write/update apache owned files to target.

  • so apache would be running rsync on the host, but on the target it's technically centos. I could change it to an rsync user and add it to the apache group but is the security a little bit lower with that? – Rudiger Nov 21 '16 at 0:53
  • Just tried it, doesn't affect it. I think numeric-ids might work if you have the same user-id but different usernames. Sounds pretty edge case. – Rudiger Nov 21 '16 at 10:39

The ownership of files in the target directory is determined entirely by the target account used to create/transfer them. (It's not possible for ordinary accounts to change the ownership of files.)

If you want the target files to be owned by apache there are four options that spring to mind

  1. Transfer the files, logging in to the target account as the apache user. With an ssh certificate you can avoid any need to embed a password. You can also set up the ssh connection to deny any operation other than running the rsync service.

  2. Pull the files from the target host. You could set this job up to run under cron on a frequent basis (rsync with no work can be a relatively cheap option), or you could get it check for a trigger such as creating a file and only if that is activated run the full rsync process.

    In this situation I would have cron running on your target host, checking for a file locally every five minutes with a snippet like this

    test -f "$HOME"/.rsync_trigger && rsync ... && rm -f "$HOME"/.rsync_trigger
  3. Use inotifywait to fix up the file ownerships once the files had been copied. This would require the process to run as root, but it could be carefully self-contained so that it could only change the ownerships of files owned by centos within the apache target directory.

  4. Copy the files with rsync running as root. Not ideal, but may be necessary if all else fails.

  • 1 jumps out as would I'm trying to achieve but as you can't login to as apache (at least on centos) how can I achieve this? – Rudiger Nov 21 '16 at 10:20
  • @Rudiger I assumed when you said can't login this was a policy decision not a technical issue. Of course you will be able to log in as Apache. It may require changing the login shell, setting a password, or possibly even creating the home directory, but it will be perfectly possible. I'll see if I can run up a CentOS VM to see what's required. But looking at those options should be a good start for you. What version of CentOS are you running? – roaima Nov 21 '16 at 10:23
  • When trying to run su apache it says this account is currently not available. I believe this is a security feature of RHEL. I do believe I can convert the account however I prefer to keep security features. – Rudiger Nov 21 '16 at 10:25
  • @Rudiger RHEL or CentOS? Which version? – roaima Nov 21 '16 at 10:43
  • It's CentOS 7. RHEL does the same thing and thats why CentOS inherits it. – Rudiger Nov 21 '16 at 10:48

So the best way I found is to have a user that has sudo access for only that command and use --rsync-path='sudo rsync'. e.g.:

rsync -avz -e 'ssh -l rsync -i /home/rsync/.ssh/rsync -o StrictHostKeyChecking=no' /path/ --rsync-path='sudo rsync' rsync@xxx.xxx.xxx.xxx:/path/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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