rsync与X11转发不设置DISPLAY?

huangapple go评论70阅读模式
英文:

rsync with X11-Forwarding does not set DISPLAY?

问题

Here is the translated content you requested:

一些背景信息:

  • 我的Debian服务器上运行了一些服务,不时地我想备份相关数据。
  • 服务器上有一个名为backup的目录,我通过手动停止服务,使用rsync -Payz --delete --recursive将数据复制到该目录(保留元数据并避免不必要的复制),然后重新启动服务来更新它。
  • 我想在我的笔记本电脑上拥有backup目录的副本,并保持更新。
  • 为此,我想运行类似于rsync -Payz --delete --recursive user@server:backup .的命令。
  • 这里的主要困难在于,许多文件的所有者是root,而rsync没有sudo的权限来移动它们(服务在容器中运行,这些权限在容器级别是有意义的,但在主机级别系统认为主机的root是所有者)。
  • 要创建服务器备份,我可以简单地调用sudo rsync,但对于笔记本电脑上的副本,我必须告诉rsync在服务器上运行sudo rsync并将密码请求转发到客户端,这就引出了当前的问题。

我做了什么:
我遵循了此帖子中的建议,所以我运行的完整命令是:

rsync -Payz --delete --recursive -e "ssh -X" --rsync-path="sudo -A rsync" user@server:backup .
  • --rsync-path="sudo rsync"用于在远程上以sudo权限运行rsync
  • --rsync-path="sudo -A rsync"用于使sudo依赖于ssh-askpass来获取密码。
  • -e "ssh -X"启用X11转发,以便ssh-askpass可以要求我在我的笔记本电脑上输入密码。

问题:

  • 这在我的旧笔记本电脑上(MacBook)有效,但在我的新笔记本电脑上(运行Manjaro发行版)无效。考虑到链接的帖子评论说它在Ubuntu上有效,我认为我需要更改配置中的某些内容,或者可能我遗漏了某些依赖项,但我不知道是什么或为什么。
  • 我得到的错误如下:
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"运行该命令时,出现以下行,似乎是问题所在:
debug1: 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]

所以显然当rsync在此处运行ssh -X时,DISPLAY变量未设置。

  • 如果我运行ssh -X 'echo $DISPLAY',它会显示localhost:10.0,并运行ssh -X user@server 'sudo ls'会像预期的那样要求密码(通过一个名为“OpenSSH身份验证密码请求”的窗口)。
  • 我相信这意味着问题出在ssh -Xrsync之间的交互,而不是X11转发本身,但我不知道我做错了什么。

请注意,这是您提供的内容的翻译版本。如果您需要进一步的协助,请随时告诉我。

英文:

Some context:

  • I have some services running on my Debian server, and from time to time I want to make a backup of the relevant data
  • I have a 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 services
  • I want to have a copy of the backup directory on my laptop, and keep it updated
  • To that end, I want to run something like rsync -Payz --delete --recursive user@server:backup .
  • The main difficulty here is that many of the files have 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)
  • To create the sever backup I can simply call 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 issue

What 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 laptop

The issue

  • This used to on my old laptop (a MacBook), but doesn't on my new one (running a Manjaro distribution). Given that the linked post's comments say it's working on Ubuntu, I'm assuming I need to change something in my configuration, or maybe I'm missing a dependency or something, but I have no idea what or why
  • The error I get is the following:
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]
  • When I run the command with -e "ssh -Xv", the following lines appear that seem to be the issue
debug1: 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

  • If I run 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")
  • I believe that means that the problem is in the interaction between ssh -X and rsync, not the X11-Forwarding itself, but I don't get what I'm doing wrong

答案1

得分: 1

以下是您要翻译的内容:

"I 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 "$@"
英文:

I 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 "$@"

huangapple
  • 本文由 发表于 2023年5月17日 23:30:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76273779.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定