ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ubuntu 20.04 无人值守VNC:TigerVNC+xfce4配置与排错

Ubuntu 20.04 无人值守VNC:TigerVNC+xfce4配置与排错 远程运维 Ubuntu 20.04 服务器时纯命令行能解决八成问题但总有两成绕不开图形界面跑一个只有 GUI 的烧录工具、调一块开发板的串口上位机、开 IDE 看波形、或者单纯想在一台没接显示器的小主机上看看浏览器。这时候 VNC Server 就是最省事的选择——不用 HDMI 假负载不用把机器搬到工位上一台笔记本连过去就能操作。我在 Ubuntu 20.04 上装过不下二十次 VNC Server从最早的 vino 到 x11vnc 再到现在的 TigerVNC踩过的坑基本能写满一页纸黑屏、灰屏、连上只有个叉形光标、重启后服务没了、剪贴板死活不通。这篇就把整套流程摊开讲一遍包括方案怎么选、xstartup 怎么写、systemd 服务怎么做、出问题怎么查。不管你是刚接触 Linux 的新手还是已经能熟练敲命令的老手都能直接从里面抄到能跑通的配置。1. 方案选型Ubuntu 20.04 上到底该用哪个 VNC1.1 三种主流方案的真实差异很多人第一次装 VNC 是直接搜到哪个教程就用哪个结果装完发现要么黑屏要么重启失效。问题的根源在于Ubuntu 上的 VNC 不是一种东西而是三种思路完全不同的实现选错了后面每一步都在填坑。第一种是vino也就是 GNOME 桌面自带的“屏幕共享”。它挂在已经登录的图形会话上本质是“把当前屏幕画面推出去”。优点是零配置、系统设置里点一下就能开缺点是必须先有人在物理机或自动登录状态下进桌面服务器重启后没人登录就没有画面而且 GNOME 3.36 在 Xorg 下偶尔会拒绝连接。它适合“我就想临时看一眼正在跑的桌面”不适合无人值守。第二种是x11vnc思路是“镜像一个已经存在的 X 会话”。它比 vino 灵活能指定 DISPLAY也能在没人的情况下保持会话但依然依赖 Xorg 会话本身存在。如果你的机器设置了自动登录x11vnc 是挺省心的选择如果没自动登录开机后还是得想办法进桌面。第三种是TigerVNC也就是我最终长期使用的方案。它不依赖任何已存在的桌面会话自己启动一个独立的 Xvnc 进程并在里面拉起一个桌面环境。也就是说只要系统起来VNC 就有画面跟有没有人登录、接没接显示器完全无关。这才是真正意义上的“无人值守远程桌面”。TightVNC 属于同一类但 TigerVNC 在 Ubuntu 20.04 的官方仓库里维护得更勤快剪贴板和性能也更好所以直接用 TigerVNC。方案依赖已登录桌面开机即用独立会话多用户并发配置难度vino是否否否极低x11vnc是视自动登录而定否否中TigerVNC否是是是中TightVNC否是是是中1.2 桌面环境必须换掉 GNOME选了 TigerVNC 之后第二个决策点是桌面环境。这里我要非常明确地说别在 Ubuntu 20.04 的 GNOME 3.36 上硬刚。原因是 GNOME Shell 深度依赖 systemd 的用户会话、dbus、以及一堆 Xorg 之外的运行时资源。当你用 vncserver 起一个独立的 Xvnc 进程时它拿不到完整的用户会话环境结果就是一片黑屏或者只有一个鼠标指针运气好点能看到左上角的“Oh no! Something has gone wrong”。网上有些改法要在 xstartup 里塞 dbus-launch、gnome-session、各种 export改到最后能不能起来全看运气。正确做法是给 VNC 单独装一个轻量桌面xfce4是最平衡的选择启动快、资源占用小、该有的终端和文件管理器都有、对 Xvnc 环境容忍度高。装它不会影响你原本的 GNOME两者可以共存——物理机接显示器时进 GNOME远程连进来看到的是 xfce4互不干扰。如果你习惯 MATE 也可以mate-session 同样跑得起来但 xfce4 的依赖更少出问题的概率更低。1.3 显示编号和端口的对应关系这个细节新手最容易绕晕。TigerVNC 用显示编号:N来标识会话对应的监听端口是5900 N。也就是说:1对应 5901 端口:2对应 5902 端口:3对应 5903 端口客户端连接时写192.168.1.100:1或者192.168.1.100:5901两种写法等价。搞清楚这个换算关系后面排查“端口不通”的时候能省很多时间——你在配置里写的是:1但防火墙里要放行的是5901这两个不对应是最常见的乌龙。2. 动手前的准备把地基打平2.1 环境自检的几条命令养成动手前先看一眼环境的习惯能避免大量“照着教程做却不对”的情况。先确认版本和会话类型lsb_release -a echo $XDG_SESSION_TYPE df -h /第一条确认你确实是 20.04第二条看当前是 x11 还是 wayland如果在物理机上是 wayland 也别慌VNC 起的是独立 X 会话跟这个没关系第三条看根分区剩余空间xfce4 加 TigerVNC 大概要占 500MB 左右空间不够会装到一半失败。再确认网络地址ip a记下目标网卡的 IP 地址后面配置和测试都要用。如果你的机器有多张网卡比如虚拟机常见的 ens33 加 docker0连接时要用能通的那张的地址。提示Ubuntu 20.04 默认的安装镜像可以在官网直接下载服务器版和桌面版都行。服务器版更干净装完再按本文补图形组件反而比桌面版更可控。2.2 更新软件源Ubuntu 20.04 已经有一定年头默认源里的软件版本偏旧装之前建议更新一次sudo apt update sudo apt upgrade -y如果下载速度慢可以换成国内的镜像源。这里只说思路编辑/etc/apt/sources.list把archive.ubuntu.com和security.ubuntu.com替换成国内镜像域名sudo apt update生效。改之前先备份一份原文件改错了能一键还原这是我在任何配置文件上都会做的事。2.3 安装核心组件一条命令搞定sudo apt install -y tigervnc-standalone-server tigervnc-common \ tigervnc-tools xfce4 xfce4-goodies dbus-x11拆开说说每个包的作用方便你判断能不能省tigervnc-standalone-server核心提供vncserver命令和 Xvnc 服务端tigervnc-common公共库和vncpasswd密码工具tigervnc-tools提供vncviewer等客户端工具方便本机自测xfce4轻量桌面环境xfce4-goodies额外的面板插件可选但装了体验更完整dbus-x11提供dbus-launchxfce4 的部分组件比如电源管理、通知需要它dbus-x11这个包经常被教程漏掉结果就是远程桌面里没有声音图标、通知不弹、甚至任务栏缺一块。加上它麻烦少一半。3. 从零配出一个能用的 VNC 桌面3.1 密码设置有个容易忽略的坑设置连接密码vncpasswd它会让你输两遍密码然后问你要不要设置一个“view-only 密码”只读密码一般选 n。密码文件落在~/.vnc/passwd。这里有两个必须注意的点第一密码长度限制是 8 位。TigerVNC 的密码机制基于较老的加密方案超过 8 位会被截断。这不是 bug是协议本身的限制。所以别费劲设 20 位密码会被悄悄砍掉反而让人误以为设了长密码。第二这个密码不等于系统登录密码。它只用于 VNC 握手跟 SSH、sudo 都无关。也正因为如此VNC 密码本身强度不高务必配合下面的访问控制手段使用。如果你的用户没有设置过 VNC 密码直接跑vncserver会提示你先执行vncpasswd这也是新手常见的卡点。3.2 编写 xstartup整个流程里最关键的一步~/.vnc/xstartup是一个 shell 脚本vncserver 启动时会执行它用来决定“会话里跑什么桌面”。默认生成的版本内容很少直接启动会得到一个灰底加 X 光标的空画面。我们要把它替换成适合 xfce4 的版本mkdir -p ~/.vnc cat ~/.vnc/xstartup EOF #!/bin/bash unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS export XDG_RUNTIME_DIR/run/user/$(id -u) [ -x /etc/vnc/xstartup ] exec /etc/vnc/xstartup [ -r $HOME/.Xresources ] xrdb $HOME/.Xresources vncconfig -iconic exec startxfce4 EOF chmod x ~/.vnc/xstartup逐行解释一下这些细节决定了你是黑屏还是能看到桌面unset SESSION_MANAGER和unset DBUS_SESSION_BUS_ADDRESS是为了清掉可能从父进程继承过来的环境变量。如果这些变量指向物理机上正在跑的 GNOME 会话xfce4 会试图去连一个不属于自己的会话总线然后直接崩掉。export XDG_RUNTIME_DIR/run/user/$(id -u)是新版本桌面环境必备的。很多组件包括 systemd 用户实例会去这个目录找运行时资源。默认情况下 Xvnc 不会自动设置它缺了这一行某些版本的 xfce4 会卡在启动画面。vncconfig -iconic 负责打通本地和远程之间的剪贴板。没有它你复制一段命令过去粘贴不了效率会掉一大截。-iconic表示以最小化方式运行不会在桌面上弹个窗口出来。exec startxfce4是最后一步用 exec 替换掉当前 shell 进程让 xfce4 成为会话的主进程。这样退出桌面时整个 VNC 会话也会跟着结束不会留一堆僵尸进程。还有一个版本相关的重要提醒Ubuntu 20.04 仓库里的 TigerVNC 是 1.10.xvncserver默认只监听本地回环地址localhost。也就是说装完之后从别的机器连是连不上的。解决办法是启动时加参数或者写进配置文件见下一节。3.3 用配置文件替代一长串命令行参数每次启动都敲一长串参数容易出错TigerVNC 支持从~/.vnc/config读取默认值cat ~/.vnc/config EOF sessionxfce geometry1920x1080 depth24 localhostno alwaysshared EOFgeometry是分辨率按你客户端屏幕大小来设别盲目上 4K网络带宽吃不住depth24是色深24 位比默认的配置视觉效果好很多代价是流量略增localhostno是 1.10 版本的关键参数允许非本机连接alwaysshared允许多个客户端同时连同一个会话调试的时候两个人一起看很方便。注意TigerVNC 在较新的版本1.13 以上里把参数写法改成了localhost0或-localhost no如果你以后升级了系统版本这条参数可能需要调整遇到连不上先检查这里。3.4 第一次启动与验证启动第一个会话vncserver :1正常的话会输出类似这样的信息New hostname:1 (user) desktop is hostname:1 Starting applications specified in /home/user/.vnc/xstartup Log file: /home/user/.vnc/hostname:1.log记住这个日志路径后面所有问题的答案基本都在里面。启动失败、黑屏、桌面起不来第一件事就是tail -50 ~/.vnc/hostname:1.log比在网上瞎搜快得多。查一下端口有没有监听ss -tlnp | grep 5901看到LISTEN就说明服务在跑。本机可以用自带的 vncviewer 连127.0.0.1:1试一下画面出来了再换远程机器连。4. 做成开机自启的系统服务4.1 手写一个 systemd 单元文件手动敲vncserver :1只适合调试服务器重启后会话就没了。要让它开机自启用 systemd 管理是最规范的方式。新建/etc/systemd/system/vncserver.service[Unit] DescriptionRemote desktop service (VNC) Aftersyslog.target network.target [Service] Typeforking Useryouruser Groupyouruser WorkingDirectory/home/youruser PIDFile/home/youruser/.vnc/%H:%i.pid ExecStartPre-/usr/bin/vncserver -kill :%i /dev/null 21 ExecStart/usr/bin/vncserver :%i ExecStop/usr/bin/vncserver -kill :%i [Install] WantedBymulti-user.target把youruser换成你的实际用户名两处都要换。这里用了模板服务的写法%i会被替换成实例编号也就是说这一个文件能管:1、:2任意多个会话不用为每个编号写一份。Typeforking配合PIDFile是必须的因为 vncserver 会 fork 出后台进程后自己退出systemd 需要知道真正的进程号才能正确判断服务状态。ExecStartPre前面那个减号表示“这一行失败也不算错”作用是先清理可能残留的旧会话避免重启时报“会话已存在”。4.2 启用与验证sudo systemctl daemon-reload sudo systemctl enable --now vncserver1.service sudo systemctl status vncserver1.service看到绿色的active (running)就成功了。停掉和重启分别是sudo systemctl stop vncserver1.service sudo systemctl restart vncserver1.service如果状态是failed先用journalctl -u vncserver1.service -n 50看系统层日志再配合~/.vnc/*.log看应用层日志两边对照基本能定位到根因。我遇到最多的是权限问题~/.vnc目录属主不对或者xstartup忘了加执行权限。4.3 多用户和多会话的场景如果这台机器要给三个人用每人一个独立桌面做法是给每个用户都配一遍vncpasswd和xstartup然后启用不同编号的实例sudo systemctl enable --now vncserver1.service sudo systemctl enable --now vncserver2.service sudo systemctl enable --now vncserver3.service不过要提醒一句模板文件里的User是写死的一个实例文件只能对应一个用户。多用户场景更省事的做法是每个用户在自己账号下用systemctl --user管理把单元文件放到~/.config/systemd/user/下这样天然隔离互不影响。我自己的习惯是单用户机器用系统级服务多人共用的开发机用用户级服务管理起来更清爽。5. 常见问题排查实录5.1 黑屏、灰屏、只有一个 X 光标这是最高频的问题基本三个原因桌面环境没起来。看日志有没有startxfce4: command not found如果有就说明 xfce4 没装上或者 xstartup 里的路径不对。用绝对路径/usr/bin/startxfce4能排除 PATH 问题。XDG_RUNTIME_DIR 缺失或权限不对。检查/run/user/$(id -u)是否存在、属主是不是你自己、权限是不是 700。不对的话手动修sudo chmod 700 /run/user/$(id -u) sudo chown $(id -u):$(id -g) /run/user/$(id -u)dbus 相关组件缺失。装dbus-x11不行再补xfce4-session。如果画面是灰底加网格加一个叉形光标那基本可以确定是 xstartup 没被执行或者执行失败。检查chmod x有没有做以及脚本里的换行符是不是 Windows 格式从网页复制粘贴有时会带 CRLF用dos2unix转一下。5.2 连不上、连接被拒绝、超时按这个顺序查能覆盖九成情况第一步确认端口在监听ss -tlnp | grep 5901。没有输出说明服务根本没起来先解决服务本身的问题。第二步确认监听地址。如果显示的是127.0.0.1:5901而不是0.0.0.0:5901那就是localhostno没生效。1.10 版本必须在~/.vnc/config里写这一行光在命令行加参数可能被覆盖。第三步检查防火墙。Ubuntu 的 ufw 默认是关闭的但如果你开过需要放行sudo ufw status sudo ufw allow from 192.168.1.0/24 to any port 5901 proto tcp这里我特意用了带来源网段的写法而不是简单allow 5901因为 VNC 协议本身的认证机制比较弱把它暴露给整个网络不是个好主意。限定内网网段风险可控。第四步确认客户端地址写对了。192.168.1.100:1和192.168.1.100:5901是等价的但写成192.168.1.100:1在有些客户端上会被误解成端口 1保险起见用5901这种显式端口写法。5.3 剪贴板不通、中文输入法用不了剪贴板的前提是 xstartup 里有vncconfig -iconic 。加上之后重启会话本地复制的内容就能粘到远程终端里。有些客户端还需要在设置里勾上“发送剪贴板”之类的选项各家叫法不同找找看。关于输入法xfce4 默认的键盘布局只有英文。如果你需要中文输入装 ibus 或者 fcitx 都可以注意两点一是要在 xstartup 里配合设置GTK_IM_MODULE/QT_IM_MODULE/XMODIFIERS三个环境变量二是要把输入法守护进程也拉起来。这部分和物理机上的配置逻辑一样改完重启 VNC 会话生效。如果装完发现候选框不显示多半是环境变量没设全。5.4 问题速查表症状最可能的原因处理方向黑屏 / 只有光标xstartup 未执行或无执行权限chmod x ~/.vnc/xstartup查日志灰屏加网格桌面环境启动失败装 xfce4改用绝对路径启动连不上超时只监听 127.0.0.1配置localhostno端口拒绝防火墙未放行ufw allow ... port 5901重启后服务消失没做 systemd 自启写单元文件并 enable启动报“会话已存在”pid 文件残留vncserver -kill :1后重启剪贴板不互通缺 vncconfigxstartup 中加vncconfig -iconic 画面卡顿分辨率或色深过高降到 1920x1080 / depth 16还有几个零碎但很有用的小技巧如果vncserver -kill :1报找不到进程但端口还占着直接sudo rm -f ~/.vnc/*.pid再启动如果重启后连上发现桌面还是上次的残局那是 Xvnc 进程没被干净杀掉pkill Xvnc一次再起服务如果在虚拟机里跑记得把虚拟机的网卡模式设成桥接或者端口转发否则宿主机根本看不到这个 IP。6. 安全与性能上的几个实用取舍6.1 访问控制比密码更重要前面说过 VNC 的密码机制天生只有 8 位强度有限。真正兜底的是访问控制我的组合是这样防火墙只放行内网网段绝不对公网开放 5900-5910 这段端口用ufw的源地址限制把访问来源收窄到具体几台机器需要从外部访问时先通过 SSH 登录到跳板机再从跳板机连内网 VNC不把 VNC 端口直接暴露另外~/.vnc/passwd文件权限确保是 600属主是自己。vncpasswd默认会设好但手动改过目录权限之后值得再确认一次。6.2 分辨率、色深与流量的平衡远程桌面的流畅度直接取决于三个参数的乘积分辨率 × 色深 × 画面变化频率。我在局域网里用 1920x1080 / depth 24体验接近本地跨网段或者带宽紧张时降到 1440x900 / depth 16字会有点颗粒感但操作不卡。如果只需要跑命令完全没必要开整个桌面用 SSH 就够了VNC 留给真正需要图形界面的场景。这是最容易被忽视的“性能优化”——不是调参数而是选对工具。还有一个很多人不知道的选项TigerVNC 支持在会话中动态调整画质客户端上一般有 Low / Medium / High 之类的档位感觉卡就往下调一档比重启服务快得多。6.3 网络受限时的几个替代思路有些环境里 VNC 端口就是不让开这时候有几条路可以走。一是在本机用 X11 转发通过 SSH 的-X参数把单个图形程序显示到本地适合“只要跑一个 GUI 工具”的场景比整套远程桌面轻得多。二是用 Web 化的方案把 VNC 转成浏览器可访问的形式省去装客户端。三是干脆改用其他远程桌面协议某些方案在图形传输效率上比 VNC 做得好代价是服务端配置更复杂。选哪种取决于你的真实需求要整套桌面还是只要一个程序要长期驻留还是临时用一次。我自己的判断标准很简单——如果需要图形界面超过半小时上 VNC只是偶尔点几下SSH 加 X11 转发就够了。我在多台机器上反复装这套流程之后最大的体会是大部分问题都出在 xstartup 和 localhost 这两个地方把这两个点吃透Ubuntu 20.04 上的 VNC 就没什么神秘的了。还有个小习惯值得分享——每次改完配置先vncserver -kill :1干净退出再用 systemctl 重启比直接 restart 少踩很多“配置没生效”的坑。最后提醒一句改~/.vnc/config之前记得备份原文件这东西改错了排查起来比想象中费时间。
返回列表