Having a problem that rsync does not set UID and GID as expected, my gut feeling is that rsync should be run as root on the destination machine.
I can't login as root via SSH, since that's disabled for security purposes. The user on the destination machine is able to use sudo.
Is it possible to use rsync with sudo?
6 Answers
On the destination machine
- Find out the path to
rsync:which rsync - Edit the
/etc/sudoersfile:sudo visudo(see also: must I use visudo?) - Add the line
<username> ALL=NOPASSWD:<path to rsync>, where username is the login name of the user that rsync will use to log on. That user must be able to usesudo
Then, on the source machine, specify that sudo rsync shall be used:
rsync ... --rsync-path="sudo rsync" ...Using it without the NOPASSWD on the destination machine will result in the message
12sudo: no tty present and no askpass program specified
My solution is to use --rsync-path="sudo rsync", if it ask for password you can use workaround like this:
rsync -avz --stats --rsync-path="echo <SUDOPASS> | sudo -Sv && sudo rsync" user@192.168.1.2:/ .However, it is better to not type your password on the commandline, where it sill be stored in terminal history. Instead, you can use read -s to prompt for the password without showing it:
read -s -p "Remote sudo password: " SUDOPASS && rsync -avz --stats --rsync-path="echo $SUDOPASS | sudo -Sv && sudo rsync" user@192.168.1.2:/ .(Note: -p to prompt isn't supported in all shells (e.g. zsh), if you get an error you can leave it off, or echo before reading instead)
You can have the remote sudo ask you for your password through X-windows. Here's a way to do that:
- Make sure
ssh-askpassis installed on the remote host (and that you are using X-windows, of course) - Make sure this is in
/etc/sudo.conf:
# Path to askpass helper program
Path askpass /usr/bin/ssh-askpassAdd these options to rsync:
-e "ssh -X" --rsync-path="sudo -A rsync"ssh -Xwill forward your X-windows information and port to your remote sessionsudo -Awill make sudo use ssh-askpass to ask you for your password
If there is no access to sudoers file, just create a wrapper script for the ssh command.
ssh_sudo:
{ echo $PASSWORD; cat - ;
} | ssh $* &At first, this passes the password to the ssh client's sudo process in order to start rsync on the remote side. Next all input coming from the local rsync is piped to ssh.
Finally call rsync e.g. with:
PASSWORD=<SUDOPASS> rsync -avzue ssh_sudo --rsync-path "sudo -S rsync" SRC DSTI guess the security aspect here is not that bad, you'll only have to save the password locally as env var. Reading it from a file should work as well...
1When trying to solve this same problem in the ansible synchronize module, I came across this question and would like to draw some attention to the solution by Simon Schmid. Can't upvote or comment using my account (not enough reputation points), so I'll post this as another answer:
Simon's solution not only is the safest alternative in that it requires no changes to sudoers and passes the password using the environment (so that it will not pop up in history files and logs), it also works without changes to the target machine, which is very convenient if you want to rsync to lots of fresh machines and do not want to reconfigure them just for this command.
After playing around with it a bit, I've managed to inline the shell commands used for wrapping ssh on the host machine as well, so it is possible to just use a single rsync line:
PASSWORD=<SUDOPASS> rsync -avzue '/bin/sh -c "{ echo $PASSWORD; cat - ; } | ssh $0 $* &"' --rsync-path "sudo -S rsync" SRC DSTHappy syncing ;-)
2The solutions which suggest modifying /etc/sudoers or echoing the password into a pipe didn't feel comfortable.
Instead, I've found success with the answer posted here. My slight modification prepends a sudo to the rsync call in the second line in order to have unrestricted write permissions on the local machine as well.
stty -echo; ssh myUser@REMOTE_SERVER "sudo -v"; stty echo
sudo rsync -avze ssh --rsync-path='sudo rsync' myUser@REMOTE_SERVER:/REMOTE_PATH/ /LOCAL_PATH/ 1