首先:我已经阅读了关于SO的类似问题的答案,但没有一个有效。
情况:
什么有效:
.Xauthority
文件复制到其他用户,X11转发也可以。一些设置信息:
DISPLAY
变量在容器中设置(到host-ip-addr:10.0,因为sshd正在侦听的TCP端口6010)。tcpdump
已检查)。什么行不通:
X11 connection rejected because of wrong authentication.
xterm: Xt error: Can't open display: host-ip-addr:10.0
我尝试的事情:
ssh -Y
选项启动客户端ssh "X11ForwardTrusted yes"
放在机器B上的ssh_config中xhost +
(允许任何客户连接)Host *
放在机器B上的ssh_config中X11UseLocalhost no
放在机器A的sshd_config中(允许非本地主机客户端)xauth add
在容器中添加X身份验证令牌.Xauthority
文件从工作用户复制到容器.Xauthority
文件具有正确的权限和所有者我怎样才能禁用所有X安全资料并使其正常工作?
甚至更好:我怎样才能让它与安全性一起工作?
是否至少有一种方法可以启用大量调试以查看问题的确切位置?
答案 0 :(得分:6)
好的,事情就是这样:
1)登录远程计算机
2)检查使用echo $DISPLAY
3)运行xauth list
4)复制与DISPLAY
5)输入您的泊坞容器
6)xauth add <the line you copied>
*
7)使用export DISPLAY=<ip-to-host>:<no-of-display>
*到目前为止还不错?
这不是什么新鲜事......但是这是扭曲:
由xauth list
为登录用户打印的行看起来像这样(在我的情况下):
<hostname-of-machine>/unix:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>
因为我使用桥接docker设置,X转发端口不在本地侦听,因为sshd没有在容器中运行。将上面的行更改为:
<ip-of-host>:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>
实质上:删除/unix
部分。
<ip-of-host>
是运行sshd的IP地址。
如上所述设置DISPLAY变量。
所以错误是环境变量中的DISPLAY
名称与xauth list
/ .Xauthority
文件中的条目“不相同”,客户端因此无法正确验证
我切换回不受信任的X11转发设置。
然而,sshd_config文件中的X11UseLocalhost no
设置很重要,因为接收连接将来自“不同”的机器(docker容器)。
答案 1 :(得分:1)
非常感谢@ Lazarus535
我发现对我来说,将以下内容添加到我的docker命令中是可行的:
--volume="$HOME/.Xauthority:/root/.Xauthority:rw"
我发现了这个窍门here
编辑:
正如拉撒路正确指出的那样,您还必须设置--net=host
选项以使此工作有效。
答案 2 :(得分:1)
这在任何情况下均有效。
如果没有安装xhost
。然后,在bash中
export DISPLAY=:0.0
xhost +local:docker
在此之后,使用docker run
来运行您的-e DISPLAY=$DISPLAY
命令(或您正在运行的任何docker命令)
答案 3 :(得分:0)
它通常通过https://stackoverflow.com/a/61060528/429476
起作用但是,如果您使用与ssh -X
使用的用户不同的用户身份运行docker到服务器中,然后复制Xauthority仅有助于卷映射文件。
示例-我与alex
用户一起进入服务器。然后在su -root
之后运行docker并收到此错误
X11 connection rejected because of wrong authentication.
复制.XAuthoirty文件并像https://stackoverflow.com/a/51209546/429476一样映射它后,就可以正常工作
cp /home/alex/.Xauthority .
docker run -it --network=host --env DISPLAY=$DISPLAY --privileged \
--volume="$HOME/.Xauthority:/root/.Xauthority:rw" \
-v /tmp/.X11-unix:/tmp/.X11-unix --rm <dockerimage>
接线的更多详细信息
答案 4 :(得分:0)
一些澄清的评论。主机是A,本地机器是B
我编辑了这篇文章,以指出我认为理论上应该可行但尚未经过测试的东西,以及我知道可行的东西
如果您的 docker 不是交互式运行并运行 sshd,您可以使用 jumphosts 或 proxycommand 并指定要运行的 x11 客户端。您应该不要与容器共享您的 Xauthority 文件,并且共享 -e DISPLAY 可能对未来的 ssh 会话没有影响
由于您本质上有两个 sshd 服务器,因此以下任一服务器都可以立即使用
如果你的openssh-client版本大于7.3,可以使用下面的命令
ssh -X -J user-on-host@hostmachine,user-on-docker@dockercontainer xeyes
如果您的 openssh 客户端较旧,则语法改为 (谷歌说代理命令中不需要 -X,但我很怀疑)
ssh -X -o ProxyCommand="ssh -W %h:%p user-on-host@hostmachine" user-on-docker@dockermachine xeyes
或者 ssh -X 进入主机,然后 ssh -X 进入 docker。
在上述任何一种情况下,您都应该不要与容器共享 .Xauthority
最简单的方法是设置 --net=host 和 X11UseLocalhost yse。 如果您的 docker 正在运行 sshd,您可以在本地计算机上打开第二个 ssh -X 会话并使用上述 jumphost 方法。 如果您在 ssh 会话中启动它,您可以 -e DISPLAY=$DISPLAY 或在您进入时将其导出。如果您附加到未使用此行的现有容器,您可能必须将其导出。>
将这些 docker args 用于 --net 主机和 x11uselocalhost 是 ssh -X 到主机
-e DISPLAY=$DISPLAY
-v $HOME/.Xauthority:/home/same-as-dash-u-user/.Xauthority
-u user
接下来是对一切工作原理和其他尝试方法的解释
ssh -X/-Y 在 hosts Xauthority 文件中设置会话密钥,然后设置监听端口,在该端口上放置使用会话密钥的 x11 代理,并将其转换为与上的密钥兼容你的本地机器。根据设计,.Xauthority 密钥在您的本地机器和主机之间会有所不同。如果您使用 jumphosts/proxycommand 主机和容器之间的密钥将再次彼此不同。如果您改为使用 ssh 隧道或直接 X11 连接,则必须与容器共享主机 Xauthority,在与容器共享 .Xauthority 的情况下,每个用户只能有一个活动会话,因为新会话将使通过修改主机 .Xauthority 使其仅适用于该会话的 ssh x11 代理
即使 X11UseLocalhost 没有导致 x 服务器侦听通配符地址,但使用 --net 主机我无法将容器显示重定向到 localhost:X.Y 其中 x 以及为什么来自主机 $DISPLAY
如果您选择 X11UseLocalhost yes,则主机上的 DISPLAY 变量变为 localhost:X:Y,这会导致 ssh x11 代理仅侦听本地主机端口 x。
如果 X11UseLocalhost 为 no,则主机上的 DISPLAY 变量变为主机的主机名:X:Y,这会导致 xerver 侦听 0.0.0.0:6000+X 并导致 xclients 通过网络访问指定的主机名.
但这是简单的方法。我们通过将 DISPLAY 变量重定向到始终为 localhost 来绕过它,并执行 docker 端口映射以将数据从容器上的 localhost:X+1.Y 移动到主机上的 localhost:XY,其中 ssh 正在等待转发 x 流量回到本地机器。 +1 使我们不知道运行 --net=host 或 --net=bridge 设置容器端口需要在 dockerfile 中指定公开并使用 -p 命令发布端口。
这仅适用于 --net 主机。这种方法无需 xauth 即可工作,因为我们直接通过管道连接到本地机器上的 unix 域套接字
ssh 到主机不带 -X
ssh -R6010:localhost:6010 user@host
start docker with -e DISPLAY=localhost:10.1 or export inside
在本地机器上的另一个终端
socat -d -d TCP-LISTEN:6010,fork UNIX-CONNECT:/tmp/.X11-unix/X0
在原始终端运行 xclients
如果容器是 net --bridged 并且您不能使用 docker 端口,请在容器上启用 sshd 并使用 jumphosts 方法