Windows 下的 SSH X11 Forwarding 远程桌面转发 VSCode + VcXsrv + OpenSSH

2023-12-18

TL;DR: VcXsrv + Display Number set to 10 + Disable Access Control, $Env:DISPLAY="127.0.0.1:10"; ssh -CXY -p port user@host on local, echo $DISPLAY export DISPLAY=127.0.0.1:10 on remote

最近加入了一个新的实验室,需要运行一些在Linux下运行的带图形化窗口的程序,给的服务器账户不提供sudo权限,无法安装 VNC/Moonlight 等远程桌面软件。

询问实验室其他人,其他人表示连接到服务器窗口会自动弹出来。详细询问得知其使用的软件是 mobaxterm。其原理为通过SSH转发本机的Xserver到远程,让远程程序调用本机的Xserver来显示图形界面。考虑其闭源,故寻找其开源实现。

需要解决两个问题,第一是在Windows上运行一个Xserver,第二是将这个Xserver通过ssh转发过去。

Background: X

Linux下的图形程序一般会拆分成两个部分,一个是 Xserver,一个是 Xclient。Xserver 与显卡驱动等交互,将图形显示在显示器上;Xclient 与 Xserver 通过 Unix socket 进行交互;Xclient 向 Xserver 发送图形绘制命令,实现图形显示。

一般系统上会运行一个 Xserver,每个程序都是一个 Xclient,程序运行的时候,通过读取DISPLAY 环境变量得到与哪个 Xserver 交互。

Windows 上的 Xserver

由以上原理得知,本机需要运行一个 Xserver,这里我使用了开源的 VcXsrv 实现。

安装后点击 Xlaunch 图标启动程序。

在这里需要修改两个设置,一个是向导最开始,需要设置 Display number 为一个数字,比如在这里我设置了为 10,另一个是第三步的时候需要Disable access control,这里是因为一些 windows 下 ssh 的 bug (xauth 不大好用),不是一个安全的做法,但是这里这么做了(为了能用)。

SSH 的 X11 转发

除了常见的 TCP 正/反向转发外,SSH 还提供了 X11 的转发。

其大体的流程就是在服务器上建立一个虚假的 Xserver,在远程服务器上 Xclient 连接到这个 Xserver 的流量都通过 SSH 转发到本地的 Xserver 上。故要求在本地 SSH 能够通过读取 DISPLAY 变量知道本地 Xserver 的连接信息,建立隧道,然后在远程设置 DISPLAY 变量,方便远程 Xclient 连接。

对应在实际使用上,即 SSH 会读取本机 Windows 上 DISPLAY 变量,如果是一个合法的 Xserver 的话,在连接到服务器后,SSH 会自动设置远程的 DISPLAY。这个过程可以在 SSH 连接过程中通过 ssh -v 选项看到。

以上过程会汇聚成这样一条命令:

$Env:DISPLAY="127.0.0.1:10"; ssh -CXY -p port user@host

这个命令前半部分 $Env:DISPLAY="127.0.0.1:10"; 是在 Powershell 上手动设置 DISPLAY 环境变量,供 ssh 读取和连接。后半部分的 -XY 选项是设置该连接需要 X11 转发,其中 -Y 代表,不验证 xauth(这个是 Windows 上 Xauth 和 SSH 的 bug)。-C 则代表转发的信息经过压缩,可以减少流量的使用,提升顺畅性。

让 VSCode Remote 中运行的程序也可以使用 X11 转发

这里提供了一个简单方式。首先根据上述命令在另外一个命令行窗口手动建立一个 SSH 连接,在其中通过 echo $DISPLAY 显示 DISPLAY 命令,可能会是 "localhost:10.0" 这种形式,然后在 VSCode 中手动设置这个连接串,例如 export DISPLAY="localhost:10.0"。这样在 VSCode 中运行的程序会通过单独开的命令行窗口建立的 X11 转发,将图形窗口显示在 Windows 本地。

Ref:

维护网站需要一定的开销,如果您认可这篇文章,烦请关闭广告屏蔽器浏览一下广告,谢谢!
加载中...

(。・∀・)ノ゙嗨,欢迎来到 lookas 的小站!

这里是 lookas 记录一些事情的地方,可能不时会有 lookas 的一些神奇的脑洞或是一些不靠谱的想法。

总之多来看看啦。