Skip to content

Commit 93fe04d

Browse files
committed
advanced/desktop: Vlab solution for LightDM + VNC
1 parent fc11e6b commit 93fe04d

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

docs/advanced/desktop.md

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,18 +306,24 @@ QT_IM_MODULE="fcitx"
306306
2007 年的 Compiz 的立方体效果。[By Nicofo,CC BY-SA 3.0](https://commons.wikimedia.org/wiki/Compiz#/media/File:Compiz-fusion_effects_Cube.jpg)
307307
{: .caption }
308308

309+
### 显示管理器 {#x-display-manager}
310+
311+
在 X 下,显示管理器(Display Manager,DM)负责在 X 服务器上显示登录界面,在用户登录后启动对应的桌面环境或者窗口管理器。常见的 DM 有 [GDM](https://gitlab.gnome.org/GNOME/gdm/)(GNOME Display Manager)、[SDDM](https://github.com/sddm/sddm)(Simple Desktop Display Manager,KDE 默认使用)、[LightDM](https://github.com/canonical/lightdm) 等。DM 一般作为 systemd 的服务运行,在系统启动时自动启动 X 服务器,并且显示登录界面。
312+
313+
之所以叫 Display Manager 而不是 Login Manager,是因为 DM 还管理着 X(即 "Display")——比如说,如果 X 崩溃了,DM 会重新启动 X 并且重新显示登录界面。
314+
309315
### 远程桌面访问 {#x-remote-desktop}
310316

311317
X 的网络透明性设计似乎使得远程桌面访问变得非常简单——只需要 `ssh -X` 或者 `ssh -Y` 就可以了。但是由于 X 协议本身的设计问题,这么做的性能并不好,主要原因包括:
312318

313319
1. X 协议很「啰嗦」,大量的操作都需要往返通信,这导致网络延迟会被协议放大数倍,甚至十几倍。
314320
2. 旧的 X 程序一般会调用 X 协议的接口来画线段、字体等(例如[客户端、服务端与窗口](#client-server-window)中展示的 xedit),但是绝大多数现代 UI 框架(例如 GTK、Qt)早已经不这么做了,而是直接画图给服务器。在远程环境下意味着传输大量未压缩的图像数据,网络带宽消耗大。
315321

316-
因此 X 的网络透明性几乎只适合在极低延迟的网络环境下使用。对于更常见的场景,根据需求不同,可以使用传统的 VNC/RDP 方案,本身作为 X server,支持多种网络与图形协议的 [Xpra](https://github.com/Xpra-org/xpra),针对游戏场景优化的 [Sunshine](https://github.com/LizardByte/Sunshine),或者为远程协助设计的 [RustDesk](https://rustdesk.com/) 等等。类似的远程桌面方案还有很多,可以按需选择。
322+
因此 X 的网络透明性几乎只适合在极低延迟的网络环境下使用(基于同样的理由,我们也不介绍为远程使用 DM 设计的古早协议 XDMCP)。对于更常见的场景,根据需求不同,可以使用传统的 VNC/RDP 方案,本身作为 X server,支持多种网络与图形协议的 [Xpra](https://github.com/Xpra-org/xpra),针对游戏场景优化的 [Sunshine](https://github.com/LizardByte/Sunshine),或者为远程协助设计的 [RustDesk](https://rustdesk.com/) 等等。类似的远程桌面方案还有很多,可以按需选择。
317323

318324
!!! example "SSH + VNC 的远程桌面访问方案"
319325

320-
以下介绍一种常见的远程桌面访问方案:通过 SSH 隧道访问远程主机上的 VNC 服务器。只要能够建立 SSH 连接,就可以通过这种方法获取到基本的 X 桌面环境,并且用户之间互相隔离,且不需要配置防火墙,远程桌面图像也不会经手第三方。
326+
以下介绍一种常见的远程桌面访问需求的解决方案:通过 SSH 隧道访问远程主机上的 VNC 服务器。只要能够建立 SSH 连接,就可以通过这种方法获取到基本的 X 桌面环境,并且用户之间互相隔离,且不需要配置防火墙,远程桌面图像也不会经手第三方。
321327

322328
[TigerVNC](https://github.com/TigerVNC/tigervnc) 实现了 Xvnc,安装 `tigervnc-standalone-server` 包即可。Xvnc 是一个集成了 VNC 服务器功能的 X server,可以像启动 X 一样启动 Xvnc。这里为了安全起见,我们将启动的 Xvnc 绑定到家目录下的一个 Unix socket 上,由 Unix 的文件权限管理来保证用户之间的隔离(因此不需要设置额外的 VNC 密码),并且避免将 VNC 端口暴露到网络上。启动的脚本如下(使用 [tigervncserver(1)][tigervncserver.1]):
323329

@@ -375,6 +381,73 @@ X 的网络透明性设计似乎使得远程桌面访问变得非常简单——
375381

376382
如果需要重启 VNC 服务器,直接杀死对应的进程,再重新执行 `startvnc` 即可。
377383

384+
!!! example "VNC 与 LightDM 集成"
385+
386+
以下介绍 USTC Vlab 项目在客户容器中[集成 VNC 服务器与 LightDM 的方案](https://github.com/USTC-vlab/deb/tree/master/vlab-vnc)。集成的好处是:用户在连接到 VNC 后,就能看到熟悉的 LightDM 的登录界面,可以在界面中输入密码、选择桌面环境等,而不需要预先配置好 VNC session。
387+
388+
在 [lightdm.conf](https://github.com/canonical/lightdm/blob/5f14752419fc7f0fd763013c8195dcb0099c940a/data/lightdm.conf) 中,我们可以设置让 LightDM 使用的 X 服务器,以及 LightDM 启动 greeter(实际给用户展示的图形界面)之前要运行的程序:
389+
390+
```ini title="/etc/lightdm/lightdm.conf"
391+
[Seat:*]
392+
xserver-command=/usr/local/bin/vncserver-lightdm
393+
greeter-hide-users=false
394+
greeter-setup-script=/usr/local/bin/vncserver-greeter-setup.sh
395+
```
396+
397+
```shell title="/usr/local/bin/vncserver-lightdm"
398+
#!/bin/bash
399+
# Need Bash for $PPID
400+
401+
DISPLAY=":0"
402+
LIGHTDM_PID=$PPID
403+
XVNC_PID=0
404+
405+
kill_vnc() {
406+
kill -s SIGTERM $XVNC_PID
407+
wait
408+
}
409+
410+
if [ $# -gt 0 ]; then
411+
DISPLAY="$1"
412+
fi
413+
414+
AUTHORITY="/var/run/lightdm/root/$DISPLAY"
415+
416+
Xvnc "$DISPLAY" -rfbport 5900 -seat seat0 -SecurityTypes None -auth "$AUTHORITY" -SendPrimary=0 &
417+
418+
XVNC_PID=$!
419+
trap kill_vnc SIGTERM
420+
421+
sleep 2
422+
kill -s SIGUSR1 $LIGHTDM_PID
423+
424+
wait
425+
exit 0
426+
```
427+
428+
!!! danger "安全性注意事项"
429+
430+
在这里,VNC 服务没有安全性校验。在 Vlab 中,所有用户对 VNC 的访问都必须经过我们自己编写的 VNC 网关,并且用户之间的 VNC 端口由防火墙阻止互相访问,因此这种设计是安全的。如果你在其他场景使用,请务必注意安全性问题,**特别是需要暴露端口到公网的情况**。互联网中存在大量自动化扫描空密码、弱密码的 bot。如果你不注意安全,那么之后你就可能会看到自己的 VNC 的桌面被其他人分享在某些社交媒体上,然后发现自己的桌面被陌生人入侵操控。
431+
432+
VNC 传统的密码模式 `VncAuth` 是不安全的——它的密码明文传输,并且密码长度最多只有 8 个字节,因此不建议使用。建议至少使用 `TLSVnc`,或者使用 SSH 隧道等方式保护 VNC 连接。
433+
434+
!!! note "为什么要给 LightDM 发送 SIGUSR1?"
435+
436+
这一点在 [xserver(1)][xserver.1] 手册页中有说明:当 X 服务器发现自己从父进程继承的 SIGUSR1 信号的 handler 是 `SIG_IGN`(忽略信号)时,就会在启动完成之后向它的父进程发送 SIGUSR1 信号。DM 可以利用这个机制来等待 X 服务器启动完成。
437+
438+
这里的 shell 脚本用了相对粗糙的 `sleep 2` 来等待 X 服务器启动完成,然后以 X 服务器的这一套信号协议来通知 LightDM。
439+
440+
```shell title="/usr/local/bin/vncserver-greeter-setup.sh"
441+
#!/bin/sh
442+
vncconfig -nowin &
443+
```
444+
445+
!!! note "vncconfig 的作用"
446+
447+
[vncconfig(1)][vncconfig.1] 是 TigerVNC 提供的一个小工具,负责处理剪贴板同步等功能。如果不运行它,那么 VNC 客户端与服务器之间的剪贴板将无法同步。
448+
449+
之后 LightDM 在启动时,就会启动 Xvnc,在 5900 端口上监听 VNC 连接。
450+
378451
## Wayland
379452

380453
## 音频服务器

includes/man.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
[rsync.1]: https://man7.org/linux/man-pages/man1/rsync.1.html
1616
[systemd-run.1]: https://www.freedesktop.org/software/systemd/man/latest/systemd-run.html
1717
[tigervncserver.1]: https://manpages.debian.org/unstable/tigervnc-standalone-server/tigervncserver.1.en.html
18+
[vncconfig.1]: https://linux.die.net/man/1/vncconfig
19+
[xserver.1]: https://linux.die.net/man/1/xserver
1820

1921
<!-- man 2 -->
2022

0 commit comments

Comments
 (0)