最近给一台纯命令行的 Rocky Linux 9.8(aarch64)服务器配置 VNC 远程桌面,全程 tigerVNC + Xfce,中间踩了三个非常有代表性的坑:系统时钟偏差导致 dnf 证书报错、session 配置值不生效悄悄 fallback 成 GNOME、以及 macOS 自带 VNC 客户端连不上 TigerVNC。把完整步骤和排查过程整理如下。

说明:文中所有 IP 均为 RFC1918 私有段示例(192.168.1.130),请替换为您的真实环境值;所有密码均为占位符。

环境说明

项目 状态
系统 Rocky Linux 9.8 (Blue Onyx),aarch64
初始状态 纯命令行服务器(multi-user.target),未安装任何桌面环境
防火墙 firewalld 运行中
SELinux Enforcing
VNC 方案 tigervnc-server + Xfce(轻量,适合服务器)

服务器版没有桌面,而 TigerVNC 的虚拟会话需要一个桌面环境支撑,所以要在装 VNC 的同时把 Xfce 一起装上。选 Xfce 而不是 GNOME,是因为它轻量得多,对服务器更友好。

完整安装步骤

1. 启用 EPEL 和 CRB 仓库

Xfce 的包在 EPEL 里,而 EPEL 9 的部分构建依赖在 CRB 仓库,需要一并启用:

dnf install -y epel-release
dnf config-manager --set-enabled crb
dnf repolist --enabled | grep -Ei "epel|crb"

2. 安装 Xfce 桌面组和 TigerVNC

dnf group install -y "Xfce"
dnf install -y tigervnc-server tigervnc-server-minimal
rpm -q tigervnc-server

aarch64 架构的 EPEL 同样覆盖,无需额外操作。

3. 设置 VNC 连接密码

vncpasswd -f 从 stdin 读密码并输出二进制格式到密码文件:

mkdir -p /root/.vnc
echo 'your_vnc_password_here' | vncpasswd -f > /root/.vnc/passwd
chmod 600 /root/.vnc/passwd

注意 VNC 密码超过 8 字符会被截断,只取前 8 位。

4. 配置会话(display 映射 + 会话参数)

把 :1 显示号映射给 root 用户:

echo ":1=root" >> /etc/tigervnc/vncserver.users

写入 /root/.vnc/config(用户级配置会覆盖 /etc/tigervnc/vncserver-config-defaults):

session=xfce
geometry=1920x1080
SecurityTypes=VncAuth
localhost=no

这里有个关键坑,session 的正确取值见下文踩坑记录第二节——系统默认配置里是 session=gnome,而官方文档一般让你填 xsessions 里的 Name 字段(如 Xfce Session),但实测这个值不生效,正确写法是 session=xfce。

SecurityTypes=VncAuth 是为了兼容 macOS 自带的屏幕共享客户端,原因同样见踩坑记录第三节。

5. 启动服务并设置开机自启

Rocky 9 的 TigerVNC 使用 systemd 模板单元,按 display 号实例化:

systemctl enable --now vncserver@:1
systemctl is-active vncserver@:1

:1 对应监听端口 5901(:N → 5900+N)。如果以后要给别的用户加会话,vncserver.users 里加 :2=xxx,再 systemctl enable --now vncserver@:2 即可。

6. 防火墙放行

firewall-cmd --permanent --add-port=5901/tcp
firewall-cmd --reload

也可以用预置的 --add-service=vnc-server(一次放行 5900-5902),但按端口精确放行更符合最小权限原则。

7. 验证

服务端确认监听:

ss -tlnp | grep 5901
# LISTEN 0.0.0.0:5901  users:(("Xvnc",pid=xxxx,fd=13))

确认会话进程(能同时看到 Xvnc、xinit 和 xfce4-session 才算完整):

ps -ef | grep -E "Xvnc|startxfce|xfce4-session" | grep -v grep

客户端侧先做协议握手测试,能收到 RFB 003.008 banner 说明 VNC 服务正常:

printf "" | nc -w 2 192.168.1.130 5901 | head -c 12
# RFB 003.008

踩坑记录

坑一:dnf 报 "certificate is not yet valid"(系统时钟偏差)

现象:dnf install epel-release 直接失败:

Curl error (60): SSL peer certificate or SSH remote key was not OK for
https://mirrors.rockylinux.org/mirrorlist?arch=aarch64&repo=BaseOS-9
[SSL certificate problem: certificate is not yet valid]

排查:certificate is not yet valid 十有八九是本机时钟问题。对比服务器 date 和真实时间,发现服务器时钟慢了约 19 天;timedatectl 显示 System clock synchronized: no,但 chronyc tracking 显示 chronyd 其实已经拿到了 NTP 参考源,只是偏差太大没有自动步进。

解决:手动触发一次步进校正即可:

chronyc makestep

几秒后 date 即与真实时间一致,dnf 恢复正常。

引申:这类"慢了十几二十天"的偏差如果是重启后反复出现,大概率是主板 CMOS 电池没电,顺手检查一下;也可以在 /etc/chrony.conf 里放宽 makestep 的限制(如 makestep 1.0 -1,任意时刻偏差超过 1 秒都允许步进)。

坑二:session=Xfce Session 不生效,悄悄 fallback 成 GNOME

现象:/root/.vnc/config 里按官方习惯写了 session=Xfce Session(对应 xfce.desktop 的 Name= 字段),服务正常启动,但看进程:

ps -ef | grep xinit
# xinit /etc/X11/xinit/Xsession /usr/bin/gnome-session-custom-session -- /usr/bin/Xvnc :1 ...

它启动的是 gnome-custom-session(字母序排在最前的 .desktop),而不是 startxfce4。服务不报错、端口也正常监听,连上去就是一个起不来的空 GNOME 会话,非常隐蔽。

排查:顺着 systemctl cat vncserver@:1 → /usr/libexec/vncsession-start → /usr/sbin/vncsession 挖下去,会发现 vncsession 的 session 匹配并不按 Name= 字段来;没匹配上时它就静默选列表里的第一个会话。

解决:把 session 值改成 .desktop 的会话标识(即文件名 xfce,或直接写 Exec 的 startxfce4 也能命中):

session=xfce

重启服务后进程变成 xinit /etc/X11/xinit/Xsession startxfce4 -- /usr/bin/Xvnc :1 ...,正确。

教训:改完配置后一定要用 ps -ef | grep xinit 确认实际拉起的会话,不能只看 systemctl is-active。

坑三:macOS 自带屏幕共享连不上 TigerVNC

现象:macOS 用 Finder ⌘K 连 vnc://192.168.1.130:5901,报"版本不兼容/无法连接"。

原因:Rocky 9 的 TigerVNC 默认 SecurityTypes=TLS,VncAuth,其 VeNCrypt/TLS 握手方式 macOS 自带客户端(屏幕共享.app)不支持。

解决:在 /root/.vnc/config 里显式指定走标准 RFB 密码认证:

SecurityTypes=VncAuth

macOS 即可直接连接。代价是只有密码交互加密、画面明文,在内网环境可接受;如果必须走公网,建议改用支持 TLS 的第三方客户端(如 RealVNC Viewer,或 brew install tiger-vnc 装 TigerVNC 官方 viewer,但后者依赖 XQuartz)。

macOS 连接方式

安装完成后,macOS 无需装任何客户端,三选一:

  • Finder 按 ⌘K(前往 → 连接服务器),输入 vnc://192.168.1.130:5901
  • 终端执行 open vnc://192.168.1.130:5901
  • 直接打开 /System/Library/CoreServices/屏幕共享.app

密码即步骤 3 设置的 VNC 密码。

安全加固建议

装完先做三件事:

  1. 轮换密码:如果安装过程中密码出现在 shell 历史里(比如通过 echo 'password' | vncpasswd -f),记得 history -c 或直接改掉密码;
  2. 改用 SSH 密钥登录:避免 root 密码认证暴露在公网/大内网;
  3. 收窄监听范围:如果只从固定跳板机连接,可以把 localhost=no 去掉、用 SSH 隧道(ssh -L 5901:localhost:5901 root@192.168.1.130)走加密通道,防火墙甚至可以不放行 5901。

小结

Rocky 9 配 TigerVNC 本身步骤不多:EPEL/CRB 仓库 → 装 Xfce + tigervnc-server → vncpasswd → vncserver.users 映射用户 → ~/.vnc/config 写会话参数 → systemd 启动 → 防火墙放行。真正费时间的是三个坑:

  1. 时钟偏差引发 SSL 证书报错,与 VNC 无关但会卡住第一步(chronyc makestep);
  2. session 配置值不匹配时静默 fallback,必须看进程才知道(正确值是 xfce 而非 Xfce Session);
  3. TigerVNC 默认 TLS 与 macOS 自带客户端不兼容(SecurityTypes=VncAuth)。

SELinux Enforcing 环境下 Rocky 9 官方打包的 vncserver@.service 自带策略(SELinuxContext=vnc_session_t),全程无需手动处理 SELinux,这点比老教程里 CentOS 7 时代的经验省心不少。

文章作者: emporer
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Emporer-Linux!
喜欢就支持一下吧