Some context:
backup
directory on the server, which I update manually by stopping the services, copying the data into that directory (using rsync -Payz --delete --recursive
, which preserves metadata and avoids unnecessary copies), then relaunching the servicesbackup
directory on my laptop, and keep it updatedrsync -Payz --delete --recursive user@server:backup .
root
as an owner and rsync
isn't allowed to move them without sudo
(the services run in containers, and those permissions make sense at the container level, but at the host level the system considers the host's root
is the owner)sudo rsync
, but for the copy on my laptop I have to tell rsync
to run sudo rsync
on the server and forward the password request to the client, which brings us to the current issueWhat I've done:
I've followed the advice from this post, so the full command I'm running is
rsync -Payz --delete --recursive -e "ssh -X" --rsync-path="sudo -A rsync" user@server:backup .
--rsync-path="sudo rsync"
is used to run rsync
with sudo
rights on the remote--rsync-path="sudo -A rsync"
is used so that sudo
relies on ssh-askpass
to get the password-e "ssh -X"
enables X11-Forwarding so that ssh-askpass
can ask me to type the password on my laptopThe issue
Error: Can't open display:
sudo: no password was provided
sudo: a password is required
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(231) [Receiver=3.2.7]
-e "ssh -Xv"
, the following lines appear that seem to be the issuedebug1: X11 forwarding requested but DISPLAY not set
debug1: Sending command: sudo -A rsync --server --sender -logDtprze.iLsfxCIvu . backup
Error: Can't open display:
sudo: no password was provided
sudo: a password is required
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
Transferred: sent 2176, received 2464 bytes, in 0.2 seconds
Bytes per second: sent 9432.6, received 10681.1
rsync error: error in rsync protocol data stream (code 12) at io.c(231) [Receiver=3.2.7]
so apparently when rsync
runs ssh -X
here, the DISPLAY
variable is left unset
ssh -X 'echo $DISPLAY
however, it does displays localhost:10.0
, and running ssh -X user@server 'sudo ls'
does ask me the password as expected (through a window titled "OpenSSH Authentification Passhrase Request")ssh -X
and rsync
, not the X11-Forwarding itself, but I don't get what I'm doing wrongI can only suggest you trace the environment being passed through rsync as follows. Add option -n
to do no transfers, and use some /tmp/dummy
file. Prefix the command with strace
using option -v
to see the environment during execve()
calls, -f
to follow children, and -o log
to output to some log file.
For example,
DISPLAY=:0 strace -vf -o /tmp/log rsync -n -Payz --delete --recursive \
-e 'ssh -X' --rsync-path='sudo -A rsync' user@server:/tmp/dummy /tmp/dummy
Looking through the log file you should see something like
5261 execve("/usr/bin/ssh", ["ssh", "-X", "-l", "user", "server",
"sudo -A rsync", "--server", "--sender", "-nlogDtprze.iLsfxC", ".",
"/tmp/dummy"], ["DISPLAY=:0", "SHELL=/usr/bin/bash", ...] <unfinished ...>
(one long line).
Beware, you may need to ignore many execve's of ssh
that are
attempted and fail as each directory in the current PATH
is tried.
In this example output, 5261 is the process id.
The execve()
system call of /usr/bin/ssh
shows
the arguments to ssh
in the first array [...]
,
and the environment passed to the command in the second array [..."DISPLAY=:0"...]
.
Ensure "DISPLAY=:0" is in this second array.
If it isn't, then look earlier in the file for the first execve()
of rsync
to see
if DISPLAY is in the env there. You should find something like:
5624 execve("/usr/bin/rsync", ["rsync", "-n", "-Payz", "--delete",
"--recursive", "-e", "ssh -X", "--rsync-path=sudo -A rsync",
"user@server:/tmp/dummy", "/tmp/dummy"], [...,"DISPLAY=:0",...]) = 0
You can add a second -f
to strace
to get separate log files, one for
each process, rather than all intermixed.
If it is in the first execve("/usr/bin/rsync"
, and not in the later
execve("/usr/bin/ssh"
, that would indeed suggest that rsync has
deliberately removed it from the environment. Perhaps this is some sort of
new security feature?
To work round it, create your own shell script "ssh" in your PATH
that
simply does
#!/usr/bin/bash
export DISPLAY=:0; exec /usr/bin/ssh "$@"