Red Hat 8.3 安装 VNC 详细教程:TigerVNC Server 从安装到安全加固

服务器装在机房里,出了图形界面的问题总不能每次都跑现场。VNC 就是解决这个问题的:远程桌面协议,装上之后在办公室就能操作服务器的图形界面,装软件、调配置、看报错都和坐在机器前一样。这篇讲在 Red Hat Enterprise Linux 8.3 上从零搭建 TigerVNC Server:桌面环境安装、服务配置、防火墙与 SELinux、SSH 隧道加密、多用户多显示器、故障排查,一套流程下来,今天装上,今天就能用。

说明:本文以 RHEL 8.3(2020 年 11 月发布)为准,步骤同样适用于 RHEL 8.x 其他小版本。RHEL 8.3 是较旧的小版本,如果条件允许,建议先升级到受支持的版本再部署生产服务。

一、前置条件:订阅、网络、桌面环境

动手之前先确认三件事,缺一个后面都会卡住。

# 1. 确认系统版本
cat /etc/redhat-release
# Red Hat Enterprise Linux release 8.3 (Ootpa)
uname -r

# 2. 确认订阅已注册(RHEL 装软件包需要有效订阅)
subscription-manager status
dnf repolist

# 3. 确认网络能访问红帽 CDN(cdn.redhat.com)
curl -sI --max-time 10 https://cdn.redhat.com/ | head -1
  • 订阅:RHEL 的软件包在 AppStream 和 BaseOS 仓库里,没有有效订阅 dnf install 会报仓库不可用。注册订阅:subscription-manager register --username <账号> --auto-attach,注册后用 dnf repolist 确认 rhel-8-for-x86_64-appstream-rpms 和 baseos 两个仓库都启用了。
  • 网络:内网环境要确认 yum 源可用,可以是红帽 CDN,也可以是内部镜像源。内网镜像源要配好 /etc/yum.repos.d/ 下的 repo 文件。
  • 桌面环境:VNC 要起图形界面,最小化安装的系统没有桌面环境,先装 GNOME(见第二节)。

二、安装桌面环境(Server with GUI)

最小化安装的 RHEL 8.3 只有命令行,没有图形界面。VNC 要显示桌面,得先装 GNOME。Server with GUI 是红帽官方的图形化服务器环境组,包含 GNOME 桌面和常用的图形管理工具。

# 查看可用的环境组
dnf group list

# 安装 Server with GUI(包含 GNOME 桌面)
dnf groupinstall "Server with GUI"

# 设为图形启动(开机进图形界面)
systemctl set-default graphical.target

# 确认当前启动目标
systemctl get-default
# graphical.target

装完先别急着重启,继续装 VNC,一次性配好再重启验证。如果这台机器只做 VNC 远程桌面、不需要本地显示器出画面,也可以不改默认启动目标,VNC 服务自己会起虚拟显示器,不依赖本地图形界面。

三、安装 TigerVNC Server

RHEL 8 的 VNC 服务器是 TigerVNC,包名 tigervnc-server,在 AppStream 仓库里。TigerVNC 是目前维护最活跃的 VNC 实现,性能和兼容性都比老旧的 TightVNC 好。

# 安装 TigerVNC 服务器
dnf install -y tigervnc-server

# 确认安装的版本和文件
rpm -qi tigervnc-server
rpm -ql tigervnc-server | grep -E "vncserver|systemd" | head

# 常用命令
which vncserver vncpasswd vncconfig
vncserver -help | head -30
包作用是否必装
tigervnc-serverVNC 服务器(vncserver、vncpasswd)必装
tigervnc-server-moduleXorg 的 VNC 模块,配合 x0vncserver 共享真实显示器 :0可选
tigervncVNC 客户端(vncviewer)仅当本机也要当客户端时装

注意:tigervnc-server-module 是另一个用法——共享物理显示器 :0(也就是接在机器上的那块显示器),配合 x0vncserver 用。日常远程桌面用虚拟显示器就够了,不用装这个包。

四、配置 VNC 用户与密码

VNC 的密码是按用户设置的,每个用户有自己的 VNC 密码和显示器。先给要远程登录的用户设密码。

# 切换到要远程登录的用户(这里用 admin 举例)
su - admin

# 设置 VNC 密码(会提示输入两次)
vncpasswd
# Password:
# Verify:
# Would you like to enter a view-only password (y/n)? n

# 密码存在 ~/.vnc/passwd,权限自动设为 600
ls -l ~/.vnc/passwd
  • 密码长度:传统 VNC 认证最多 8 个字符,超过 8 个会被截断。设密码时 TigerVNC 会提示,超过 8 个字符的部分不起作用,别以为设了 12 位就更安全。
  • view-only 密码:只看不操作的密码,适合给别人看屏幕但不让操作。生产环境一般不设,直接选 n。
  • 密码文件权限:~/.vnc/passwd 必须是 600,不然 vncserver 拒绝启动。手动改过权限的要改回来:chmod 600 ~/.vnc/passwd。
  • root 用 VNC:能不用 root 就不用 root,给普通用户配 VNC,需要 root 权限的操作在 VNC 里用 sudo。

五、配置 systemd 服务

RHEL 8 用 systemd 管理 VNC 服务,服务模板在 /lib/systemd/system/vncserver@.service。@ 后面的数字就是显示器号::1 对应端口 5901,:2 对应 5902,依此类推。做法是复制模板、改用户名和显示器号、启用服务。

# 复制服务模板,给 admin 用户配 :1 显示器
cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service

# 编辑服务文件
vi /etc/systemd/system/vncserver@:1.service
# /etc/systemd/system/vncserver@:1.service
[Unit]
Description=Remote desktop service (VNC)
After=syslog.target network.target

[Service]
Type=forking
# 启动前先清理残留的旧会话
ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
# <USER> 改成实际用户名,%i 就是显示器号 1
ExecStart=/usr/sbin/runuser -l admin -c "/usr/bin/vncserver %i -geometry 1920x1080"
PIDFile=/home/admin/.vnc/%H%i.pid
ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'

[Install]
WantedBy=multi-user.target
  • 显示器号和端口:显示器 :1 对应 TCP 5901,:2 对应 5902。防火墙放行哪个端口,取决于配了哪个显示器号。
  • 分辨率:-geometry 1920x1080 是虚拟桌面的分辨率,按客户端显示器调。分辨率越大越占显存和带宽,远程 over VPN 时 1280x1024 更流畅。
  • 不要直接改模板:模板在 /lib 下,软件包升级会覆盖。复制到 /etc/systemd/system 下再改,升级不受影响。
  • Type=forking:vncserver 默认是 fork 到后台跑,服务类型要和它匹配,别改成 simple,不然 systemd 以为服务启动失败会反复重启。
# 重载 systemd 配置
systemctl daemon-reload

# 开机自启并启动
systemctl enable vncserver@:1.service
systemctl start vncserver@:1.service

# 确认状态
systemctl status vncserver@:1.service
vncserver -list
ss -tlnp | grep 5901

六、防火墙与 SELinux

# 防火墙放行 VNC(firewalld 自带 vnc-server 服务,覆盖 5900-5903)
firewall-cmd --permanent --add-service=vnc-server
firewall-cmd --reload
firewall-cmd --list-services

# 只放行单个端口的做法(显示器 :1 用 5901)
# firewall-cmd --permanent --add-port=5901/tcp
# firewall-cmd --reload

# 确认端口在监听
ss -tlnp | grep 590

SELinux 方面,TigerVNC 通常不需要额外配置。如果服务启动失败并且日志里有 SELinux 相关的拒绝,先查审计日志确认是不是 SELinux 的问题,再决定怎么处理。

# 查最近的 SELinux 拒绝记录
ausearch -m avc -ts recent

# 临时关 SELinux 验证是不是它的问题(只做测试,验证完马上开回来)
setenforce 0
systemctl restart vncserver@:1.service
# 如果 setenforce 0 之后能用了,就是 SELinux 策略问题,再针对性处理
setenforce 1

# 千万别图省事直接把 SELinux 设成 disabled,生产机器不要这么干

七、启动服务与连接测试

服务起来之后,用 VNC 客户端连上去验证。客户端推荐 TigerVNC Viewer(和服务器同源,兼容性最好)或者 RealVNC Viewer。

# 服务端确认
systemctl status vncserver@:1.service
vncserver -list
# TigerVNC server sessions:
# X DISPLAY #     PROCESS ID
# :1              1234

# 客户端连接地址(显示器 :1 对应端口 5901)
# TigerVNC Viewer 里填:服务器IP:5901
# 或者填:服务器IP:1(:1 是显示器号的写法)
  • Windows 客户端:装 TigerVNC Viewer,地址填 服务器IP:5901,输 VNC 密码。
  • Linux 客户端:dnf install tigervnc,然后 vncviewer 服务器IP:1。
  • 第一次连不上:先在服务器本机测端口通不通:ss -tlnp | grep 5901 看服务在不在监听,再从客户端 telnet 服务器IP 5901 看网络通不通,分段定位。
  • 黑屏或者只有灰屏:一般是桌面会话没起来,看 ~/.vnc/*.log 里的报错,常见原因是 xstartup 配置不对(见第八节)。

八、配置详解:xstartup 与 ~/.vnc/config

VNC 连上之后显示什么桌面,由启动脚本决定。TigerVNC 启动显示器时,会执行用户的 ~/.vnc/xstartup;如果没有这个文件,就用系统默认的 /etc/vnc/xstartup,它会调 /etc/X11/xinit/xinitrc 起默认会话。想用 GNOME 桌面,写一个自己的 xstartup。

# ~/.vnc/xstartup(GNOME 桌面)
cat > ~/.vnc/xstartup << 'EOF'
#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
exec gnome-session &
EOF
chmod +x ~/.vnc/xstartup

# 改完 xstartup 要重启 VNC 服务才生效
systemctl restart vncserver@:1.service

TigerVNC 还支持 ~/.vnc/config 配置文件,启动参数写在这里,不用每次都在命令行或者 service 文件里写。

# ~/.vnc/config(每行一个参数)
cat > ~/.vnc/config << 'EOF'
geometry=1920x1080
depth=24
localhost=no
alwaysshared
SecurityTypes=VncAuth
desktop=RHEL83-VNC
EOF

# 常用参数说明
# geometry:虚拟桌面分辨率
# depth:色深,24 是常用值
# localhost:yes 只监听本地(配合 SSH 隧道用,见第九节)
# alwaysshared:允许多个客户端同时连一个显示器
# SecurityTypes:认证方式,VncAuth 是密码认证
# desktop:桌面标题,客户端窗口上显示的名字

九、安全加固:VNC 流量默认不加密

这是最重要的一节。VNC 协议本身不加密,密码和屏幕内容都是明文传的,直接暴露在公网或者不可信的内网等于裸奔。生产环境必须做下面至少一项。

9.1 SSH 隧道(推荐)

# 服务端:只监听本地,不对外暴露 5901
# ~/.vnc/config 里加一行
# localhost=yes
# 然后重启服务
systemctl restart vncserver@:1.service

# 客户端:建 SSH 隧道,把本地 5901 映射到服务器的 5901
ssh -L 5901:localhost:5901 admin@服务器IP

# 隧道建好之后,VNC 客户端连 localhost:1
# 流量走 SSH 加密隧道,不经过明文网络

9.2 其他加固措施

  • 防火墙白名单:只放行办公网 IP 段访问 5901,别对全网开放。firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port port="5901" protocol="tcp" accept'
  • 密码策略:VNC 密码和系统登录密码用不同的,定期换。VNC 密码最长 8 位是协议限制,弥补办法是靠 SSH 隧道和防火墙白名单。
  • 不要给 root 配 VNC:普通用户 + sudo,需要 root 权限的操作在 VNC 里 sudo 提权。
  • TLS 加密:TigerVNC 支持 VeNCrypt + X509 证书加密,需要配证书,适合有证书体系的环境。个人和小团队用 SSH 隧道就够了。
  • 不用的时候停掉:临时用的 VNC,用完 systemctl stop vncserver@:1.service,别长期挂着。

十、多用户与多显示器配置

一台服务器可以给多个用户各配一个显示器,互不干扰。做法就是按第五节再复制一份服务文件,改显示器号和用户名。

# 给第二个用户 bob 配 :2 显示器
su - bob
vncpasswd
exit

cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:2.service
# 编辑文件:把 User 和 runuser 后面的用户名改成 bob
vi /etc/systemd/system/vncserver@:2.service

systemctl daemon-reload
systemctl enable vncserver@:2.service
systemctl start vncserver@:2.service

# 确认两个显示器都在跑
vncserver -list
ss -tlnp | grep 590
# :1 → 5901(admin),:2 → 5902(bob)

# 防火墙:vnc-server 服务覆盖 5900-5903,:1 和 :2 都在范围内,不用再加
显示器端口用户服务名
:15901adminvncserver@:1.service
:25902bobvncserver@:2.service
:35903待分配vncserver@:3.service

十一、常见故障排查

现象可能原因处理方法
systemctl start 失败用户名写错、家目录权限不对、密码没设看 systemctl status 的报错;确认 vncpasswd 设过;确认 ~/.vnc 属于该用户
客户端 Connection refused服务没起来、防火墙没放行、端口不对ss -tlnp 确认监听;firewall-cmd --list-services 确认放行;核对显示器号和端口的对应关系
Authentication failedVNC 密码错、密码文件权限不对重新 vncpasswd;chmod 600 ~/.vnc/passwd;注意密码超过 8 位会被截断
连上是黑屏或灰屏xstartup 没执行、GNOME 没装、会话启动失败看 ~/.vnc/*.log;确认装了 Server with GUI;检查 xstartup 有没有执行权限
连上闪退GNOME 会话崩溃、显存/内存不足看 ~/.vnc/*.log 和 journalctl -u vncserver@:1;换轻量桌面(Xfce)测试
字体模糊、画面卡顿分辨率太高、带宽不足、色深太高降 geometry 到 1280x1024;depth 改 16;走局域网别走 VPN
服务启动后自动停service 文件 Type 不对、PIDFile 路径错确认 Type=forking;PIDFile 里的用户和家目录路径要对
# 排障三板斧:服务状态、VNC 日志、系统日志
systemctl status vncserver@:1.service
cat ~/.vnc/*.log
journalctl -u vncserver@:1.service --since "1 hour ago"

# 手动前台启动看报错(排障时用,别长期这么跑)
vncserver -fg :1
# 按 Ctrl+C 停掉,报错直接打在终端上

十二、日常运维命令速查

# 服务管理
systemctl start|stop|restart|status vncserver@:1.service
systemctl enable|disable vncserver@:1.service

# 会话管理(不用 systemd 时手动管理)
vncserver -list          # 列出当前会话
vncserver :1             # 手动启动 :1
vncserver -kill :1       # 杀掉 :1 会话
vncpasswd                # 改 VNC 密码

# 网络与防火墙
ss -tlnp | grep 590      # 看哪些 VNC 端口在监听
firewall-cmd --list-services
firewall-cmd --permanent --add-service=vnc-server && firewall-cmd --reload

# 日志
journalctl -u vncserver@:1.service -f
tail -f ~/.vnc/*.log

整套流程总结:先确认订阅和桌面环境,装 tigervnc-server,给用户设密码,复制 systemd 模板配好显示器,放行防火墙,连上验证,最后上 SSH 隧道加固。VNC 本身不难,难的是安全:密码 8 位上限、流量不加密,这两点不处理好,VNC 装得越顺,风险越大。先把 SSH 隧道搭上,再开放给其他人用。

发表回复

后才能评论