
写这篇东西的时候我刚在一台干净安装的 openEuler 20.03 服务器上把 tigervnc-server 配完。如果你也是第一次在欧拉上做远程桌面大概率会踩到这几个坑明明 dnf install 已经装完包vncserver 服务却起不来service 文件里的USER占位符看着就别扭不知道该改成什么好不容易连上了屏幕上却只有一片灰没有桌面。这篇文章我会把 openEuler 20.03 上安装配置 tigervnc-server 的完整过程拆开讲从最基础的软件包选型讲到 systemd 实例化、防火墙放行、SELinux 处理最后再把常见问题的排查思路整理成一张速查表。整套流程我都是在一台最小化安装的 openEuler 20.03 上实测过的照着做基本不会翻车。1. 安装前需要想明白的三件事服务端、桌面环境和显示号1.1 先搞清楚 tigervnc-server 到底是什么角色很多人第一次配 VNC 就把概念搞混了。tigervnc-server 是 VNC 的服务端作用是在服务器上监听端口把图形桌面“广播”出去而你去 Windows 笔记本上打开的 VNC Viewer 是客户端负责连过来看这个桌面。也就是说你要在 openEuler 上装的是 tigervnc-server不是 tigervnc 客户端。如果连不上第一步先确认自己是不是在服务器上装错了包。这里还有一个容易忽略的点装完 tigervnc-server 只是拿到了软件本身系统里没有对应的服务单元文件可以直接用。openEuler 20.03 的 TigerVNC 包安装后会在/usr/lib/systemd/system/下放一个模板文件vncserver.service。这个东西不是拿来直接 start 的而是要你复制成带显示号的服务实例。为什么这样设计因为 VNC 服务端天然支持一机多桌面比如 :1 给运维同事:2 给开发同事每个显示号可以对应不同的用户和不同的分辨率。systemd 模板 实例化的方式恰好能把这套多桌面管理逻辑承接过来。1.2 服务器上没有桌面环境装了 VNC 也白搭这一步是网上教程漏得最多的。VNC 本质上是一个远程桌面协议它需要系统里先有一层图形会话。如果你当初装 openEuler 20.03 的时候选了“最小化安装”系统里根本没有 X Server也没有 GNOME 或 Xfce 这类桌面套件那 vncserver 进程虽然能拉起来但客户端连上去之后只能看到一个黑屏或者灰屏。所以在动手之前先想清楚目标机器上有没有图形环境。我个人一般这样判断执行dnf group list看有没有安装 “Server with GUI” 这一类的组或者直接看/usr/bin/gnome-session、/usr/bin/xfce4-session这类可执行文件是否存在。如果确认没有桌面我劝你先别急着配 VNC老老实实先把桌面装好。openEuler 20.03 的软件源里通常有完整的工作站组可以执行dnf group list dnf groupinstall Server with GUI注意组名在不同版本里可能略有差异先 group list 看一眼再装别拿网上的命令无脑复制。装完之后重启或者进图形模式确保本机图形会话能起来再往下配 VNC这样排查问题会轻松很多。1.3 显示号、端口号、systemd 实例名这三者的对应关系初次接触 VNC 的人对:1这个概念往往很懵。用一句话讲显示号是 VNC 自己内部的桌面编号它在 TCP 层面对应的监听端口是5900 显示号。也就是说:1对应 5901 端口:2对应 5902 端口依此类推。这个对应关系直接决定了三件事systemd 服务单元文件名要写成vncserver:1.service这个:1就是显示号。防火墙和云安全组里要放行的端口必须跟着显示号走比如显示号是 1就要放行 5901/tcp。客户端连接时填的地址是服务器IP:5901或者用简写服务器IP:1。理解了这套对应关系后面配置就不会一头雾水。你也可以顺带想明白另一件事如果一台机器上要跑多个 VNC 桌面只要把模板复制成vncserver:2.service、vncserver:3.service并放行对应的 5902、5903 端口即可。不用再装一遍软件。2. 环境准备与 tigervnc-server 安装检查、装包、建用户2.1 先确认系统版本和软件源状态动手之前我建议先确认一下你手上的系统确实是 openEuler 20.03。虽然网上有大量 CentOS 7 的 VNC 配置教程里面的命令在欧拉上大部分也能跑但版本差异还是会造成一些路径和参数上的坑。确认版本用这两条命令cat /etc/openEuler-release cat /etc/os-release如果是 20.03 版本输出里会明确写着 openEuler 20.03 的字样。同时建议顺手执行一遍dnf makecache把软件源缓存刷新一下。这一步不能省因为镜像站源偶尔会更新缓存过期可能导致安装时解析不到最新包。国内服务器如果配的是默认的欧拉镜像源一般速度都不错不用额外折腾源切换。2.2 安装 tigervnc-server 及配套组件在 openEuler 20.03 上安装 TigerVNC 服务端很简单dnf install -y tigervnc-server有的教程会让你连tigervnc-server-module一起装这个包里带的是 x0vncserver 之类的附加工具如果只是常规的“系统桌面远程连接”装主包其实就够用了。但如果你后续有“只共享某个已经运行的 X 桌面”这种需求那就把 module 包也装上。我的习惯是两条一起dnf install -y tigervnc-server tigervnc-server-module vim顺手把 vim 装上后面改配置文件方便反正也不占几个字节。装完以后验证一下rpm -qa | grep tigervnc能看到 tigervnc-server 和 tigervnc-server-module 的输出就说明包已经装好了。这里多说一句openEuler 20.03 默认包管理器是 dnf但 yum 命令也做了兼容所以你要是看到老教程里写 yum install在欧拉上也能正常执行。2.3 创建普通用户并设置独立的 VNC 密码VNC 不建议直接用 root 账户跑一是安全审计麻烦二是 TigerVNC 对 root 用户有一些额外的限制比如默认配置下 X 服务不允许 root 直接启动容易莫名其妙报错。我习惯创建一个普通用户比如 vncuseruseradd vncuser passwd vncuser系统密码设置好之后还要给这个用户设置单独的 VNC 密码。VNC 密码和系统登录密码是两套体系它存在当前用户家目录下的~/.vnc/passwd文件里。设置方式很直接su - vncuser vncpasswd执行 vncpasswd 后终端会提示输入密码输两遍确认。这里有两个细节值得注意第一传统 VNC 协议对密码长度限制很死超过 8 个字符的密码在部分版本里会被静默截断导致你明明输对了却认证失败所以别设太长的密码第二vncpasswd 生成的~/.vnc目录权限必须保持严格不能随便 chmod 777否则启动时 TigerVNC 会以“不安全权限”为由拒绝读取密码文件。3. systemd 服务单元配置详解vncserver:1 到底怎么写3.1 默认模板文件长什么样安装完 tigervnc-server 后你先执行一下rpm -ql tigervnc-server | grep systemd正常情况下会看到一个模板文件路径一般是/usr/lib/systemd/system/vncserver.service。用 cat 打开看内容大致是下面这个风格[Unit] DescriptionRemote desktop service (VNC) Aftersyslog.target network.target [Service] Typeforking UserUSER GroupUSER WorkingDirectory/home/USER ExecStartPre/bin/sh -c /usr/bin/vncserver -kill %i /dev/null 21 || : ExecStart/usr/sbin/runuser -l USER -c /usr/bin/vncserver %i -geometry 1024x768 -depth 24 ExecStop/bin/sh -c /usr/bin/vncserver -kill %i /dev/null 21 || : [Install] WantedBymulti-user.target重点看两个地方一个是USER这是占位符必须替换成你实际创建的用户名另一个是%i这表示 systemd 从服务实例名里自动提取的显示号。所谓实例名就是你复制出来的文件名中 后面的部分。如果你把模板复制成vncserver:1.service那么%i就等于:1vncserver 启动时就监听:1显示屏对应 5901 端口。3.2 为什么不能直接 systemctl start vncserver很多人装完包就迫不及待地执行systemctl start vncserver结果系统提示找不到服务。原因就在于系统只提供了模板文件没有提供具体的实例单元。systemd 模板文件不能单独启动必须实例化。而动态实例化的前提是你至少有一个vncserver:N.service文件存在。正确的做法是把模板复制成实例文件cp /usr/lib/systemd/system/vncserver.service /etc/systemd/system/vncserver:1.service复制到/etc/systemd/system/而不是直接改/usr/lib/systemd/system/这是个好习惯。前者属于系统本地配置目录优先级高于后者以后软件包升级时不会覆盖你改过的内容。复制完之后编辑这个新文件vim /etc/systemd/system/vncserver:1.service把里面的USER全部替换成 vncuser。这里我要特别提醒WorkingDirectory/home/USER这一行如果不改或者改错VNC 服务启动后工作的目录就会不对用户登录进去看到的是一个不正常的环境。所以别只改 ExecStart 那行所有USER都替换掉。3.3 一个关键参数-localhost no 决定你能不能远程连上模板文件里默认的 ExecStart 是ExecStart/usr/sbin/runuser -l vncuser -c /usr/bin/vncserver %i -geometry 1024x768 -depth 24这个默认写法有一个隐蔽的坑TigerVNC 新版本出于安全考虑默认只监听本机回环地址 127.0.0.1。如果你不做任何修改在本机通过 ssh 执行vncviewer 127.0.0.1:1是能连上的但从你的 Windows 笔记本连过去绝对失败。很多人折腾半天其实就差这个-localhost no。所以我最终把 ExecStart 改成了这样ExecStart/usr/sbin/runuser -l vncuser -c /usr/bin/vncserver %i -geometry 1440x900 -depth 24 -localhost no解释一下-geometry 1440x900桌面分辨率。分辨率设太高会明显卡顿尤其服务器 CPU 不够强或者网络延迟大的时候。我一般建议先用 1280x720 或 1440x900 试测试通过后再按需调。-depth 24色深。24 位色彩显示效果好但带宽占用也大。内网用 24 没问题跨公网远程建议改成 16能明显降低卡顿感。-localhost no允许非本机连接。加上它外部客户端才能真正访问。改完文件后执行systemctl daemon-reload重新加载 systemd 配置。这一步必须做否则 systemd 用的还是旧配置你改了半天启动服务后还是旧参数。3.4 多用户场景创建第二个桌面实例如果你有多个用户要同时远程使用那就把模板再复制一份换一个显示号cp /usr/lib/systemd/system/vncserver.service /etc/systemd/system/vncserver:2.service同样把USER替换成第二个用户名比如 devuser再把需要改的分辨率、色深按需调整。这样你就有:1和:2两套独立的远程桌面互不干扰。端口分别对应 5901 和 5902后续防火墙放行也要逐个添加。4. 启动 VNC 服务并放行防火墙与 SELinux4.1 用 systemctl 启动并设置开机自启配置文件改好之后启动流程就很简洁了。先启动服务再设置开机自启systemctl daemon-reload systemctl start vncserver:1.service systemctl enable vncserver:1.service查看服务状态systemctl status vncserver:1.service如果一切正常你应该能看到 active (running) 的状态并且日志里出现了类似New Xtigervnc server ... is listening的信息。这一步如果出问题最常见的日志报错是/home/vncuser/.vnc目录不存在或者密码文件没生成那多半是没执行 vncpasswd回头补上就行。确认服务在跑之后必须再验证端口监听ss -lntp | grep 5901看到类似LISTEN 0 ... 0.0.0.0:5901的输出说明 vncserver 已经真正监听到了外部网卡的 5901 端口。如果只显示127.0.0.1:5901说明你忘了加-localhost no回到上一节改配置。4.2 firewalld 防火墙放行端口openEuler 20.03 默认启用了 firewalld。先从 Windows 测试连接之前必须在防火墙里放行对应端口否则端口监听得再正常也白搭。firewall-cmd --permanent --add-port5901/tcp firewall-cmd --reload放行之后顺手查看一下firewall-cmd --list-ports能看到 5901/tcp 就说明防火墙规则已经生效。这里要注意两个细节第一--permanent参数不能漏如果只写--add-port不带 permanent规则只在本次运行时生效服务器重启就没了第二如果你想把端口限定在某个来源 IP可以写成firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.1.100 port protocoltcp port5901 accept这在公网场景下尤其重要。VNC 本身密码认证强度有限裸奔到公网上等于给自己埋雷加个来源 IP 限制能挡掉一大波扫描。4.3 SELinux 要不要动openEuler 20.03 默认开启 SELinux状态是 enforcing。按我实测经验干净的 tigervnc-server 安装 默认 SELinux 策略环境下VNC 连接基本不会触发 SELinux 拦截因为 TigerVNC 相关服务已经预置了对应的策略允许规则。但如果你是从其他发行版迁移过来或者动过 SELinux 布尔值就可能踩到。排查方法很简单先看状态getenforce然后去连接一次连不上就看有没有 AVC 拦截日志ausearch -m avc -ts recent | grep vnc如果有 AVC 日志再考虑放行相关布尔值或调整上下文。我见过的一个典型场景是用户把家目录放在自定义路径下例如/data/vncuserSELinux 上下文类型不对xauth 写不进去VNC 启动报错。这时候可以用restorecon -Rv /data/vncuser恢复正确的 context。这里我强烈不建议动不动就setenforce 0或者直接把 SElinux 改成 disabled。把 SELinux 关掉确实能让很多连接问题瞬间消失但代价是整台服务器暴露在更低的安全基线之下。先查日志确认问题真的是 SELinux 引起的再对症处理。5. 客户端连接、桌面环境与黑屏兜底5.1 从 Windows 或本机用 VNC Viewer 连接服务端起来之后客户端的选择很多。Windows 上我常用 TigerVNC Viewer 或者 RealVNC Viewer都是下载后解压就能用的绿色软件不需要安装。连接地址填服务器IP:5901即可。如果你图省事也可以填服务器IP:1很多客户端能自动换算成 5901。第一次连接时VNC Viewer 会弹出一个警告大意是“这台主机的指纹尚未验证”这是正常的因为 VNC 默认没有配置 TLS 证书。确认 IP 是你的服务器后点继续即可。接下来会要求输入密码注意这里要输的是 vncpasswd 设置的 VNC 密码不是 vncuser 的系统登录密码。如果一切正常你就能看到远程桌面了。如果连接被拒或者卡在密码阶段别急着怀疑密码输错先看看日志和服务状态排查步骤我放在下一节。5.2 没有桌面环境时的 xstartup 配置连接成功但屏幕一片灰或者直接黑屏这个现象在最小化安装的 openEuler 上出现的概率极高。核心原因就是前面第 1.2 节说的系统里没有图形桌面会话。解决步骤分两步第一步安装桌面环境前面已经写过命令第二步确保用户家目录下的~/.vnc/xstartup脚本能正确启动桌面。TigerVNC 在启动时会去找当前用户的~/.vnc/xstartup如果不存在或没有执行权限它可能只会启动一个空的根窗口表现出来就是灰屏。我现在经常用的 xstartup 模板是#!/bin/sh unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS exec /usr/bin/gnome-session如果系统装的是 Xfce就把最后一行换成exec /usr/bin/xfce4-session写完后必须赋予执行权限chmod x ~/.vnc/xstartup然后重启 vncserver 服务systemctl restart vncserver:1.service注意重启服务前最好先让当前已连接的客户端断开否则旧会话可能抢占 GPU 或者 X 锁导致新会话起不来。5.3 连接后键盘乱、分辨率不对、字体发虚怎么办远程桌面连上去之后比较常见的小毛病有三类。第一是键盘布局不对敲出来的字符和键盘上的按键对不上通常在 VNC Viewer 客户端设置里把键盘布局改成和服务器一致即可或者在服务启动时加参数指定 keymap。第二是分辨率不是预期值我在配置里写了-geometry 1440x900但客户端看起来还是默认的 1024x768这多半是旧会话没杀掉或者 vncserver 读取了陈旧配置执行vncserver -kill :1后重新启动就能解决。第三是字体发虚本质是色深不够把-depth 24加上就好很多。5.4 把 VNC 桌面调整成贴近本机使用习惯最后给一个提升使用体验的小技巧。连接成功以后你可以把远程桌面的主题、字体和缩放调整成自己熟悉的样子这些配置会存放在用户家目录的配置文件里。如果想要多个人共用一套初始环境可以先配好一个用户再把该用户家目录下的.config等目录拷贝给其他用户作为模板。不过这种操作注意文件权限别把 A 用户的配置直接用 root 复制到 B 用户目录下否则 B 用户可能起不来图形会话。6. 常见问题排查连接失败、密码、日志与端口冲突6.1 连不上时的第一反应先看日志很多初学者遇到 VNC 连不上第一反应是卸载重装。其实大多数问题都能在日志里找到答案。查看 VNC 服务日志的命令是journalctl -u vncserver:1.service另外每个用户家目录下的~/.vnc/里也会生成以主机名和显示号命名的日志文件比如openEuler:1.log里面的信息更原始直接记录 Xvnc 的启动过程。遇到环境类问题看这个文件比看 systemd 日志有更多线索。6.2 一张表解决大部分常见故障我把这轮配置过程中实际遇到的高频问题整理成了速查表按出现概率排序现象可能原因处理方式客户端提示 Connection refused服务没起来或者端口不被监听systemctl status vncserver:1.service再 ss -lntp连接超时、无响应防火墙没放行firewall-cmd --list-ports确认包含 5901/tcp在公网连接被秒断云安全组/网络ACL拦截去云控制台检查对应端口的安全组规则提示 Authentication failedVNC 密码错误或密码文件权限不当su 到对应用户重新执行 vncpasswd检查~/.vnc/passwd权限是否为 600连接成功但黑屏/灰屏没有桌面环境或 xstartup 异常确认是否安装桌面组检查 xstartup 是否存在且有执行权限启动服务报找不到单元没有复制实例单元文件确认/etc/systemd/system/vncserver:1.service存在启动服务提示 No such file模板文件中的路径不对用rpm -ql tigervnc-server检查实际路径重启后服务不自动启动enable 失败或依赖网络未就绪重新执行systemctl enable vncserver:1.service分辨率不对旧会话残留或参数没生效vncserver -kill :1再重启服务6.3 端口被占用和进程残留问题如果你反复修改配置并重启服务很容易遇到端口被占用。最典型的场景是 ExecStartPre 里的 kill 命令没生效旧 Xvnc 进程还在跑新进程起不来。排查命令ps aux | grep Xvnc看到残留进程后手动杀掉kill -9 进程号这里我想特别提醒一句直接在/usr/lib/systemd/system/里改模板文件是不可取的。我见过有人这么做结果系统升级 tigervnc-server 包时文件被覆盖所有自定义配置化为乌有。把实例文件放在/etc/systemd/system/才是规范动作。6.4 性能调优低配服务器也能顺畅用 VNC如果服务器配置不高或者你是跨公网远程办公VNC 的流畅度可能会让你崩溃。我实测下来比较有效的组合是分辨率 1280x720、色深 16、关闭桌面动画特效。有条件的话尽量走内网或者专线公网延迟高的时候即使配得再合理也会卡。另外TigerVNC 有个-PreferredEncoding之类的编码参数可以在部分客户端上微调。新版本默认采用压缩效率较高的编码大部分场景下不需要手动改。真正影响体感的是网络往返时间不是编码格式。所以我对远程桌面的建议很简单内网随便造公网尽量少反复拖动大窗口。6.5 密码策略和连接安全建议搞完一套 VNC 之后别急着把地址发给所有人。VNC 密码位数短、认证过程也不像 SSH 那么强所以我的习惯是第一VNC 密码不要和系统密码重复第二尽量通过防火墙只允许特定来源 IP 访问 5901 端口第三如果公司有跳板机优先用 SSH 隧道方式访问 VNC而不是直接把 5901 暴露到公网。本机开一条隧道再连安全性和稳定性都高一个档次。结尾写到这里openEuler 20.03 上安装配置 tigervnc-server 的完整流程就算讲完了。按我这几年的运维体会VNC 这套东西本身并不难难点全在系统层面的协同桌面环境装没装、systemd 模板怎么解析、防火墙放行端口对不对、SELinux 有没有躲在后面拦路。只要把这几个环节逐个确认到位配置成功的概率基本就是百分百。最后再分享一个小技巧如果你想彻底搞清楚 vncserver 进程到底在干什么可以在启动后执行ps -ef | grep Xvnc把完整命令行参数手工拆一遍比看任何教程都直观。希望这篇内容能帮你少走一些我当年踩过的弯路。