最近帮朋友处理了几台内网服务器要图形化部署工具的活儿,遇到最多的就是VNC远程桌面的安装问题。要么机器没法联网yum装不了包,要么手动下载rpm包之后被依赖关系折磨到怀疑人生,折腾一整天桌面还是黑屏的。想了下干脆把VNC在线和离线安装的完整流程、rpm包怎么找、依赖怎么处理、服务端怎么配、客户端怎么连,全部串起来写一篇,照着抄就行。
这篇东西适合所有需要在Linux上开远程桌面的朋友,不管是CentOS、Ubuntu还是国产麒麟系统,不管是能联网的环境还是彻底隔离的内网,思路和命令基本都是通用的。我尽量把每一步的原理和坑都讲透,而不是只丢几条命令让你背。
1. 先说清楚:VNC远程桌面到底解决什么问题
1.1 VNC的原理和适用场景
VNC(Virtual Network Computing)的原理其实特别朴素,它把远程主机的屏幕图像通过网络实时转发给客户端,同时把客户端的键盘鼠标事件回传给主机。说白了,你看到的是实实在在的图形桌面画面,不是像SSH那样只能敲命令行。正因为这个特性,VNC最适合的场景就这几类:
- 服务器上跑了图形化配置工具(比如数据库安装向导、磁盘管理工具),人不在机房没法点鼠标;
- 内网隔离环境下的图形应用演示,需要把桌面共享给别的人看;
- 领导或者同事需要远程操作一台Linux桌面,但对方只会用鼠标不会敲命令;
- 虚拟机或云主机没有接物理显示器,出问题时要看到桌面才能排查。
我第一次正经用VNC,是帮一台放在弱电间的CentOS服务器装商业数据库,安装向导是图形界面的,SSH连上去完全没法下一步,最后就是靠VNC一条通道搞定的。所以记住这个定位:VNC是命令行之外的一双眼睛,它不是用来替代SSH做批量运维的,而是专门解决"必须看到图形界面"这类问题的。
1.2 在线安装和离线安装,到底怎么选
这是个决策问题,我的原则很简单:
- 只要目标机器能访问系统自带的软件源,也就是yum/dnf/apt能联网拉到包,一律走在线安装。省事,依赖自动解决,版本也经过发行版测试验证过,出问题概率最低;
- 只有在内网隔离、完全无法访问软件源的场景下,才考虑离线安装,也就是手动把rpm包下载好,拷贝进去再装。
这里有个很大的坑:很多人把"离线"理解成"我有网络只是目标机器没网",然后直接跑到各种下载站随便下了一个VNC的rpm包,拷到服务器上一装,报依赖缺失,再跑去搜另一个依赖包,装完又报还缺,直接陷入依赖地狱。后面我会专门讲怎么系统性地解决依赖问题,避免走这条路。
1.3 服务端软件选型:TigerVNC、RealVNC、x11vnc怎么选
Linux下常见的VNC服务端主要有三个阵营,我直接说结论:
| 服务端 | 维护状态 | 适用场景 | 备注 |
|---|---|---|---|
| TigerVNC | 活跃 | 企业Linux/服务器优先选择 | CentOS/RHEL/Fedora自带仓库就有,systemd管理方便 |
| RealVNC Server | 商业+免费版 | 跨平台、需要加密增强 | 个人免费版够用,但二进制要官网下载 |
| x11vnc | 活跃 | 已有图形桌面、只做镜像转发 | 不创建新会话,只共享当前桌面,性能开销小 |
我默认推荐TigerVNC。原因很直接:主流Linux发行版的仓库里都有,命令统一(vncserver/vncpasswd/vncviewer),systemd单元文件集成度高,配置改动后直接重启服务就行。本文后续所有实操都以TigerVNC为例,其他服务端思路大同小异,命令换个名字而已。
2. 在线安装:yum和apt一分钟装好VNC Server
2.1 RHEL/CentOS系的在线安装
在CentOS 7、RHEL 7、Rocky Linux、AlmaLinux这类系统上,在线安装极其简单,两条命令的事:
# 先确认系统版本,避免下载了不匹配的包 cat /etc/redhat-release # CentOS 7/RHEL 7用yum,CentOS 8+/RHEL 8+建议dnf,命令参数一样 yum install -y tigervnc-server # 或者 dnf install -y tigervnc-server装完检查一下确认成功:
rpm -qa | grep tigervnc能看到类似tigervnc-server-1.13.1-3.el9.x86_64的输出就说明装好了。这里要特别提醒大家区分两个包:tigervnc-server是服务端,tigervnc(不带-server后缀)是客户端工具。你在服务器上只需要装服务端,vncviewer那个客户端通常装在你自己的电脑或跳板机上。
2.2 Debian/Ubuntu系的在线安装
Debian和Ubuntu用的是apt,安装命令也很直接:
# 先更新源索引,再安装 apt update apt install -y tigervnc-standalone-server tigervnc-common这里必须要指出一个版本差异:Ubuntu 18.04及之前的仓库里,默认的VNC服务端包叫vnc4server或者tightvncserver,属于比较老旧的实现了。如果你用的是20.04及以上版本,直接装tigervnc-standalone-server就行。很多网上教程比较老,会教你apt install tightvncserver,在新版系统上虽然也能装,但功能上肯定不如新维护的TigerVNC完整。
2.3 银河麒麟等国产系统的在线安装
现在国产系统的使用场景越来越多,相关提问也特别多。银河麒麟、中标麒麟、统信UOS这些系统的底层来源各不相同,要区别对待:
- 银河麒麟V10(X86架构)底层基于CentOS技术路线,包管理就是yum/dnf,在线安装直接
yum install -y tigervnc-server; - 部分版本的软件源配置不完整,或者内网镜像只同步了基础包,这时候yum可能报找不到包,就只能按离线方案处理;
- ARM架构的机器(比如飞腾、鲲鹏芯片的服务器)安装时要注意包架构是
aarch64,不是x86_64,下错包必然装不上。
遇到国产系统装包失败,我有个小技巧:先看/etc/os-release里的ID和VERSION_ID字段,再用yum repolist检查源是否可用。很多时候问题真不是系统本身,而是源的mirror地址被改成了内网地址但没生效,或者没有对应的发行版源。
3. 离线安装:rpm包下载与依赖处理全流程
这是整篇文章的重头戏,也是标题最大的关键词所在。离线安装VNC本质上就四步:准备环境、找包下载、分析依赖、按序安装。每一步都有讲究。
3.1 准备工作:确认系统版本和架构,别下错包
离线安装的第一步不是下载,而是搞清楚三件事:
- 操作系统的发行版和具体版本号(CentOS 7还是RHEL 8?麒麟V10还是其他?)
- CPU架构(x86_64还是aarch64)
- 需要哪些依赖包、依赖关系怎么理
用这几条命令一次性搞定:
cat /etc/os-release uname -m rpm --versionos-release能看到系统的ID和版本号,uname -m确认架构,rpm --version确认rpm工具本身可用。我见过太多人辛辛苦苦下载了x86_64的rpm包,结果目标机器是ARM架构,或者把el7的包装到el9上,最后装不上还以为是系统坏了。这一步确认好,后面可以少走很多弯路。
3.2 获取rpm包的正确姿势
离线安装的前提是有一台可以联网的"下载机",而且这台下载机的发行版、版本、架构最好和目标机器保持一致。否则你下载的包可能依赖于目标机上根本没有的库,到时候排依赖排到崩溃。
方式一:yumdownloader 自动拉取
在联网机器上,如果配置了和目标机器同版本的软件源,最推荐的方式是:
# 安装yum-utils工具包 yum install -y yum-utils # 下载tigervnc-server,--resolve会把所有依赖一起拉下来 yumdownloader --resolve tigervnc-server加--resolve参数后,yum会把安装这个包所需的所有依赖rpm文件自动下载到当前目录,这会省去大量手动分析依赖的工作。这是我最常用的方式,强烈推荐。
方式二:repoquery查依赖,再单独下载
如果你没有yumdownloader,或者需要精确控制下载哪些包,可以先查依赖清单:
# 安装yum-utils后就有repoquery命令 yum install -y yum-utils # 查看tigervnc-server的完整依赖列表 repoquery --requires --resolve tigervnc-server输出会列出所有依赖包名,然后再用yumdownloader 包名逐个下载。
方式三:直接从镜像站手工下载
没有yumdownloader工具时,也可以直接访问国内各大镜像站,在目录树里按路径找包:
# 以清华镜像源为例,CentOS 7 x86_64的包路径 https://mirrors.tuna.tsinghua.edu.cn/centos/7/os/x86_64/Packages/ # 或者EPEL扩展源路径(部分包在扩展源里) https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/Packages/在页面里搜tigervnc-server,找到类似tigervnc-server-1.8.0-24.el7.x86_64.rpm的文件,右键复制链接下载即可。这种方式适合只缺一两个包的情况,如果依赖链条长,一个个手动找会非常痛苦。
方式四:翻本地缓存碰运气
如果机器以前能联网、只是现在断网了,可以看看/var/cache/yum/(yum缓存)或/var/cache/dnf/(dnf缓存)下有没有缓存的rpm包,有时候系统自动更新留下的缓存正好有你需要的版本。
3.3 rpm命令详解与本地安装
拿到rpm包之后,在下机(联网机器)上可以先做验证,确认包没问题再往目标机器拷:
# 查看rpm包基础信息,确认版本、架构、供应商 rpm -qpi tigervnc-server-1.13.1-3.el9.x86_64.rpm # 查看这个包依赖哪些动态库或能力 rpm -qpR tigervnc-server-1.13.1-3.el9.x86_64.rpm把rpm包通过U盘、scp或者内网共享拷贝到目标机器后,安装命令是:
# 单个包安装(不会自动解决依赖) rpm -ivh tigervnc-server-1.13.1-3.el9.x86_64.rpm # 如果报依赖缺失,可以把多个包一起安装,rpm会一起处理 rpm -ivh tigervnc-server-*.rpm libX11-*.rpm glib2-*.rpm # 强制安装,跳过所有依赖检查(谨慎使用) rpm -ivh --nodeps tigervnc-server-*.rpm提示:
--nodeps是双刃剑。有时候依赖缺失但软件本身能跑,比如某些依赖库只在特定功能下才需要,这时候用--nodeps能快速装完,但可能埋下隐患。我的建议是:先用正常方式装,如果依赖确实卡死,再查清楚缺失依赖的影响面,判断能不能用--nodeps绕过。生产环境慎用,别为了图快把环境搞坏。
3.4 依赖问题的处理策略
依赖问题是离线安装最大的拦路虎。我的实战经验是分层处理:
第一层:先明确缺失的依赖有哪些。
rpm -ivh tigervnc-server-*.rpm # 报错会提示具体缺什么,类似: # error: Failed dependencies: # libXtst.so.6()(64bit) is needed by tigervnc-server-...第二层:查这个动态库或能力属于哪个包。
在联网机器上,用repoquery或者yum provides:
# 查询某个能力由哪个包提供 repoquery --whatprovides 'libXtst.so.6()(64bit)' # 输出通常是:libXtst-1.2.3-1.el9.x86_64 # yum provides也行,效果类似 yum provides 'libXtst.so.6()(64bit)'第三层:补齐下载缺失的依赖包,按依赖层级从底层到顶层安装。先装动态库包,再装主程序包。把所有rpm包放在同一目录然后一次install是可行的,但如果你对依赖顺序没把握,就分开装,一层一层来。
第四层:如果目标机器上连rpm命令都没有,那就参考后面"常见问题"里专门讲的"没找到rpm命令"这节。
4. 服务端配置与启动
装好软件只是第一步,VNC真正能连上还需要配置密码、启动服务、放行防火墙和SELinux。这一节全部走一遍。
4.1 设置VNC密码
VNC的密码不是系统登录密码,而是VNC会话专属的,用vncpasswd命令设置:
# 首次执行会提示输入密码,二次确认,还会问是否设置view-only密码 vncpasswd # 生成的密码文件默认在 ~/.vnc/passwd ls -l ~/.vnc/passwd注意:VNC密码最长8位,超过8位会被截断。这是个很老的限制,但很多人踩坑——设了个16位强密码,后面怎么连都报密码错误,其实是密码被截断了。另外密码里尽量不要用单引号、双引号这类特殊字符,某些客户端解析会出问题。
4.2 首次启动与systemd管理
现在的Linux发行版都推荐用systemd方式管理VNC服务,以CentOS 7/8为例:
# 方法一:直接启动一个会话(简单粗暴,适合临时用) vncserver :1 # 会在5901端口监听(5900+编号N) # 方法二:用systemd管理服务,可以设置开机自启 systemctl start vncserver@:1.service systemctl enable vncserver@:1.service如果是systemd方式,不同发行版的单元文件模板略有差异。CentOS 7下常见的配置是这样的:
# 修改 /etc/systemd/system/vncserver@.service [Unit] Description=Remote desktop VNC service After=syslog.target network.target [Service] Type=forking User=root ExecStart=/usr/sbin/vncserver %i -geometry 1280x720 ExecStop=/usr/sbin/vncserver -kill %i [Install] WantedBy=multi-user.target改完后重新加载并启动:
systemctl daemon-reload systemctl start vncserver@:1.service systemctl status vncserver@:1.service注意:service文件的具体路径以你自己系统上rpm -ql tigervnc-server查到的为准。有些新版TigerVNC的模板在/lib/systemd/system/vncserver@.service或者/usr/lib/systemd/system/,建议复制一份到/etc/systemd/system/再修改,避免升级软件包时模板被覆盖。
4.3 让远程桌面显示正确的图形界面:xstartup配置
这是VNC最容易出问题的环节。VNC启动后会执行~/.vnc/xstartup脚本,这个脚本决定启动什么样的桌面环境。如果脚本内容不对,常见的表现是:能连上但只有一片灰色背景加一个叉形光标,啥图标都没有,看起来就像卡死了一样。
典型配置一:启动GNOME完整桌面
#!/bin/sh unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS exec gnome-session典型配置二:启动Xfce轻量桌面(内网机器经常选这个,占资源少)
#!/bin/sh startxfce4 &典型配置三:只启动一个基础窗口管理器(最保险,但功能少)
#!/bin/sh exec xfce4-session写完记得赋予执行权限,并重启VNC会话让配置生效:
chmod +x ~/.vnc/xstartup # 重启VNC会话 vncserver -kill :1 vncserver :1提示:升级系统或切换桌面环境后,xstartup里的桌面会话名称可能失效(比如gnome-session在新版系统里变成了gnome-session-binary)。遇到这种情况多查日志,日志位置在
~/.vnc/machine:1.log,重点看最后的报错行,里面会直接告诉你哪个命令找不到。
4.4 防火墙与SELinux处理
防火墙是VNC连接超时最常见的原因。VNC默认使用TCP 5900+编号端口,比如vncserver :1对应5901。放行命令:
# firewalld体系 firewall-cmd --permanent --add-port=5901/tcp firewall-cmd --reload # 或者如果有预定义服务,直接添加服务 firewall-cmd --permanent --add-service=vnc-server firewall-cmd --reload如果是CentOS 6时代遗留的iptables工具:
iptables -I INPUT -p tcp --dport 5901 -j ACCEPT service iptables saveSELinux方面,如果开了SELinux且VNC连接一直失败,先看状态:
getenforce # 临时关闭测试(仅排查用) setenforce 0如果确认是SELinux拦截,可以用ausearch -m avc | grep vnc查看审计日志,再针对性调整。虽然一台内网服务器关SELinux影响不大,但我还是建议先定位清楚再处理,别一上来就永久关闭,不健康。
5. 客户端连接与使用
服务端配好了,现在讲讲怎么从自己的电脑连上去。
5.1 VNC Viewer连接
VNC客户端最常用的就是RealVNC出品的VNC Viewer,Windows、macOS、Linux都有对应版本,手机端也有Android和iOS版。下载时要区分平台,不要下错。
连接方式:
# 在客户端机器上输入 vncviewer 192.168.1.100:1 # 或者直接用完整端口写法(推荐,语义更清晰) vncviewer 192.168.1.100:5901首次连接会弹一个未加密连接的警告,点Continue继续。然后输入VNC密码,回车就能看到远程桌面了。如果连不上,大概率是防火墙、端口监听地址或者密码的问题,到第6节对应排查。
5.2 分辨率、色彩深度等常用参数
连接体验和带宽之间需要平衡,特别是内网带宽不高的时候:
- 分辨率:启动服务端时用
-geometry 1280x720指定,或者客户端连接时实时调整; - 色彩深度:
-depth 24画质最好,-depth 16或-depth 8画质会降但带宽占用少; - 局域网内一般
-depth 24毫无压力,跨公网链路、RDP隧道或者移动网络建议从-depth 16起步。
我实际用下来的感受是:VNC对带宽的消耗比RDP要大不少,如果画面频繁变化(比如播放视频),带宽占用会飙升。所以VNC更适合日常操作和维护,用来传输视频流就有点强人所难了。
5.3 多用户与多显示器场景
如果一台服务器要多个用户同时通过VNC登录,可以给每个用户分配不同的显示编号:
# 用户alice启动 vncserver :1 # 用户bob启动 vncserver :2 # 分别对应5901和5902端口查看当前所有会话:
vncserver -list注意一点:一个用户启动的VNC会话,另一个用户知道密码之后也可以连,但实际上操作的是同一个桌面。如果想让每个用户有独立桌面,需要各自用各自的系统账号登录并启动自己的vncserver实例,会话之间互不干扰。
6. 常见问题与排查实录
这一节全是从实际干活里踩坑踩出来的经验,含金量比前面所有命令加起来都高。
6.1 常见问题速查表
| 现象 | 最可能原因 | 排查方法 |
|---|---|---|
| 连接超时 | 防火墙或安全组没放行590x端口 | firewall-cmd --list-ports检查端口 |
| 能连上但黑屏 | xstartup配置不对或桌面环境缺失 | 查~/.vnc/*.log日志 |
| 一直提示密码错误 | 密码超过8位被截断,或大小写不对 | vncpasswd重新设置短密码 |
| 服务起不来 | systemd单元文件配置错误 | systemctl status vncserver@:1.service看报错 |
| 端口占用 | 其他进程已经用了5901 | ss -tlnp | grep 5901确认 |
| 鼠标键盘不响应 | VNC服务异常或会话卡死 | vncserver -kill :1后重启会话 |
| 连接后画面极其模糊 | 色彩深度设太低 | 客户端设置里把depth调到24 |
6.2 没找到rpm命令是什么情况
热词里频繁出现"没找到rpm命令",大概率是两类情况:
第一类:系统压根没有rpm包管理工具。Debian/Ubuntu系列默认用dpkg/apt,不是rpm,安装包后缀是.deb,所以你在Ubuntu里敲rpm命令当然报command not found。解决方案很简单:换用apt安装VNC;如果你确实想用rpm包,需要确认系统是否兼容(比如Ubuntu服务器版装rpm会有不少兼容性问题,不建议这么干)。
第二类:系统是极度精简的容器或定制版,比如某些Docker镜像基于Alpine(包管理是apk)或者裁剪过不带rpm。这种情况先确认发行版,再决定化安装方式,别硬来。
提示:判断一个系统用什么包管理器,最简单的方式就是看安装包后缀:
.deb对应dpkg/apt,.rpm对应rpm/yum/dnf,.apk对应apk。拿rpm去装deb包大概率装不上,这不是你的姿势问题,是工具不匹配。
6.3 连接黑屏/会话登录不显示桌面的排查
黑屏是VNC咨询量最大的问题,没有之一。我的排查路径是固定的:
- 先看日志:
cat ~/.vnc/machine:1.log,日志里会明确告诉你卡在哪一步,最常见的是xfce4-session: command not found或者gnome-session: command not found; - 检查xstartup脚本权限,有没有执行权限:
ls -l ~/.vnc/xstartup chmod +x ~/.vnc/xstartup- 确认系统里是否真的装了对应的桌面环境:
# CentOS系查已安装的桌面组 yum grouplist | grep -i desktop- 尝试最小化验证:把xstartup改成只启动一个xterm终端:
#!/bin/sh xterm &能出终端窗口就说明VNC通道本身是通的,问题出在桌面环境配置上。
后来我还发现一个更隐蔽的坑:登录用户的HOME变量不要乱改,xstartup里的相对路径和权限必须一致。比如VNC用root身份运行,但会话配置放在了某个普通用户目录下,文件找错地方就会一直黑屏。用echo $HOME确认一下当前用户的家目录,再决定去哪个.vnc目录下找配置。
6.4 踩坑记录与独家技巧
最后分享几个实操过才知道的细节:
软件版本兼容问题。TigerVNC新版客户端可以连旧版服务端,但某些加密扩展会不兼容。连不上时,先在客户端设置里关掉TLS加密再试一次。如果关掉就能连上,说明是加密协商的锅,别去折腾服务端。
systemd改了geometry不生效。如果你改了service文件里的-geometry参数,改完必须执行systemctl daemon-reload再重启服务,否则设置不会生效。这个坑很多人踩,以为是配置写错了,其实是systemd缓存了旧的unit文件。
VNC默认监听0.0.0.0,但如果服务启动时因为某种原因只监听127.0.0.1,外部怎么都连不上。建议排查时先看监听地址:
ss -tlnp | grep 5901内网跨网段连接时,如果VNC端口通了但SSH端口不通,不要直接怀疑VNC配置,先确认网络层通不通。ping一下目标主机的VNC端口:
# 在客户端机器上测试TCP端口连通性 timeout 3 bash -c 'echo > /dev/tcp/192.168.1.100/5901' && echo "port open" || echo "port closed"虚拟机或云主机场景,如果防火墙放行了还是连不上,先检查云安全组和网络ACL是不是还有一层拦截。这种问题的典型特征是:本地防火墙已放行、服务监听正常、但外部就是连不上,那大概率就是平台安全策略的问题。
这套东西本质上就是"在线能装就装,离线会找依赖,出问题看日志"。VNC本身不复杂,难的是不同发行版、不同桌面环境、不同网络条件下的组合问题。先把系统确认清楚,再选安装方式,依赖用工具分析而不是瞎猜,配置出问题优先看日志——这套思路换哪个发行版都通用。至于更高级的玩法,比如SSH端口转发配合VNC做加密通道、多显示器下的布局调整,那是基础链路打通之后值得研究的方向,但先把这篇的步骤走通,再说别的。