「Mac&Linux」一次基于X和蒲公英组网的远程桌面尝试
因为某些原因我必须在远程条件下使用带图形环境的Ubuntu工作。虽然说有向日葵和ToDesk这种远程控制工具,但是后者经常莫名其妙蹦个错误告诉我连不上网络(指的是Mac上的这个软件连不到它公司自己的网络,连我这个账号在ToDesk上有哪些在线设备都不知道),前者怎么说呢... 我已经受够远程桌面那模糊的画质和时长时短的操作时延了!
我打算试试用VNC或X这种远程窗口方案。
ssh登录
网络拓扑是这样的:
(Macbook笔记本) —— (Windows笔记本) —— (Ubuntu 22.04 虚拟机)
其中Ubuntu是Windows上基于VMware运行的虚拟机,而且Macbook和Windows分别在两个大内网里,没法直连,这里采用贝锐蒲公英提供的远程组网方案(内网穿透好帮手),分别在Macbook和Windows上安装并运行蒲公英,具体的教程就不需要展示了。
为了描述方便,下面Macbook简称Mac,Windows简称Win,Ubuntu简称VM。
总之,通过蒲公英两边都得到了一个虚拟局域网的IP,暂定为Mac得到了172.111.1.14而Win是172.111.1.15。同时Win和VM处于同一个由VMware构成的虚拟网络中,在这个网络中假定Win是192.168.168.1,VM是192.168.168.136。通过实验可以确认Mac和Win、Mac和Ubuntu、Win和VM都是具有网络可达性的(可以互Ping成功),说明蒲公英组网之后可以正确地修改路由表,使得虚拟局域网中的Mac和虚拟局域网外的VM都能互相发现。
好,抽象的事情要来了。我们先试试能不能从Mac用ssh连接VM:(所有涉及用户名的地方都用gua代替)
~/ $ ssh gua@192.168.168.136
kex_exchange_identification: read: Connection reset by peer
Connection reset by 192.168.168.136 port 22
我的第一个想法是:莫非VM设置出了问题,不允许连接?挨个排查:
- Mac和Win之间的网络可达性:互Ping有应答,没问题
- Win和VM之间的网络可达性:互Ping有应答,没问题
- Mac和VM之间的网络可达性:互Ping有应答,没问题
- VM自身的sshd网络设置:从Win用ssh登录VM成功,没问题
- 蒲公英链路不允许ssh:从Mac用ssh登录Win成功,不太像是主动的限制
- Win本身对ssh链路的影响:从Mac用ssh把Win作为跳板登录VM成功,不太像是Win的锅
显然,我觉得各个环节都不太可能有问题,除非:蒲公英虚拟组网本身有缺陷,或者Win作为网络节点会对ssh链路产生影响。
考虑到蒲公英之前在Linux上的服务端做得实在是太烂了,我倾向于是前者。
那么,现在就只能用这种指令访问了。
~/ $ ssh -J gua@172.111.1.15 gua@192.168.168.136
然后它成功了,难评蒲公英。
设置X远端显示
X是一套历史悠久的视窗显示体系,现在主流的版本号是11,因此也叫X11。在X11里面:
- X Server是提供显示资源的一端,即提供显示器、键鼠输入信号的一端。
- X Client是需要显示资源的一端,通常指的是应用程序,因为是应用程序有显示画面、接受输入信号的需求。
- X Protocol是所用的X协议,体系里有这么个概念,但是我们在此不用倾注过多关注。
在一般的使用场景里,通常是用户需要让远端服务主机上的应用程序(远端主机通常配置很强性能更好,因此跑计算任务都在远端主机上)在本地主机上显示画面(在本地主机上绘制Python跑出来的曲线图之类的)。在这个场景中,远端主机上输出画面的应用程序是X Client,而本地主机则需要运行X Server。
这里Mac上运行X Server,接收来自VM上的X Client们的画面信号。
选择合适的X Server程序
带有X Server的程序有很多,在Windows上有MobaXterm(内置X Server)和PuTTY、VcXsrv(用X Launch启动)等。其中以VcXsrv最为经典,可以设置X Server所使用的Display号和Screen号。由于我是在Mac上运行X Server,这里用的是XQuartz。
有个小坑点,这里如果用 brew install --cask XQuartz
如果网络变化的话会安装一个残缺的XQuartz,而你重新用 brew
安装并不会告诉你有什么异常,也不会重新给你装好,因此建议去官网下载 .pkg 包进行安装。
在X体系里,最重要的环境变量是 $DISPLAY
,这个变量决定了X应用程序会往哪个方向建立X连接。在我们所要进行的整个过程中,你都没有任何必要手动修改这个变量。这是因为:XQuartz会自动修改你在Mac上的 $DISPLAY
;而如果你使用 ssh -Y
连接远端主机, ssh
会自动帮你修改远端主机上的 $DISPLAY
数值。
# 在Mac上,当你从Launch Pad直接运行完XQuartz,会得到...
~/ $ echo $DISPLAY
/private/tmp/com.apple.launchd.57Nwhjt3kp/org.xquartz:0
# 得到形如上一行的文本
# 在远端主机上,当你直接使用ssh连接而不配置任何X转发选项时,会得到...
~/ $ echo $DISPLAY
# 得到空白,说明没有设置
# 在远端主机上,当你使用 ssh -Y 连接时,会得到...
~/ $ echo $DISPLAY
localhost:10.0
# 得到这个,说明ssh -Y主动设置了DISPLAY变量
# 当你用VMware直接在有图形界面的Ubuntu里运行终端时,会得到...
~/ $ echo $DISPLAY
:0
# 得到这个,这是因为用了默认的本地显示器,在本地进行显示
当X Server所在的本地主机和X Client所在的远端主机的 $DISPLAY
变量都被正确设置时,X方面就没什么太大的问题了。
Mac:使用X Quartz实现远程窗口
Mac上的X Quartz的使用具有比较鲜明的特色。怎么说呢... 用起来感觉像“访达”。XQuartz自己是一个程序,而远端的X Client所产生的窗口则是属于这个程序的子窗口。
使用X Quartz在Mac上实现远端窗口的基本步骤如下:
- 启动XQuartz,它应该在“应用程序” -> “其他”或者“实用工具” 里。如果XQuartz很快就退出了,建议重装一个。
- 在XQuartz中启动终端
- 在终端中使用
ssh -Y gua@192.168.168.136
连接所需要的远端主机 - 在终端中执行需要X Server的命令,这时候就会在你的本地主机创建窗口了
值得注意的是,其中的 ssh -Y
在man手册中被指出是 “Trusted”。我一开始以为是通过 -Y
的话要额外经过身份验证之类的,后来细究了一下发现 -Y
类似裸奔模式: -X
只允许部分X Client的操作,而 -Y
则没有这种限制。因此比较正经的教程通常会告诉你应该多用 -X
避免安全问题,而网上的文章通常都会建议你用 -Y
避免在奇怪的地方被莫名其妙地拦住。
这样的步骤只是让读者快速了解实现远端窗口的全部流程,细究起来还是有很多问题,比如:
- XQuartz的终端非常难看,不能正确地显示我的Powerline字体。
- 在
.ssh/config
中为目标主机配置快捷启动和ForwardX11Trusted yes
好像没有起到和-Y
一样的用处,有待研究。
此外,这样做的延时是比较恐怖的。虽然绘制的效果不错,但是上面那个示意图中xeyes对鼠标的跟踪效果的延时高达800ms;我通过终端启动QtCreator之后,有关操作的延时可以高达13.92s。这样的延时多少有点不可接受了。
有机会再做个对比实验,看看网络链路在其中的影响有多大。