Forward x11 可以工作但不能进入 Xypher “无法打开显示:localhost:11.0”

Forward x11 可以工作但不能进入 Xypher “无法打开显示:localhost:11.0”

在本地网络上,我有一个远程(无头)Ubuntu 服务器。我想访问该机器上的桌面,但我真的不想安装 vnc 等……我已经有了 lxde,为什么我不能转发 x11 并启动 lxde 并开心地工作呢?好吧,我可以,

ssh -X user@server
# and now on the server:
xeyes
# shows up on my pc and
startlxde
# Also shows up on my PC. So there are no issues with permissions or xhost or whatever.
# But then that polutes my PC desktop with the server desktop.
exit 
# I want to "capture" the server x11 display into a window on my PC. 
# Enter Xyfer, said to do exact that. Back on the PC
Xephyr -ac -br -keybd ephyr,,,xkbmodel=pc105,xkblayouts -noreset -screen 800x600 :1 &
# And that starts perfectly. No problem. And I can 
export DISPLAY=:1
xeyes
# and the eyes show up in the Xephyr window. Brilliant! But then when I
ssh -X user@server
export DISPLAY=localhost:11.0
xeyes
# I get:
# Error: Can't open display: localhost:11.0
# and the same for
export DISPLAY=<myPCsIP>:11.0
export DISPLAY=<myPCsIP>:1.0
export DISPLAY=<myPCsIP>:1
export DISPLAY=<myPCsIP>:11
# I also tried sshing with -Y vs -X, and xhost +

编辑:根据 Kenster 的说法,答案是, export DISPLAY=:2 在 ssh 进入远程系统之前,或 Xephyr 正在运行的任何系统上。然后在远程系统上设置 DISPLAY 就好了。

我搜索和阅读了相当多的内容,但似乎被许多其他问题的答案淹没了,这些问题只是这个问题的一部分,而不是整个问题。例如,我发现了大量关于启用 x11 转发的文章;但这已经完成并且有效……只是不在 :1 显示器上。搜索转发多个显示器会找到很多关于通过多个连接转发的文章。等等。

有什么想法吗?我希望这个问题和它的最终答案对其他人有教育意义,我会尽力记录下来。

根据要求,以下是带有 -vv 的日志文件。它们已清理。“笔记本电脑”是我的本地 PC,“服务器”是远程(本地网络)机器,它是运行 Ubuntu 20.04 的 jetson nano。这些用户名不是真实的。“剪辑”中无关的内容已被删除。

请注意,我的配置略有变化,因为我意识到我需要这个才能在插入两个物理显示器的情况下工作,所以我有一个本地 :0 和 :1 显示器,而 Xephyr 现在在 :2 上运行(好像它是第三个显示器)。有趣的是,我似乎有 :1 的 xauth 条目,但仍然无法连接到它。

jamesn@laptop:~$ ssh -X -vv jetson@server
OpenSSH_8.2p1 Ubuntu-4ubuntu0.7, OpenSSL 1.1.1f  31 Mar 2020


snip


debug1: Next authentication method: password
jetson@server's password: 
debug2: we sent a password packet, wait for reply
debug1: Authentication succeeded (password).
Authenticated to server ([server]:22).
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: pledge: exec
debug1: client_input_global_request: rtype [email protected] want_reply 0
debug2: channel_input_open_confirmation: channel 0: callback start
debug2: x11_get_proto: /usr/bin/xauth  list :1 2>/dev/null
debug1: Requesting X11 forwarding with authentication spoofing.
debug2: channel 0: request x11-req confirm 1
debug2: fd 3 setting TCP_NODELAY
debug2: client_session2_setup: id 0
debug2: channel 0: request pty-req confirm 1
debug1: Sending environment.
debug1: Sending env LANG = en_CA.UTF-8
debug2: channel 0: request env confirm 0
debug2: channel 0: request shell confirm 1
debug2: channel_input_open_confirmation: channel 0: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel_input_status_confirm: type 99 id 0
debug2: X11 forwarding request accepted on channel 0
debug2: channel_input_status_confirm: type 99 id 0
debug2: PTY allocation request accepted on channel 0
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 4.9.253-tegra aarch64)

snip

Last login: Tue Jun 13 20:35:21 2023 from 192.168.0.170
debug1: client_input_channel_open: ctype x11 rchan 3 win 65536 max 16384
debug1: client_request_x11: request from 127.0.0.1 33894
debug2: fd 7 setting O_NONBLOCK
debug1: channel 1: new [x11]
debug1: confirm x11
debug2: channel 1: rcvd adjust 40228
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 38112
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 49152
debug2: channel 1: rcvd adjust 49152
X Error of failed request:  BadLength (poly request too large or internal Xlib length error)
  Major opcode of failed request:  156 (NV-GLX)
  Minor opcode of failed request:  1 ()
debug2: channel 1: rcvd eof
debug2: channel 1: output open -> drain
debug2: channel 1: obuf empty
debug2: channel 1: chan_shutdown_write (i0 o1 sock 7 wfd 7 efd -1 [closed])
debug2: channel 1: output drain -> closed
debug1: channel 1: FORCE input drain
debug2: channel 1: ibuf empty
debug2: channel 1: send eof
debug2: channel 1: input drain -> closed
debug2: channel 1: send close
  Serial number of failed request:  19
  Current serial number in output stream:  19
debug2: channel 1: rcvd close
debug2: channel 1: is dead
debug2: channel 1: garbage collecting
debug1: channel 1: free: x11, nchannels 2
jetson@nano:~$ echo $DISPLAY
localhost:10.0
jetson@nano:~$ xeyes
debug1: client_input_channel_open: ctype x11 rchan 3 win 65536 max 16384
debug1: client_request_x11: request from 127.0.0.1 33896
debug2: fd 7 setting O_NONBLOCK
debug1: channel 1: new [x11]
debug1: confirm x11
debug2: channel 1: rcvd eof
debug2: channel 1: output open -> drain
debug2: channel 1: obuf empty
debug2: channel 1: chan_shutdown_write (i0 o1 sock 7 wfd 7 efd -1 [closed])
debug2: channel 1: output drain -> closed
debug1: channel 1: FORCE input drain
debug2: channel 1: ibuf empty
debug2: channel 1: send eof
debug2: channel 1: input drain -> closed
debug2: channel 1: send close
^C
jetson@nano:~$ debug2: channel 1: rcvd close
debug2: channel 1: is dead
debug2: channel 1: garbage collecting
debug1: channel 1: free: x11, nchannels 2

jetson@nano:~$ export DISPLAY=localhost:11.0
jetson@nano:~$ xeyes
Error: Can't open display: localhost:11.0
jetson@nano:~$ export DISPLAY=localhost:12.0
jetson@nano:~$ xeyes
Error: Can't open display: localhost:12.0

答案1

如果您希望 ssh 将 X 应用程序转发到您的 Xephyr 显示器,则在运行 ssh 时将本地系统上的 DISPLAY 环境设置为 Xephyr 显示器的值:

DISPLAY=:2 ssh -X user@remote ...

在远程系统上,如果 ssh 会话正在转发 X,则远程会话将具有由处理会话的 SSH 服务器设置的 DISPLAY 变量值。除非您故意想要使用某些东西,否则不需要更改远程系统上的 DISPLAY其他比该会话转发的显示更多。

如果您想将某些应用程序转发到一个显示器,而将其他应用程序转发到另一个显示器,您可以运行两次 ssh:

DISPLAY=:0 ssh -X ...
DISPLAY=:2 ssh -X ...

在此特定情况下,远程系统上的两个会话将具有不同的 DISPLAY 值,例如“localhost:10.0”和“localhost:11.0”。每个 DISPLAY 值在相应的 ssh 会话运行时均有效。

那么,这里到底发生了什么?从历史上看,X 客户端(应用程序)通过 TCP 连接到 X 服务器。X 的默认 TCP 端口是端口 6000,而 DISPLAY 值(如“:0”或“:0.0”)表示本地系统上的端口 6000(6000 + 0)。显示“somehost:1.0”表示主机“somehost”上的端口 6001(6000 + 1)。

当您运行该ssh实用程序时——特别是OpenSSH版本,这是几乎每个人都使用的版本——并请求 X 转发,ssh将 X 转发到其 DISPLAY 变量指定的 X 服务器。DISPLAY 每次只能有一个值,因此ssh每次调用只能转发到一个特定的 X 服务器。

在服务器上,SSH 服务器进程将分配一个 TCP 端口,作为会话的“假”X 服务器。它通常从端口 6010 开始,然后是 6011 等等,直到找到一个空闲端口。一旦它确定了端口,它就会监听到该端口的连接,并通过 SSH 连接将它们转发到客户端。

如果 SSH 服务器进程还启动命令或终端会话,它将把该会话的 DISPLAY 环境变量设置为它设置的“假”X 服务器的正确值。此 DISPLAY 值可能是“localhost:10.0”或类似的值。DISPLAY 中的数字取决于分配的实际 TCP 端口 - 10 表示 6010(6000 + 10)。“localhost”表示连接到应用程序正在运行的系统。

答案2

据我所知,SSH X11 转发需要 Xauthority 数据存在,即使正常情况下不需要它(即即使使用主机身份验证)。使用xauth添加 MIT-MAGIC-COOKIE-1 条目以:1显示到客户端 ~/.Xauthority 文件和 Xephyr 的-serverauth文件(可能为同一个文件)。

答案3

根据@Kenster的说法,答案是在 ssh 进入远程系统之前导出 DISPLAY=:2 或 Xephyr 正在运行的任何内容。然后就可以在远程系统上设置 DISPLAY 了。

@Kenster,如果你发布这个答案的你自己的副本,我会很乐意将功劳转给它。

相关内容