1. 项目概述与方案选型
1.1 这个项目到底解决什么问题
openEuler作为企业级Linux发行版,绝大多数场景下都是不带图形界面的纯服务器环境。但总有那么些时候,你需要在服务器上跑一些带GUI的软件,或者团队里有同事不习惯纯命令行操作,又或者你想在办公电脑上直接连到服务器桌面干点活。这时候,给openEuler装一套完整的远程桌面方案就成了刚需。
本项目的目标很明确:在openEuler上安装UKUI桌面环境,再用TigerVNC把桌面共享到局域网内任意一台电脑上,让你像操作本地电脑一样操作远程的openEuler服务器。
我选择的组合是UKUI + TigerVNC,这套方案的优势在于:
- UKUI是由麒麟团队主导开发的轻量级桌面环境,对中文用户极其友好,菜单布局、字体渲染都更贴近国内使用习惯,而且资源占用比GNOME低不少。
- TigerVNC是目前Linux生态下最稳定、最成熟的VNC服务端实现,和systemd集成得很好,配置起来比X11VNC、x0vncserver这些方案省心得多。
- 全程走局域网VNC协议,不依赖公网IP、不需要路由器端口映射,只要两台机器能互相ping通就能连。
1.2 和XRDP、X11VNC等方案的对比
先说结论:如果你问我openEuler装远程桌面优先推荐哪个,我会说VNC系比RDP系更省事,TigerVNC又是VNC系里最稳的。
xrdp走的是RDP协议,Windows自带的远程桌面客户端直接就能连,看起来很美。但xrdp在openEuler上有个老毛病——和桌面环境的会话管理器偶发兼容问题,连上之后黑屏或者卡在登录界面的情况不少见。而且openEuler的官方源里不一定有打包好的xrdp,经常要自己编译,折腾成本高。
TigerVNC走的是VNC协议,虽然客户端需要单独装,但服务端的稳定性是真的好,尤其是配合systemd的模板单元文件,一个服务管一个显示端口,重启自启、多用户会话都很干净。再加上它和桌面环境是解耦的——VNC只管传屏幕画面和键盘鼠标事件,桌面环境是什么它不关心,所以兼容性反而更好。
简单整理一下:
| 方案 | 协议 | 客户端 | openEuler源内可用 | 稳定性 | 安装难度 |
|---|---|---|---|---|---|
| TigerVNC | VNC | VNC Viewer等 | 可用 | 高 | 低 |
| xrdp | RDP | Windows远程桌面 | 不一定 | 中 | 中 |
| X11VNC | VNC | VNC Viewer等 | 可用 | 中 | 中(依赖已有的X会话) |
基于这个对比,我最终敲定了UKUI + TigerVNC的组合。下面把整个流程从零开始走一遍。
2. 环境准备与基础配置
2.1 openEuler版本确认
动手之前,先确认你手上的openEuler版本。不同版本的软件源和包名可能会有细微差别,我本次实操用的是openEuler 22.03 LTS SP4,这也是目前生产环境里用得最多的版本之一。
cat /etc/openEuler-release如果输出类似openEuler release 22.03 (LTS-SP4),那下面的步骤可以直接照抄。如果你用的是20.03 LTS或24.03 LTS,大部分命令也一样,只是个别软件包版本会不同,不影响整体流程。
2.2 配置软件源
装软件之前必须先保证yum源可用。openEuler默认带的源通常没问题,但部分最小化安装的机器会缺AppStream源或EPOL源,而UKUI桌面环境的不少组件在EPOL仓库里。
先检查现有源配置:
dnf repolist如果列出来的仓库数量很少,或者你之前配置过第三方源导致冲突,建议先把官方源恢复干净。最简单的方式是直接编辑/etc/yum.repos.d/openEuler.repo,把baseos、appstream、epol这几个核心仓库都配上。
以22.03 LTS SP4为例,一个最小可用的仓库配置长这样:
[openEuler-baseos] name=openEuler-baseos baseurl=https://repo.openeuler.org/openEuler-22.03-LTS-SP4/OS/x86_64/ enabled=1 gpgcheck=1 gpgkey=https://repo.openeuler.org/openEuler-22.03-LTS-SP4/OS/x86_64/RPM-GPG-KEY-openEuler [openEuler-appstream] name=openEuler-appstream baseurl=https://repo.openeuler.org/openEuler-22.03-LTS-SP4/AppStream/x86_64/ enabled=1 gpgcheck=1 gpgkey=https://repo.openeuler.org/openEuler-22.03-LTS-SP4/OS/x86_64/RPM-GPG-KEY-openEuler [openEuler-epol] name=openEuler-epol baseurl=https://repo.openeuler.org/openEuler-22.03-LTS-SP4/EPOL/main/x86_64/ enabled=1 gpgcheck=1 gpgkey=https://repo.openeuler.org/openEuler-22.03-LTS-SP4/OS/x86_64/RPM-GPG-KEY-openEuler注意:如果你的服务器无法直连外网,请自行准备内网镜像源,替换baseurl为内网地址。这个项目的前提是系统能正常拉到软件包,不然后面全是空谈。
配置完执行dnf makecache刷新缓存。这一步如果报错,99%是网络不通或者gpgkey路径不对,排查思路在后面常见问题章节里细说。
2.3 系统更新与依赖准备
虽然是装桌面,但我还是建议先把系统基础包更新一遍,避免装桌面过程中碰到依赖冲突。执行:
dnf -y update这个过程可能比较久,取决于网络状况。更新完建议重启一次,让内核和基础库都切到最新状态。
另外提前装两个后面会用到的工具:
dnf -y install net-tools firewalldnet-tools提供ifconfig等网络排查命令,firewalld用于放行VNC端口。虽然也可以用iptables,但openEuler默认的防火墙管理工具是firewalld,顺着系统默认走最省事。
3. UKUI桌面环境安装
3.1 安装UKUI桌面组
openEuler的软件源里把UKUI打包成了环境组,一条命令就能装完所有核心组件,包括桌面、面板、文件管理器、系统设置、终端模拟器这些。
dnf -y install ukui如果你不想装全家桶,也可以只挑核心包:
dnf -y install ukui-desktop ukui-menu ukui-control-center ukui-windowmanager ukui-sidebar ukui-screensaver但说真的,UKUI这种桌面环境包与包之间的依赖关系很复杂,手动挑包很容易漏东西,最后桌面起不来还得回来补。建议直接用ukui这个组包,装完省心。
命令执行后系统会拉取几百MB的依赖包,包括Qt、GTK、系统字体、音频组件等。这个过程的耗时取决于你的网络和机器配置,耐心等就行。
3.2 设置默认启动图形界面
装完UKUI后,系统默认还是开机进命令行,需要手动把默认运行级别切到图形界面。
systemctl set-default graphical.target这条命令的本质是修改/etc/systemd/system/default.target的软链接指向,让systemd在开机时拉起图形登录管理器。
UKUI的登录管理器是gdm,确认一下开机自启状态:
systemctl enable gdm --now提示:暂时不要重启,先继续装TigerVNC。等VNC配好后一起验证,省得来回重启浪费时间。
3.3 验证桌面环境能否正常启动
如果你现在就想确认UKUI装得有没有问题,可以直接执行startx看一下,但更推荐的做法是等VNC配好之后,通过VNC连进去看。原因很简单:服务器本机往往没有接显示器,startx就算起来你也看不见;而且startx只是启一个临时X会话,和后面VNC要用的会话容易混在一起,徒增排查难度。
4. TigerVNC安装与配置
4.1 安装TigerVNC服务端
openEuler官方源里有打包好的tigervnc-server,直接装:
dnf -y install tigervnc-server装完后确认一下版本:
rpm -qa | grep tigervnc正常情况下会看到类似tigervnc-server-1.12.0-5这样的包名。如果是1.10或更老的版本,建议检查一下源是不是没刷新。
4.2 理解VNC的工作原理
TigerVNC的服务端本质上是一个X Server + 远程帧缓冲传输的结合体。它监听一个TCP端口(默认为5900+N,N是显示编号),当一个VNC客户端连上来时,服务端把桌面画面编码成像素数据流发给客户端,同时接收客户端的键盘和鼠标事件并注入到X会话中。
VNC的显示编号(Display Number)是理解整个配置的关键。:1对应端口5901,:2对应5902,以此类推。这个编号在你启动VNC服务、配置防火墙、客户端连接时都要保持一致,三者对不上就会连不上。
TigerVNC在systemd里用的是模板单元文件,vncserver@.service是万能的,你只要告诉它显示编号和用户名,它就知道该怎么做。
4.3 设置VNC密码
以普通用户身份(不要用root跑桌面,后面细说)设置VNC访问密码。假设我要给用户dev配置远程桌面:
su - dev vncpasswd执行后系统会提示输入两次密码,还可以选择是否创建一个view-only密码(即只能看不能操作的密码)。这里我的建议是:不要设置view-only密码,因为排查问题时"看得见摸不着"反而容易让人困惑,而且多一个密码多一份维护负担。直接回车跳过即可。
密码会保存在~/.vnc/passwd文件里,注意这个文件的权限必须是600,否则TigerVNC会拒绝读取。如果之后手动改过权限,记得:
chmod 600 ~/.vnc/passwd4.4 配置xstartup启动脚本
这是整个配置流程里最容易翻车的环节。
xstartup是VNC客户端连接时自动执行的脚本,它决定VNC会话里启动什么桌面环境。默认的xstartup只启动一个简陋的xterm窗口,所以你必须手动改。
而且这里有个很多教程没讲清楚的坑:你登录的VNC用户不同,xstartup要写的内容也不同。如果你用普通用户连接VNC,想进UKUI桌面,脚本里要启动的是UKUI的会话管理器;如果用root连接,路径和会话名又不一样。
以用户dev为例,编辑~/.vnc/xstartup:
#!/bin/sh unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS export XDG_SESSION_TYPE=x11 exec dbus-launch --exit-with-session ukui-session逐行解释一下:
unset SESSION_MANAGER和unset DBUS_SESSION_BUS_ADDRESS:避免VNC会话继承到父进程(可能是SSH会话或系统服务)的会话管理信息,防止启动桌面时出现会话总线冲突。export XDG_SESSION_TYPE=x11:强制声明会话类型为X11。UKUI虽然是Qt5写的,但VNC走的是X11协议,这里必须明确指定,不然有些组件会尝试走Wayland导致启动失败。exec dbus-launch --exit-with-session ukui-session:通过dbus-launch启动UKUI会话管理器,这样桌面里需要DBus通信的组件(比如通知服务、剪贴板、IPC)才能正常工作。
脚本创建后记得加执行权限:
chmod +x ~/.vnc/xstartup这是新手最容易忘的一步,没有执行权限的脚本相当于废纸,VNC服务端不会去执行它,连接进来只会看到一个灰蒙蒙的屏幕。
重要:如果你在root用户下也要配VNC,那么root的
~/.vnc/xstartup里exec dbus-launch --exit-with-session ukui-session这一行里的会话名可能需要根据系统实际情况调整。普通用户一般没问题,root有时因为环境变量残留会起不来,建议优先使用普通用户做远程桌面。
4.5 创建systemd管理单元
为了让VNC服务开机自启、崩溃自动拉起,我建议直接用systemd来管理。
openEuler上tigervnc-server装好后,systemd的模板单元文件已经自带了,路径在/usr/lib/systemd/system/vncserver@.service。直接用就行。
先为dev用户生成服务实例:
systemctl enable vncserver@:1.service但注意,直接enable之前要确认一件事:systemd模板单元文件里默认指定的用户可能不是你要的用户。看一下:
cat /usr/lib/systemd/system/vncserver@.service如果里面写死了User=root或User=<someone>,而你要以dev用户跑VNC,就需要做一层覆盖。推荐做法是创建/etc/systemd/system/vncserver@.service.d/override.conf:
[Service] User=dev Group=dev WorkingDirectory=/home/dev这个override机制是systemd的标准做法,比直接改/usr/lib/systemd/system/下的文件优雅得多,软件包更新时不会被覆盖。
改完配置后要reload一下systemd:
systemctl daemon-reload然后启动服务并验证状态:
systemctl start vncserver@:1.service systemctl status vncserver@:1.service如果状态是active (running),说明VNC服务已经起来了。用ss -tlnp | grep 5901确认端口在监听。
4.6 防火墙放行端口
TigerVNC服务端口默认被firewalld挡住,不放行的话,客户端永远连不上,而且报错信息还很模糊。先确认防火墙在运行:
systemctl status firewalld如果没开启,建议开启:
systemctl start firewalld systemctl enable firewalld然后放行VNC端口。这里有两种放行方式,选一种即可:
方式一:按端口放行(推荐)
firewall-cmd --permanent --add-port=5901/tcp firewall-cmd --reload方式二:按服务放行
firewall-cmd --permanent --add-service=vnc-server firewall-cmd --reload方式二的前提是firewalld的服务定义文件里有vnc-server,某些版本的openEuler可能没有预置。所以我又回到了方式一,直接对端口做精确放行,简单直接,不依赖服务定义。
放行后可以验证:
firewall-cmd --list-ports5. 客户端连接与日常使用
5.1 Windows客户端连接
Windows上我用得最多的客户端是RealVNC Viewer或者TigerVNC自带的Windows客户端,两者都可以,你挑一个顺手的使用,这里以TigerVNC为例说明。
打开客户端,在最上面的地址栏输入服务器IP:1,注意这个:1就是显示编号,不是端口号。如果显示编号是:1,客户端会自动去连5901端口。
回车后弹出密码框,输入之前设置的VNC密码,回车就能看到UKUI桌面了。
如果连接后出现花屏、黑屏、只有鼠标指针能动的症状,大概率是xstartup脚本的问题,按第6章的排查步骤处理。
5.2 Linux客户端连接
Linux下最简单的操作方式是命令行直连:
vncviewer 192.168.1.100:1或者用带图形界面的客户端:
dnf -y install tigervnc vncviewer5.3 macOS客户端连接
macOS上推荐用RealVNC Viewer,App Store里直接就能下载。连接方式和Windows完全一样,输入IP:1然后输密码。
5.4 多用户与多会话扩展
TigerVNC一个很强的特性是支持多个并发的虚拟桌面。如果你想给另一个用户ops也开一个远程桌面,不要再用:1,而是启用:2:
su - ops vncpasswd exit # 编辑 /home/ops/.vnc/xstartup,内容参考上面 systemctl enable vncserver@:2.service --now firewall-cmd --permanent --add-port=5902/tcp firewall-cmd --reload这样客户端用IP:2就能连到ops的独立桌面。每个用户都有自己的桌面环境和文件,互不干扰。
5.5 调整分辨率
默认的VNC分辨率由服务启动参数决定,如果感觉屏幕太小或比例不对,可以改systemd单元文件里的参数。
创建一个drop-in配置文件:
[Service] ExecStart= ExecStart=/usr/sbin/vncserver -geometry 1920x1080 -depth 24 :1注意:ExecStart=这行留空是systemd的清空默认值操作,原因是模板单元文件里已经写了一条ExecStart,不改掉的话会启动两个VNC服务实例导致端口冲突。然后:
systemctl daemon-reload systemctl restart vncserver@:1.service-geometry 1920x1080指定桌面分辨率,-depth 24指定颜色深度。1080p是目前办公显示器的绝对主流,建议直接用这个。颜色深度24位和默认的32位在视觉上几乎没有区别,但带宽占用会小一些,局域网内无所谓,如果是跨网段连接,这个参数能明显降低延迟感。
6. 常见问题与排查技巧实录
下面整理我在实际配置过程中踩过的、以及帮别人排查时遇到的高频问题,按出现概率排序。
6.1 连不上、超时、连接被拒绝
先把链路从头到尾过一遍:
| 检查点 | 命令/方法 | 预期结果 |
|---|---|---|
| 服务是否在运行 | systemctl status vncserver@:1 | active (running) |
| 端口是否在监听 | ss -tlnp | grep 5901 | 有LISTEN记录 |
| 防火墙是否放行 | firewall-cmd --list-ports | 能看到5901/tcp |
| 客户端地址是否正确 | 确认IP:1的格式 | 地址栏用的冒号,不是点 |
如果以上全部正常还是连不上,在服务器上开一个临时监听看看客户端请求有没有到:
tcpdump -i any port 5901 -n有包进来说明网络通,问题出在服务端配置;没包进来,那就是防火墙或者网络路由的问题。
6.2 连接成功但黑屏/灰屏
这个问题的根源几乎都在xstartup脚本。
首先确认脚本权限:
ls -l ~/.vnc/xstartup必须是-rwx------或者至少带x权限。然后查看VNC的日志:
cat ~/.vnc/*.log常见错误有这么几类:
dbus-launch: command not found:说明dbus工具包没装,dnf -y install dbus-x11补上。ukui-session: command not found:说明UKUI会话组件没装全,dnf -y install ukui补装。Cannot open display或者No screen found:说明X Server本身没起来,检查5901端口是否被其他进程占用,用ps aux | grep Xvnc看进程参数是否正常。
有一个屡试不爽的排查方法:在远程命令行里直接手动跑一遍xstartup里的命令,看报错:
su - dev export DISPLAY=:1 dbus-launch --exit-with-session ukui-session如果这行命令直接报错,问题一目了然;如果能正常启动,说明xstartup脚本本身没问题,问题大概率出在systemd服务的环境变量传递上。
6.3 能连但是提示认证失败
密码不对是最常见的原因,重置一次:
su - dev vncpasswd还有一个小坑:如果你同时在root和普通用户下都跑VNC,VNC密码是分开存储的,root的密码存在/root/.vnc/passwd,dev的密码存在/home/dev/.vnc/passwd。客户端连接时用的是你登录账户对应的那个密码,不要搞混。
6.4 连接后鼠标键盘无响应
这个问题比较少见,但一旦碰到很隐蔽。原因是VNC服务端和桌面环境的输入设备模块冲突。
排查顺序:
- 确认是不是view-only密码连接进来的,如果是,断开重连,输入全权访问密码。
- 确认是否只有鼠标能动但键盘没反应,检查客户端是否有类似的"抓取键盘"的功能被关闭。
- 确认VNC服务是不是以root跑的,如果root的VNC连进去后键盘鼠标都不动,但普通用户正常,那是root的Xauthority文件权限问题:
chmod 644 /root/.Xauthority6.5 桌面卡顿、画面刷新慢
局域网内如果卡顿明显,排查点按优先级排列:
- 分辨率太高:改成1280x720试试。
- 颜色深度太高:
-depth 16能大幅减少带宽占用,虽然颜色会差一点,但流畅度提升明显。 - 网络质量:用
ping -s 1024 服务器IP测一下大包延迟和丢包率。无线网络连VNC的体验通常不如有线,这是物理限制。
6.6 开机后VNC没有自动启动
如果你设置了enable但重启后5901端口没监听,检查一下systemd服务的enable链接是否生效:
systemctl is-enabled vncserver@:1.service systemctl status vncserver@:1.service如果状态是failed,看日志:
journalctl -u vncserver@:1.service很多情况下,VNC自动启动失败是因为用户目录在系统启动早期还没挂载好——再往下想一步,如果用户目录是加密目录或位于独立的挂载点上,WorkingDirectory=/home/dev在启动时找不到路径,自然就崩了。
一个简单粗暴的规避手法是在systemd单元文件里加一行延迟启动:
[Service] ExecStartPre=/bin/sleep 10十秒钟足以让大部分机器的用户目录挂载完成。
7. 安全加固与性能优化
7.1 VNC密码安全问题
VNC的密码传输是加密的,但连接建立后的数据传输默认不加密,在局域网里问题不大,跨公网使用一定要加隧道。
openEuler上最稳妥的做法是配合SSH隧道使用:
ssh -L 5901:localhost:5901 dev@服务器IP然后在本地连接localhost:1,所有流量都走SSH加密通道,安全性和易用性都兼顾。
7.2 限制来源IP
如果你只想让特定几个IP访问VNC端口,防火墙可以做来源限制:
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 port port=5901 protocol=tcp accept' firewall-cmd --reload这条规则的默认行为是覆盖上面添加的--add-port=5901/tcp,实现"只允许192.168.1.0/24网段访问5901端口"的效果。
7.3 通过VNC传输文件
VNC本身不提供文件传输功能。如果你需要往服务器传文件,两个思路:
一是利用VNC客户端自带的功能,RealVNC Viewer有简单的文件传输面板,但体验一般;更推荐的做法是直接用scp或sftp:
scp 本地文件路径 dev@服务器IP:/目标路径二是通过桌面环境自带的文件管理器配合系统挂载,但这个麻烦,不推荐。
8. 最终配置清单与验收
做完以上所有操作后,我整理了一份检查清单,你可以照着逐项验收:
| 检查项 | 命令/操作 | 预期结果 |
|---|---|---|
| 默认启动级别 | systemctl get-default | graphical.target |
| UKUI桌面安装 | rpm -qa | grep ukui | 多个ukui相关包 |
| VNC服务状态 | systemctl status vncserver@:1 | active (running) |
| VNC端口监听 | ss -tlnp | grep 5901 | 有LISTEN记录 |
| 防火墙放行 | firewall-cmd --list-ports | 包含5901/tcp |
| vncpasswd文件权限 | ls -l ~/.vnc/passwd | -rw------- |
| 客户端连接 | VNC Viewer连IP:1 | 能到UKUI桌面 |
在这个项目里踩过最深的一个坑,是xstartup脚本里的DBus环境变量清理。第一次配置时没注意继承环境的问题,结果连上VNC后桌面图标和任务栏都渲染不出来,只看到一个孤零零的壁纸,排查了半天,最后发现就是少了那三行unset和export。希望这篇文章能帮你跳过这个坑。
最后再说一个实用技巧:VNC会话里如果遇到某个程序卡死,可以先在远程命令行里执行ps aux | grep <程序名>找到进程,然后kill掉。这种方法比在桌面里操作右键菜单快得多,尤其是界面完全卡死的时候。VNC的桌面画面卡住,但SSH控制台永远可用,这个双通道的冗余设计,值得你在实际使用中时刻记着。