TigerVNC

来自 ArchWiki
(重定向自 Tightvnc)

TigerVNC 是虚拟网络计算 (VNC) 协议的实现。本文重点介绍服务器功能。

安装

Install tigervnc 软件包。

运行 vncserver 以进行虚拟(无头)会话

初始设置

注意:Linux 系统可以拥有尽可能多的 VNC 服务器,只要内存允许,所有服务器都将彼此并行运行。

为了快速开始,请参阅以下步骤。 建议用户阅读 vncserver(8) 以获取完整的配置选项列表。

  1. 使用 vncpasswd 创建密码,它会将哈希密码存储在 $XDG_CONFIG_HOME/tigervnc/passwd 中。 确保文件权限设置为 0600。 如果为另一个用户创建 vncserver 访问权限,则必须先以该用户身份登录,然后再运行 vncpasswd。
  2. 编辑 /etc/tigervnc/vncserver.users 以定义用户映射。 此文件中定义的每个用户都将有一个对应的端口,其会话将在该端口上运行。 文件中的数字对应于 TCP 端口。 默认情况下,:1 是 TCP 端口 5901 (5900+1)。 如果需要另一个并行服务器,则第二个实例可以在下一个最高的空闲端口上运行,即 5902 (5900+2)。
  3. 创建 $XDG_CONFIG_HOME/tigervnc/config,并且至少使用 session=foo 这样的行定义所需的会话类型,其中 foo 对应于要运行的桌面环境。 可以通过查看 /usr/share/xsessions/ 中相应的 .desktop 文件来查看系统上可用的桌面环境。 例如
$XDG_CONFIG_HOME/tigervnc/config
session=lxqt
geometry=1920x1080
localhost
alwaysshared
注意:前一步骤需要额外的安全设置才能完全工作; 请参阅 #通过 SSH 隧道访问 vncserver 以完成设置。 为了测试目的,请省略此步骤以允许来自 localhost 外部的不安全连接。

启动和停止 tigervnc

启动 vncserver@.service 模板的一个实例,并可选择 启用 它以在启动/关闭时运行。 请注意,在这种情况下,实例标识符是显示编号(例如,显示编号 :1 的实例 vncserver@:1.service)。

注意
  • 不支持直接调用 /usr/bin/vncserver,因为它们不会建立适当的会话范围。 systemd 服务是使用 TigerVNC 的唯一受支持方法。 请参阅:Issue #1096
  • 在启动 vncserver 之前,删除为早期版本的 TigerVNC 创建的 drop-in 服务文件。 早期版本需要为每个显示器提供 drop-in 服务文件,例如,对于显示器 :1 /etc/systemd/system/vncserver@:1.service。 如果在使用新的模板化服务文件启动时,旧的 drop-in 文件仍然存在,则 vncserver 将无法启动。

直接暴露本地显示

TigerVNC 包含 libvnc.so,可以在 X 初始化期间无缝加载它,以提高性能。 要使用此功能,请创建以下文件,然后重新启动 X

/etc/X11/xorg.conf.d/10-vnc.conf
Section "Module"
Load "vnc"
EndSection

Section "Screen"
Identifier "Screen0"
Option "UserPasswdVerifier" "VncAuth"
Option "PasswordFile" "/root/.vnc/passwd"
EndSection

运行 x0vncserver 以直接控制本地显示

tigervnc 还提供了 x0vncserver(1),它允许直接控制物理 X 会话。 使用 vncpasswd 工具定义会话密码后,像这样调用服务器

$ x0vncserver -rfbauth $XDG_CONFIG_HOME/tigervnc/passwd
注意
  • x11vnc 是另一种 VNC 服务器,它也可以直接控制当前的 X 会话。
  • x0vncserver 当前不支持客户端和服务器之间的剪贴板共享(即使在 autocutsel 的帮助下)。 请参阅:Issue #529

使用 xprofile

启动 x0vncserver 的一种简单方法是在 xprofile 文件之一中添加一行,例如

~/.xprofile
...
x0vncserver -rfbauth $XDG_CONFIG_HOME/tigervnc/passwd &

使用 systemd

使用系统服务

此选项将允许用户访问当前显示,包括显示管理器提供的登录屏幕。

每次用户注销会话时,该服务都会自动重新启动。

以下示例使用了 LightDM,但是通过修改 XAUTHORITY 变量,应该可以将其适配到其他显示管理器。

/etc/systemd/system/x0vncserver.service
[Unit]
Description=Remote desktop service (VNC) for :0 display
Requires=display-manager.service
After=network-online.target
After=display-manager.service

[Service]
Type=simple
Environment=HOME=/root
Environment=XAUTHORITY=/var/run/lightdm/root/:0
ExecStart=x0vncserver -display :0 -rfbauth $XDG_CONFIG_HOME/tigervnc/passwd
Restart=on-failure
RestartSec=500ms

[Install]
WantedBy=multi-user.target

由于这是一个系统单元,-rfbauth $XDG_CONFIG_HOME/tigervnc/passwd 指的是 /root/.vnc/passwd

启动/启用 x0vncserver.service

使用用户服务

为了拥有运行 x0vncserver 的 VNC 服务器,这是大多数用户快速远程访问当前桌面的最简单方法,请创建如下 systemd 单元,并将用户和选项替换为所需的选项

~/.config/systemd/user/x0vncserver.service
[Unit]
Description=Remote desktop service (VNC)

[Service]
Type=simple
ExecStartPre=/bin/sh -c 'while ! pgrep -U "$USER" Xorg; do sleep 2; done'
ExecStart=/usr/bin/x0vncserver -rfbauth %h/.vnc/passwd

[Install]
WantedBy=default.target

ExecStartPre 行等待 Xorg 由 ${USER} 启动。

要使用特定的用户名和密码登录,请将 ExecStart 替换为 /usr/bin/x0vncserver -PAMService=login -PlainUsers=${USER} -SecurityTypes=TLSPlain

启动/启用 x0vncserver.service 用户单元

运行 Xvnc 与 XDMCP 以按需会话

可以结合使用 systemd 套接字激活和 XDMCP,为每个尝试登录的用户自动生成 VNC 服务器,因此无需为每个用户设置一个服务器/端口。 此设置使用显示管理器来验证用户身份和登录,因此无需 VNC 密码。 缺点是用户无法在服务器上保持会话运行并在以后重新连接。

要使其运行,首先设置 XDMCP 并确保显示管理器正在运行。 然后创建

/etc/systemd/system/xvnc.socket
[Unit]
Description=XVNC Server

[Socket]
ListenStream=5900
Accept=yes

[Install]
WantedBy=sockets.target
/etc/systemd/system/xvnc@.service
[Unit]
Description=XVNC Per-Connection Daemon

[Service]
ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1920x1080 -once -SecurityTypes=None
User=nobody
StandardInput=socket
StandardError=syslog

启动/启用 xvnc.socket。 现在,任意数量的用户都可以通过连接到端口 5900 来获得唯一的桌面。

如果 VNC 服务器暴露在互联网上,请在 xvnc@.service 中的 Xvnc 中添加 -localhost 选项(请注意 -query localhost-localhost 是不同的开关),并按照 #通过 SSH 隧道访问 vncserver 进行操作。 由于我们仅在连接后选择用户,因此 VNC 服务器以用户 nobody 身份运行,并直接使用 Xvnc 而不是 vncserver 脚本,因此 $XDG_CONFIG_HOME/tigervnc 中的任何选项都将被忽略。 可选地,自动启动 vncconfig 以使剪贴板工作(vncconfig 在非 VNC 会话中立即退出)。 一种方法是创建

/etc/X11/xinit/xinitrc.d/99-vncconfig.sh
#!/bin/sh
vncconfig -nowin &

连接到 vncserver

警告:默认的 TigerVNC 安全方法不安全。 它缺少身份验证,并且在连接设置期间无法防止中间人攻击。 请注意理解服务器的安全设置,并且不要在受信任的 LAN 之外不安全地连接到 vncserver。
注意:默认情况下,TigerVNC 使用 TLSVnc 身份验证/加密方法,除非通过 SecurityTypes 参数明确指示。 使用 TLSVnc,有标准的 VNC 身份验证,并且流量使用 GNUTLS 加密,但服务器的身份未经过验证。 TigerVNC 支持替代的安全方案,例如 X509Vnc,它将标准的 VNC 身份验证与 GNUTLS 加密和服务器标识相结合; 这是安全连接的推荐模式。 当服务器上的 SecurityTypes 设置为非加密选项作为高优先级(例如 NoneVncAuthPlainTLSNoneTLSPlainX509NoneX509Plain)时,这是不明智的,那么就无法使用加密。 运行 vncviewer 时,更安全的方法是显式设置 SecurityTypes 并且不接受任何未加密的流量。 任何其他模式仅在 #通过 SSH 隧道访问 vncserver 时使用。

任意数量的客户端都可以连接到 vncserver。 下面给出一个简单的示例,其中 vncserver 在 10.1.10.2 端口 5901 上运行,或简写为 :1

$ vncviewer 10.1.10.2:1

无密码身份验证

-passwd 开关使您可以指定服务器的 $XDG_CONFIG_HOME/tigervnc/passwd 文件的位置。 预计用户可以通过 SSH 或物理访问服务器来访问此文件。 在任何一种情况下,都将文件放置在客户端文件系统中的安全位置,即只有预期用户具有读取访问权限的位置。

$ vncviewer -passwd /path/to/server-passwd-file

密码也可以直接提供。

注意:下面的密码不安全; 任何可以在机器上运行 ps 的人都会看到它。
$ vncviewer -passwd <(echo MYPASSWORD | vncpasswd -f)

GUI 客户端示例

TigerVNC 的 vncviewer 在没有任何参数的情况下运行时也具有简单的 GUI

$ vncviewer

通过 SSH 隧道访问 vncserver

对于提供 SSH 连接的服务器,此方法的优势在于无需打开除已打开的 SSH 端口之外的任何其他端口,因为 VNC 流量是通过 SSH 端口隧道传输的。

在服务器端

在服务器端,必须运行 vncserverx0vncserver

在运行其中任何一个时,建议在 $XDG_CONFIG_HOME/tigervnc/config 中使用 localhost 选项或 -localhost 开关(对于 x0vncserver),因为它只允许来自 localhost 的连接,并且类似地,只允许来自在框上 ssh 并经过身份验证的用户。 例如

$XDG_CONFIG_HOME/tigervnc/config
session=lxqt
geometry=1920x1080
localhost
alwaysshared

确保启动重启 vncserver@.service,例如(另请参阅 #初始设置

# systemctl start vncserver@:1

或对于 x0vncserver

$ x0vncserver -localhost -SecurityTypes none

在客户端

VNC 服务器已在远程计算机上设置为仅接受本地连接。 现在,客户端必须使用远程计算机(在此示例中为 10.1.10.2)打开安全 shell,并创建从客户端端口(例如 9901)到远程服务器 5901 端口的隧道。 有关此功能的更多详细信息,请参阅 OpenSSH#端口转发ssh(1)

$ ssh 10.1.10.2 -L 9901:localhost:5901

通过 SSH 连接后,保持此 shell 窗口打开,因为它充当与服务器的安全隧道。 或者,使用 -f 选项直接在后台运行 SSH。 在客户端,要通过此加密隧道连接,请将 vncviewer 指向 localhost 上的转发客户端端口。

$ vncviewer localhost:9901

实际发生的情况是 vncviewer 在本地连接到端口 9901,该端口隧道传输到服务器的 localhost 端口 5901。 连接在安全 shell 内建立到正确的端口。

提示:可以使用单行命令在连接期间保持端口转发处于活动状态,并在之后立即关闭它
$ ssh -fL 9901:localhost:5901 10.1.10.2 sleep 10; vncviewer localhost:9901

它的作用是 -f 开关将使 ssh 进入后台; 它仍然会活着执行 sleep 10。 然后执行 vncviewer,并且只要 vncviewer 使用隧道,ssh 就会在后台保持打开状态。 一旦隧道被丢弃,ssh 将关闭,这是想要的行为。

或者,vncviewer 的 -via 开关为上述命令提供了一个快捷方式

$ vncviewer -via 10.1.10.2 localhost::5901

(请注意双冒号 – vncviewer 的语法是 [host]:[display#][host]::[port]。)

通过 SSH 从 Android 设备连接到 vncserver

要使用 Android 设备作为客户端通过 SSH 连接到 VNC 服务器,请考虑进行以下设置

  1. SSH 在服务器上运行
  2. vncserver 在服务器上运行(带有 -localhost 标志以提高安全性)
  3. Android 设备上的 SSH 客户端:ConnectBot 是一个流行的选择,将在本指南中用作示例
  4. Android 设备上的 VNC 客户端:此处使用 androidVNC

ConnectBot 中,连接到所需的机器。 点击选项键,选择端口转发并添加一个端口

Type: Local
Source port: 5901
Destination: 127.0.0.1:5901

androidVNC 中,连接到 VNC 端口; 这是 SSH 连接之后的本地地址

Password: the vncserver password
Address: 127.0.0.1
Port: 5901

提示和技巧

连接到 macOS 系统

请参阅 https://help.ubuntu.com/community/AppleRemoteDesktop。 已使用 Remmina 测试。

推荐的安全设置

如果不是 #通过 SSH 隧道访问 vncserver,其中身份验证和加密通过 SSH 处理,建议使用 X509Vnc,因为 TLSVnc 缺乏身份验证。

$ vncserver -x509key /path/to/key.pem -x509cert /path/to/cert.pem -SecurityTypes X509Vnc :1

颁发 x509 证书超出了本指南的范围。 但是,Let's Encrypt 提供了一种简单的方法来做到这一点。 或者,可以使用 OpenSSL 颁发证书,与客户端共享公钥,并使用 -X509CA 参数指定它。 下面给出了一个示例,服务器在 10.1.10.2 上运行

$ vncviewer 10.1.10.2 -X509CA /path/to/cert.pem

切换全屏

这可以通过 vnc 客户端的菜单完成。 默认情况下,vnc 客户端的 mkey 是 F8

鼠标后退和前进按钮无法工作的解决方法

VNC 协议当前仅使用 7 个鼠标按钮(左、中、右、向上滚动、向下滚动、向左滚动、向右滚动),这意味着如果鼠标有后退和前进按钮,则这些按钮不可用,并且输入将被忽略。

evrouter 可用于解决此限制,方法是在单击鼠标后退/前进按钮时发送键盘按键。 可选地,服务器上可以使用 xautomationxbindkeys 中的 xte 将键盘按键映射回鼠标按钮点击(如果需要)。

使用键盘按键 XF86Back/XF86Forward 替代鼠标后退/前进按钮

如果您只需要一种在使用 Web 浏览器或文件浏览器时向后/向前导航的方法,则此方法简单且适用。

在客户端上安装 evrouterAURxautomation。 配置 evrouter,有关如何查找正确的设备名称、窗口名称、按钮名称等的说明和提示,请参阅 鼠标按钮#evrouter 和 evrouter 手册页。 示例配置

~/.evrouterrc
Window "OtherComputer:0 - TigerVNC": # Window title used as filter

# Using Shell to avoid repeating key presses (see evrouter manual)
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/275 "Shell/xte 'key XF86Back'"
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/276 "Shell/xte 'key XF86Forward'"

# Use XKey below instead if repeating keys is desired (see evrouter manual)
#"Logitech Gaming Mouse G400" "/dev/input/by-id/usb-Logitech_Gaming_Mouse_G400-event-mouse" none key/275 "XKey/XF86Back"
#"Logitech Gaming Mouse G400" "/dev/input/by-id/usb-Logitech_Gaming_Mouse_G400-event-mouse" none key/276 "XKey/XF86Forward"

在客户端上启动 evrouter。 使用上述配置,当单击鼠标上的后退按钮时,键盘按键 XF86Back 将发送到 VNC 服务器,当单击前进按钮时,将发送 XF86Forward

将键盘按键映射回服务器上的鼠标按钮点击

如果需要,可以将键盘按键映射回服务器上的鼠标按钮点击。 在这种情况下,使用客户端或服务器上永远没有的键盘按键可能是一个好主意。 在下面的示例中,键盘按键 XF86Launch8/XF86Launch9 用作鼠标按钮 8/9。

客户端上的 Evrouter 配置

~/.evrouterrc
Window "OtherComputer:0 - TigerVNC": # Window title

# Using Shell to avoid repeating key presses (see evrouter manual)
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/275 "Shell/xte 'key XF86Launch8'"
"USB mouse" "/dev/input/by-id/usb-Mouse-name-event-mouse" none key/276 "Shell/xte 'key XF86Launch9'"

在服务器上安装 xautomationxbindkeys。 配置 xbindkeys 以使用 xte 将键盘按键 XF86Launch8/XF86Launch9 映射到鼠标按钮 8/9。

~/.xbindkeysrc
"xte 'mouseclick 8'"
     XF86Launch8

"xte 'mouseclick 9'"
     XF86Launch9

启动 xbindkeys (xbindkeys -f ~/.xbindkeysrc)。 服务器现在将 XF86Launch8/XF86Launch9 映射到鼠标按钮 8/9。

故障排除

黑色矩形而不是窗口

很可能,这是由于应用程序严格要求合成 Xorg 扩展。 例如,基于 webkit 的应用程序:midori、psi-plus 等。

在这种情况下,使用如下命令重新启动 vncserver

$ vncserver -geometry ... -depth 24 :1 +extension Composite

看起来 VNC 中的 Composite 扩展仅适用于 24 位深度。

带有鼠标光标的空白黑色窗口或 xinit: 与 X 服务器的连接丢失

验证用户是否未登录到物理 X 会话,除非此选项已使用 x0vncserver 配置。 不支持单个用户的多个 X 会话,请参阅 684#issuecomment-494385395#1634

相反,当 VNC 服务器服务正在为该用户运行时,尝试登录本地 X 会话可能无法正常工作,并且在使用桌面环境时可能会卡在启动画面上。

没有鼠标光标

如果在使用 x0vncserver 时没有鼠标光标可见,请按如下方式启动 vncviewer

$ vncviewer DotWhenNoCursor=1 server

或者,将 DotWhenNoCursor=1 放入 TigerVNC 配置文件中,默认情况下该文件位于 $XDG_CONFIG_HOME/tigervnc/default.tigervnc

从远程机器复制剪贴板内容

如果从远程机器复制到本地机器不起作用,请在服务器上运行 autocutsel,如 [1] 中所述

$ autocutsel -fork

现在,按 F8 显示 VNC 菜单弹出窗口,然后选择剪贴板:本地 -> 远程选项。

没有窗口装饰 / 边框 / 标题栏 / 无法移动窗口

启动窗口管理器以修复空的 xterm 框架。 例如,在 Xfce 上,运行 xfwm4 &

桌面环境仅显示字体框

某些桌面环境可能缺少显示 ASCII 字符所需的字体。 Install ttf-dejavu

使用 xfce4 会话时 VNC 服务器立即终止

/usr/share/xsessions 下创建一个新的 .desktop 文件。 例如

/usr/share/xsessions/xfce4vnc.desktop
[Desktop Entry]
Version=1.0
Name=Xfce4vnc Session
Exec=dbus-launch startxfce4
Icon=
Type=Application
DesktopNames=XFCE4VNC

确保 Exec 键使用 dbus-launch 在新的会话总线实例上下文中启动 xfce4。 记住将 $XDG_CONFIG_HOME/tigervnc/config 中的 session 值更改为 xfce4vnc

参见