ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VNC Viewer连接Linux:TigerVNC/x11vnc配置与排错

VNC Viewer连接Linux:TigerVNC/x11vnc配置与排错 一台常年放在机房角落的 Linux 主机显示器没人看但里面的图形化工具、打包好的测试程序、只有 GUI 才能跑的临时脚本又必须用或者你人在外地要临时看一眼家里那台装了 Linux 的开发机。这类场景下VNC Viewer 连接 Linux几乎是最省事的一条路。我在 Debian、Ubuntu、Rocky、CentOS 以及各种云主机镜像上来回折腾过十几轮 VNC Viewer 的配置踩过的坑从端口不通到连上但黑屏再到能用却卡得像放幻灯片最后发现真正决定成败的往往不是软件本身而是几个极易被忽略的细节服务端到底监听在哪个地址、桌面跑在 X11 还是 Wayland、显示号和端口的对应关系有没有搞反。这篇就把整套流程从头到尾捋一遍——服务端选型、安装、配置、开机自启到客户端 VNC Viewer 的实用设置以及连不上时按什么顺序逐步排查。刚接触 Linux 的新手可以照着抄需要给团队批量开远程桌面的运维也能拿去改。1. 先理清 VNC 的完整链路别急着装软件1.1 RFB 协议和 5900 端口的那点对应关系VNC 这个词其实是 Virtual Network Computing 的缩写底层跑的是 RFBRemote Framebuffer协议。它的工作方式很朴素服务端把屏幕这块帧缓冲区的变化切成一堆小矩形块编码压缩后推给客户端客户端把鼠标移动、键盘敲击这些事件回传回去。所以你看到的画面本质上是服务端一遍遍截图发过来的结果这也解释了为什么 VNC 在播放视频、拖动窗口时会明显发涩——它天生就不是为高帧率画面设计的。理解这一点之后端口的事就好办了。VNC 用到的是5900 起步的一串端口规则是5900 显示号。显示号是 VNC 自己的一套编号跟物理显示器没关系它更像这是第几个虚拟桌面的序号。很多人第一次配置失败就是栽在这个映射上VNC 显示号实际监听端口典型来源:05900共享当前物理屏幕x11vnc 默认:15901第一个独立虚拟会话:25902第二个会话或多用户并行在 VNC Viewer 里填地址的时候192.168.1.20:1表示连显示号 1也就是 5901 端口而192.168.1.20::5901是两个冒号表示直接指定端口号。这一个冒号和两个冒号的区别能让人抓狂半小时我见过不止一次。1.2 图形会话不是服务Wayland 带来的第一道坎在 Linux 上桌面这个词的含义和 Windows 完全不同。X11 时代的设计是客户端-服务端反过来的真正跑在远端的是 X Server负责画图你的程序反而是 X Client。所以DISPLAY:1这样的环境变量决定了图形程序往哪儿画。VNC 服务端要做的事就是自己起一个虚拟的 X Server比如 TigerVNC 的 Xvnc 进程然后让桌面环境往上画。问题出在新版系统上。现在的 GNOME、KDE 默认跑的是Wayland而 Wayland 出于安全设计不允许普通程序随便抓取整个屏幕的帧缓冲。这就导致两个后果一是想在 Wayland 会话里共享当前物理屏幕工具会各种报错或者抓到一片黑二是像 x11vnc 这类依赖 X11 抓屏的方案在纯 Wayland 下基本失效。动手之前先确认一下当前的会话类型一条命令的事echo $XDG_SESSION_TYPE loginctl show-session $(loginctl | grep $(whoami) | awk {print $1}) -p Type如果输出是wayland那你有两条路要么在登录界面切回 X11 会话GNOME 登录界面右下角那个齿轮里选 GNOME on Xorg要么放弃共享物理屏的思路改用 TigerVNC 起一个独立的虚拟会话。后者其实是更推荐的做法理由在下一节展开。2. 服务端选型TigerVNC、x11vnc 和桌面自带方案的取舍2.1 TigerVNC独立会话适合长期挂着TigerVNC 是我在绝大多数场景下的首选。它的核心卖点是每个连接可以是一个完全独立的虚拟桌面跟物理屏幕上登录着谁、有没有人坐在机器前一点关系都没有。你可以同时给三个同事各开一个 :1、:2、:3互不干扰也可以自己开一个专门用来跑长任务的图形会话下班回家接着看。它依赖的是自带的 Xvnc 进程本质上是一个集成了 VNC 能力的 X Server所以在 Wayland 系统上照样能跑——因为 Xvnc 本身就是 X11 的实现跟登录会话是不是 Wayland 无关。性能上TigerVNC 的编码器更新比较积极Tight、ZRLE 这些编码在普通办公场景下延迟可以接受色彩深度调低之后跨区域用也不算太难受。2.2 x11vnc共享当前物理屏幕适合现场救火x11vnc 的定位完全不同它不创建新会话而是把已经存在的那块屏幕转发出去。你在 VNC Viewer 里看到的就是坐在机器前的人正在看的画面鼠标是同一只剪贴板也是同一个。这个特性在某些场景下无可替代——比如机器上跑着一个必须本地登录才能启动的授权软件或者需要给同事演示操作过程再或者远程协助时让对方看着你动手。代价是它天然只能有一个屏幕多用户同时连上来看到的是同一幅画面而且强依赖 X11。在纯 Wayland 会话下它基本没法用。所以我的习惯是长期远程用 TigerVNC临时救火用 x11vnc两个都装按需启动互不冲突注意别抢同一个显示号。2.3 装之前先确认桌面环境别连上才发现是空壳有一个坑特别常见服务器版系统装完根本没有图形桌面你把 VNC 服务端跑起来了连上去只有一片灰底加一个鼠标。因为 VNC 只是把画面传出去画面里有什么内容得靠桌面环境提供。最小化安装的桌面我推荐XFCE 或 LXDE。原因是它们内存占用低XFCE 完整跑起来大概两三百兆在 VNC 这种带宽敏感的场景下渲染负担小、画面刷新更利索。GNOME 也能用但一个 GNOME 会话动辄吃掉七八百兆内存加上动画特效通过 VNC 传输时会明显发顿。以 Debian/Ubuntu 系为例一次性把该装的装上sudo apt update sudo apt install -y tigervnc-standalone-server tigervnc-common \ xfce4 xfce4-goodies dbus-x11 xtermRocky / CentOS / Alma 这边sudo dnf install -y tigervnc-server xorg-x11-xinit xterm # 桌面环境自行选择 sudo dnf groupinstall -y Server with GUI注意dbus-x11这个包在很多教程里被漏掉但少了它桌面里的电源管理、通知、部分应用的启动都会莫名其妙失败表现就是桌面能进但点什么都弹不出来。3. 把服务端真正跑起来账户、配置、systemd 三件套3.1 专用账户与密码文件权限比内容更重要我的建议是不要用 root 直接开 VNC 会话。原因有二一是 root 的图形会话一旦被连上等于把整台机器交出去了二是很多桌面组件在 root 下会拒绝启动或者告警。建一个专用账户比如就叫vncusersudo useradd -m -s /bin/bash vncuser sudo passwd vncuser接着切到这个账户下生成 VNC 密码su - vncuser vncpasswdvncpasswd会问你两次密码还会问一句是否设置仅查看密码view-only password。这个只读密码很有用给别人演示时用只读密码对方只能看不能动。生成出来的文件在~/.vnc/passwd权限必须是 600否则 TigerVNC 启动时会直接拒绝chmod 600 ~/.vnc/passwd顺便说一句 VNC 密码的长度限制——旧版协议只取前 8 位虽然后来的版本支持更长密码但如果你在混合版本环境里用最好还是把密码当成 8 位有效来设计。更重要的是VNC 自身的密码认证强度很弱这一点第 5 节会专门讲怎么补救。3.2 ~/.vnc/config 和 xstartup 里真正该改的几行TigerVNC 在新版里把配置从命令行参数挪到了配置文件位置是~/.vnc/config。这个文件不用写太多写多了反而容易出错sessionxfce geometry1920x1080 depth24 localhost alwaysshared逐行解释一下我的取舍sessionxfce只是个标记真正决定启动什么的是 xstartup 脚本但某些发行版的启动脚本会读这个值写上不亏。geometry是虚拟屏幕分辨率。这里有个经验不要设得比客户端窗口还大太多否则你在小屏笔记本上连过去要么得不停滚动要么缩放后糊成一片。1920x1080 是个稳妥的默认值。depth24是色彩深度。16 位能省带宽但渐变会有色带24 位画质好、带宽翻倍局域网内建议直接 24。localhost这一行是安全开关让服务端只监听 127.0.0.1。这意味着必须通过 SSH 端口转发才能连上裸连是连不通的。初次调试时可以先把这行注释掉等确认能连上了再加回来。alwaysshared允许多个客户端同时看同一个会话比如你连一个、同事连一个不加的话默认是独占的第二个人连上来会被踢。然后是~/.vnc/xstartup这是整个配置里最关键的文件它决定了会话启动后到底跑什么#!/bin/sh unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS [ -x /etc/vnc/xstartup ] exec /etc/vnc/xstartup [ -r $HOME/.Xresources ] xrdb $HOME/.Xresources exec startxfce4写完记得加执行权限这一步漏掉的话症状就是能连上、能看到灰底、但点什么都没反应chmod x ~/.vnc/xstartup3.3 用 systemd 管理多实例顺便解决开机自启手动敲vncserver :1能用但机器一重启就没了而且进程崩了不会自动拉起来。正规做法是交给 systemd。在 RHEL 系Rocky、CentOS、Alma、Fedora里TigerVNC 自带一个模板服务vncserver.service你只需要把用户和显示号的映射写进/etc/tigervnc/vncserver.users:1vncuser :2devuser然后启动、设置开机自启sudo systemctl daemon-reload sudo systemctl enable --now vncserver:1.service sudo systemctl status vncserver:1.serviceDebian/Ubuntu 这边没有现成的模板需要自己写一个用户级 unit放在~/.config/systemd/user/vncserver.service[Unit] DescriptionTigerVNC Service Aftersys.target [Service] Typeforking ExecStartPre-/usr/bin/vncserver -kill :%i /dev/null 21 ExecStart/usr/bin/vncserver -depth 24 -geometry 1920x1080 :%i ExecStop/usr/bin/vncserver -kill :%i [Install] WantedBydefault.target用户级服务有个容易忽略的点必须开启 linger否则用户一登出服务就被系统回收了。loginctl enable-linger $USER systemctl --user enable --now vncserver.service3.4 分辨率、色深和桌面参数之间会互相打架有几组参数是会相互影响的分开看都对凑一起就出问题第一组是分辨率与缩放。服务端设 1920x1080客户端屏幕只有 1366x768VNC Viewer 默认会做缩放适配文字会有点虚。如果在意清晰度把服务端geometry降到和客户端一致反而更舒服。第二组是色深与压缩等级。24 位色深加高压缩画质好但 CPU 吃得凶16 位色深加低压缩CPU 轻松但画面有块状感。老机器上我一般选 16 位 中等压缩毕竟流畅比好看重要。第三组是桌面环境的合成器。XFCE 的窗口特效如果全开通过 VNC 拖动窗口会有明显拖影。在 XFCE 的窗口管理器微调里把合成器关掉或者干脆选无合成画面会利索很多。这个调整在本地用几乎无感但在 VNC 里差别很明显。4. 第一次连接就连不上按这个顺序查4.1 先看端口到底监听在哪儿排查永远从最底层开始。在服务器上执行ss -lntp | grep 590会看到类似LISTEN 0 5 127.0.0.1:5901或者LISTEN 0 5 0.0.0.0:5901的输出。这里的地址决定了你能不能远程连上如果是127.0.0.1说明开了localhost限制只能从本机或者经过端口转发访问如果是0.0.0.0或::才允许外部直接连。很多人会碰到这种情况配置文件里明明注释掉了localhost重启服务后还是监听在 127.0.0.1。原因通常是显示号对应的旧进程没被杀干净新进程启动失败端口还挂在旧进程上。这时候先手动杀掉再重启vncserver -kill :1 rm -f /tmp/.X11-unix/X1 /tmp/.X1-lock systemctl restart vncserver:14.2 防火墙和 SELinux 放行两个都别漏端口监听对了接下来是防火墙。firewalld 环境下sudo firewall-cmd --permanent --add-port5901/tcp sudo firewall-cmd --reloadufw 环境下sudo ufw allow 5901/tcp但 RHEL 系还有一关SELinux。它默认只允许 VNC 监听几个固定端口你换个非常规端口服务就会静默失败。查一下有没有被拦sudo ausearch -m avc -ts recent要放行新端口可以给端口打上 VNC 的标签sudo semanage port -a -t vnc_port_t -p tcp 5905这一步属于典型的日志里看不出问题、但就是连不上的坑我在这上面浪费过整整一个下午。4.3 黑屏、灰屏、一闪而退日志写着答案VNC 连上之后的三种典型异常症状很像原因完全不同。日志位置在~/.vnc/*.log每次启动的报错都写在那儿排查的第一动作就是 tail 这个文件。现象大概率原因验证方式一片黑只有鼠标桌面环境没启动成功或启动脚本报错看日志末尾的exec报错一片灰有个终端窗口只启动了 xterm没启动窗口管理器检查 xstartup 最后一行连上瞬间断开显示号冲突或 X 锁文件残留ls /tmp/.X*-lock第一种情况最常见的原因是startxfce4找不到。可能是包没装全也可能是 PATH 在 systemd 环境下和交互式 shell 不一样。解决办法是在 xstartup 里写全路径exec /usr/bin/startxfce4用which startxfce4确认一下路径再写。第二种灰屏是新版 TigerVNC 的默认 xstartup 就是只起一个 xterm如果安装时覆盖了自己的配置就会变成这样。重新写好 xstartup 即可。第三种一闪而退多半是残留的锁文件。前面 4.1 里那两条rm -f就是干这个的。4.4 密码明明对认证却被拒绝密码肯定没错这句话我在自己身上和同事身上都听过无数次最后查出来的原因五花八门密码文件路径不对。systemd 启动时用的 HOME 可能不是你预期的那个导致读的是别的用户的~/.vnc/passwd。用systemctl cat vncserver:1看看实际执行了哪些参数。权限过宽。~/.vnc/passwd权限不是 600服务端会直接忽略它。客户端缓存了旧密码。VNC Viewer 会把密码存在本地改过服务端密码之后客户端还在拿旧的试。删掉保存的连接重新建一个最快。认证类型不匹配。有些服务端默认只开VncAuth某些客户端默认走别的协商方式。可以在配置里显式加一行SecurityTypesVncAuth减少协商环节。小技巧判断到底是网络问题还是认证问题看客户端报的是 connection refused、timed out 还是 authentication failed。拒绝连接是端口没开超时是防火墙或路由拦了认证失败才是密码的事。三个词对应三个阶段能省下大量瞎试的时间。5. 让 VNC 用得不那么危险隧道、只读和限权5.1 别把 5901 裸奔在公网上VNC 协议设计于上世纪九十年代它自带的密码认证强度不高而且很多编码和握手过程是明文的。直接把 5900 段端口暴露在公网等于给整台机器开了扇没锁的门扫描器几小时内就能找上门。所以只要不是纯内网环境我的做法一律是服务端只监听 127.0.0.1走 SSH 端口转发访问。服务端配置里保留localhost那一行然后客户端这边先建立转发ssh -L 5901:127.0.0.1:5901 -N -f vncuser192.168.1.20这条命令的意思是把本地的 5901 端口通过 SSH 通道转发到远端本机的 5901。跑完之后在 VNC Viewer 里连127.0.0.1:1就行了。整个传输过程被 SSH 加密而且这台机器的 5901 端口对外根本不可见扫描器扫不到。Windows 上用 VNC Viewer 的话可以先开一个终端窗口执行转发命令保持窗口不关或者用系统自带的 SSH 客户端配合配置文件。VS Code 的 Remote-SSH 也能起到类似效果它建立的连接本身就带端口转发能力。5.2 只读模式和视图控制的实际用法vncpasswd那个仅查看密码不是摆设。生成之后你有两个密码完整密码和只读密码。给别人看演示、做培训的时候给只读密码对方能看全屏但动不了鼠标避免误操作。在服务端也可以用-viewonly参数直接锁死整个会话这种模式下所有人都是只能看。反过来如果想让某个会话只允许一个人操作就不要加alwaysshared。另外 VNC Viewer 的菜单里有个 View only 勾选项那是客户端侧的防的是自己手滑——比如你在看远端跑着的生产任务怕鼠标误点。5.3 会话权限的边界比你想的更重要一个经常会遇到的认知误区以为 VNC 会话是个超级终端。实际上通过 VNC 连上去得到的权限就是启动这个会话的那个用户的权限。用vncuser起的会话就只能操作vncuser有权限的文件装软件照样要 sudo 密码。这其实是好事。给临时协作的人开一个低权限账户的 VNC 会话再配只读密码风险可控。千万别图省事用 root 开会话——一旦密码泄露等于把整台机器交出去。我见过有团队为了方便运维直接给 root 开了 VNC 并暴露在办公网这种做法在合规检查里基本一票否决。6. VNC Viewer 客户端的实用设置别忽略这一半6.1 新建连接时最容易填错的两栏VNC Viewer 新建连接只有两栏地址和名称。名称随你写地址才是关键。这里再强调一次那个冒号规则192.168.1.20:1→ 显示号 1 → 实际连 5901 端口192.168.1.20:2→ 显示号 2 → 实际连 5902 端口192.168.1.20::5901→ 双冒号 → 直接指定端口号 5901如果你走了 SSH 转发地址栏就填127.0.0.1:1。这时候本地转发端口如果被占用改成127.0.0.1::15901这种形式同时把 SSH 命令里的本地端口也换成 15901ssh -L 15901:127.0.0.1:5901 -N -f vncuser192.168.1.20密码记住那个选项建议按机器区分对待。自己的开发机勾上无所谓共享的测试机我一般不勾免得换人之后还要去清缓存。6.2 色彩等级、压缩与缩放的实测取舍VNC Viewer 的属性里有一组 Picture quality 设置从 Low 到 Full 分几档。它的原理是等级越低服务端用的编码越激进、允许丢弃的颜色越多。色彩等级大致色深带宽感受我的使用场景Full24 位最高局域网够用看设计稿、调颜色Medium16 位中等跨区域可接受日常开发、写代码Low8 位最低画面有块状感网络很差时应急缩放Scaling这一栏局域网内我一般关掉适配让画面 1:1 显示只有当客户端屏幕比服务端小时才打开 Scale to fit window。注意缩放是客户端做的服务端照样按原分辨率渲染所以并不会省带宽只是让你不用拖滚动条而已。6.3 剪贴板、全屏和快捷键冲突VNC 的剪贴板是双向同步的但同步的不是剪贴板历史只是当前那一条内容。常用的几个交互按下功能键多数版本是 F8会弹出连接菜单里面有发送 CtrlAltDel、切换全屏、断开连接等选项。全屏模式在客户端侧是快捷键但你的输入会被送回服务端所以本地快捷键可能失效。从本地往远端粘贴大段文本时偶尔会卡顿原因是剪贴板内容被拆成多次小包传输。粘贴几百行的配置文件时建议直接用 scp 传文件别硬贴。还有一个容易踩的服务端和客户端的键盘布局不一致。你本地是中文键盘布局服务端是英文布局敲|、~、这些符号就会错位。解决方式是在服务端把键盘布局显式设置成和你一致XFCE 里在键盘设置里改命令行可以setxkbmap us或setxkbmap cn试一下。7. 挂久了才暴露的问题残留、资源和配置覆盖7.1 会话残留与僵尸 Xvnc 进程VNC 服务端跑上几周之后最容易出现的问题是显示号被占着但进程其实已经异常。表现是重启服务失败报 A VNC server is already running as :1。清理步骤我整理成一个固定流程vncserver -kill :1 ps aux | grep -i Xvnc rm -f /tmp/.X1-lock /tmp/.X11-unix/X1 ls -la ~/.vnc/ # 检查有没有残留的 .pid 文件如果ps里还能看到Xvnc进程但kill不掉那就kill -9强杀。这些 .pid 和 .lock 文件都放在 /tmp 下某些系统的 /tmp 会被定期清理如果清理时正好在会话运行中服务就会处于一种进程活着但没有锁文件的诡异状态重启才能恢复。7.2 内存和 CPU桌面环境选型的长期代价长期挂着的 VNC 会话内存占用是绕不开的话题。我实测过几组数据都是空桌面加一个终端仅供参考桌面环境空闲内存占用VNC 下的拖动流畅度LXDE约 150 MB很流畅XFCE约 250 MB流畅MATE约 350 MB流畅GNOME约 800 MB 以上一般需关特效如果是小内存云主机1GB 或 2GB我建议直接用 XFCE 甚至 LXDE把省下来的内存留给真正要跑的业务。另外把桌面里的屏保、自动锁屏、索引服务tracker、baloo 这类关掉它们在后台定时跑会通过 VNC 把画面刷来刷去白白吃掉带宽。7.3 系统升级覆盖配置怎么提前防最后说一个容易让人措手不及的情况。~/.vnc/xstartup和~/.vnc/config这两个文件在某些发行版的包升级时会被覆盖成默认版本。升级之后你发现昨天还好好的今天连上又是灰屏基本就是这个原因。我的习惯是把整个~/.vnc目录纳入版本管理或者至少做一份备份副本cp -r ~/.vnc ~/.vnc.bak.$(date %Y%m%d)系统级配置被覆盖时包管理器通常会留下.rpmnew或.dpkg-dist后缀的文件升级后扫一眼/etc/tigervnc/和~/.vnc/发现这类后缀就说明配置文件被替换了需要把改动重新合并回去。另外那个/etc/tigervnc/vncserver.users里的用户名映射在账户改名或删除之后不会自动清理会留下一条指向不存在用户的记录表现为服务启动时报 user does not exist。定期对一遍实际账户列表能省掉不少莫名其妙的报错。我个人在实际部署中的体会是VNC 这套东西的复杂度不在安装而在环境差异——同一份配置文件在 X11 和 Wayland 下、在 RHEL 系和 Debian 系下、在有 SELinux 和没有 SELinux 的机器上行为完全不同。把这几条外部条件先摸清楚剩下的事情其实只有三步监听地址调对、显示号对应无误、认证方式统一。真连不上的时候别急着改配置先tail一眼~/.vnc里的日志九成的问题答案都写在那儿了。
返回列表