很早之前我就曾写过关于 X11 转发的内容(e.g., Mininet + RYU SDN 开发环境搭建 - Nativus' Space (naiv.fun),但并没有做总结,不是很通用,因此重新再这里重新整理一下 X11 转发相关内容。(水博客)
为了能够让无头(headless) 的远程 Linux 主机显示 Wireshark、Oracle Database Installer 等具有 GUI 的程序,可采用 X11 转发的方式,在本地上显示程序的图像。
X Window System
什么是 X11
要想使用 X11 转发,首先要了解 X Window。X Window System (简写为 X11) 是一种用于位图显示的窗口系统,在类 UNIX 操作系统非常常见。
X11 为 GUI 环境提供了基本的框架,包括在屏幕上绘制和移动图像、监听鼠标键盘的操作等功能。同时 X11 自由度比较高,同样是采用 X11 方案的软件可能外观上有很大差异。
X11 是经典的 C/S 架构,分为 Server 和 Client,并定义了一系列协议用于 C-S 间通信。X Server 负责图形界面的显示和用户的输入,而 X Client 需要连接到 X Server,请求 X Server 绘制图形界面,同时从 X Server 接受用户的输入并做出响应。
在带有桌面环境的系统上,X Server 和 X Client 安装在同一台机器上,但是 X Server 和 X Client 显然可以分别运行在不同的机器上,从而实现在一台机器上运行程序,而在另外一台机器上显示图形界面。
X Server 和 X Client 分不清?
事实上,X Server 就像一个画布,Linux 上的 X Client 就像一个画家。Server 同显示器等硬件打交道,为画家(Client)提供绘图的必要服务。画家处理数据并对用户的做出响应,在画布上展示出来。(参见鸟哥的Linux私房菜)
举个实际的例子:假设此时你正在用一台 Windows 主机通过 SSH 连接到另一台 Linux 主机,要在 Linux 上运行 Wireshark 并把图像显示在 Windows 上,那么 X Server 在 Windows 上,X Client 在 Linux 上。
看上去这有点违反直觉。不过只要记住:在哪里看到画面,哪里就有 X Server。
X11 转发
X11 转发就是使用 SSH 转发 X11 的流量。
正如上文提到的,X Server 可以接受 X Client 的连接并显示出画面,那么如果 X Server 能够被随意连接就出大乱子了。所以很多时候 X Server 是具有认证的,将 X11 的流量暴露在公网上传输也是具有很大风险的。
这时 SSH 的作用就很明显了,SSH 相当于一个隧道,X11流量在其中是加密的,安全性大大提升。同时 SSH 会在远程的 Linux 主机上设置端口转发,这一点后面在操作部分会提到。
操作步骤
X Window System 有多种实现,在 Windows 平台上,常用的 X Server 软件是vcxsrv。也有一些终端软件,内部集成了 X Server(例如 MobaXterm)。
vcxsrv
- 在 Windows 上安装 vcxsrv;
- 在 Linux 上安装必要的软件包。例如:xorg-x11-xauth(用于 X11 的认证),和 xclock(用于测试 X11 转发是否生效)。
修改 Linux 主机上的 sshd 参数使之开启 X11 转发;
打开/etc/ssh/sshd_config
确保:X11Forwarding yes
重启 sshd 服务。
- 打开本地(Windows)上的 XLaunch,启动一个 X Server。记住启动完成后右下角状态栏图标上显示的名称。例如:
Leo-Laptop:0.0
。 SSH 连接主机(Linux),并启用 X11 转发。
ssh -X username@host
在主机上查看
$DISPLAY
变量指定转发到的客户端,若未设置则需要手动输入变量的值:export DISPLAY="Server Name"
其中 “Server Name” 是第 3 步中启动的 X Server 的名称,例如
Leo-Laptop:0.0
。启动服务,以 Wireshark 为例:
sudo -E wireshark &
或:
sudo HOME=~ wireshark &
其中:
&
代表在后台执行该命令,不必等待程序退出;-E
使得sudo
指令继承当前用户的环境变量;HOME=~
使得sudo
执行时设置HOME
变量为~
(当前用户的家目录)。之所以要这样做,是因为以 root 身份执行 Wireshark 时,Wireshark 会尝试访问 root 用户的家目录,而 X11 Forwarding 时并没有权限访问 root 的家目录,所以需要我们指定家目录为当前用户的家目录,避免出现权限不足运行出错。
MobaXterm
- 安装 MobaXterm 后,确保主页面右上角的 X 图标为彩色(意为已经启动 X Server)。
- 连接到服务器后, 检查 X11 转发标志是否为对勾。
如果不是对勾:
- 首先检查
/etc/ssh/sshd_config
中X11Forwarding
选项是否为 yes(参见上一节)。 - 然后检查是否已经安装 xauth 包,方法是运行
xauth
命令,看是否有结果。 - 其次检查
$DISPLAY
是否已经被设置,如果没有被设置可以尝试自行设置。需要注意的是,默认情况下DISPLAY=localhost:10.0
就表明通过 X11 转发到远程主机显示。
- 首先检查
常见问题
- 如果需要测试,那么可以尝试安装并运行 xclock,如果 Windows 上出现了一个时钟窗口,则表示转发成功。
- 关于 SSH 转发 X11,详细的日志可以通过使用
ssh -Xv
命令查看(-v
:verbose)。 - 如果登录远程的 Linux 后,需要切换用户(例如使用
su - username
),那么需要将一开始登陆用户家目录下.Xauthority
拷贝到要切换用户的家目录下,同时设置好权限和拥有者。设置完成后,可以在新的用户下运行 xauth,然后输入 list 命令查看已经具备权限的设备。然后再把$DISPLAY
变量设置成正确的值。
(出现该问题的原因是 SSH 只帮刚开始登录的用户设置了 .Xauthority 和恰当的环境变量。)