在本地网络上,我有一个远程(无头)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,如果你发布这个答案的你自己的副本,我会很乐意将功劳转给它。