1. 为什么还要折腾一台老系统的远程桌面
手里头还跑着 Ubuntu 14.04 的机器,说实话现在不算少见。很多做嵌入式开发的、搞工控设备的、维护老旧测试平台的朋友,手上总有一两台“不能动”的机器——系统版本锁死,内核不能升,一升级整套业务就跑不起来。这种机器通常放在机房角落或者实验室架子底下,平时没人给它接显示器,但偶尔又需要进去点两下图形界面,比如调个老版本的 IDE、跑个带界面的测试工具、或者给不熟悉命令行的同事演示一下操作流程。
这时候远程桌面就是刚需。SSH 能解决 90% 的问题,但剩下那 10% 的图形化操作,SSH 真替不了。VNC 就是干这个的:它把整台机器的桌面画面通过网络传到你本地,你在自己电脑上就能操作那台远端的机器,跟坐在它面前一样。
这篇内容就是围绕“在 Ubuntu 14.04 上把 VNC server 跑起来”这件事展开的。我会把整个安装、配置、启动、排错的链路讲透,包括为什么选 TightVNC 而不是别的、桌面环境怎么配、开机自启怎么做、以及那些年我踩过的坑。适合手上正好有老系统需要远程桌面的人,也适合想搞明白 VNC 底层逻辑的读者。Ubuntu 14.04 虽然老,但它的软件源结构和 systemd 之前的 init 体系,反而让 VNC 的配置逻辑更“原始”,搞懂它对理解新版系统也有帮助。
2. 方案选型:为什么是 TightVNC 而不是别的
2.1 VNC 协议本身是怎么回事
VNC 全称 Virtual Network Computing,核心思路特别朴素:服务端把屏幕 framebuffer 的内容做差分编码,通过 RFB 协议发给客户端,客户端把鼠标键盘事件回传。它不传视频流,传的是“画面变化”,所以带宽占用相对可控,局域网里跑起来很流畅。
RFB 协议是跨平台的,服务端和客户端可以不同厂商。这就带来一个好处:你在 Windows 上用 RealVNC Viewer,连 Ubuntu 上的 TightVNC Server,完全没问题。协议层面对得上就行。
但 VNC 有个绕不开的点:它默认不加密。RFB 协议早期版本传输是明文的,密码认证用的也是一套固定的挑战应答机制,安全性一般。所以生产环境里,VNC 通常不直接暴露在公网,要么走 SSH 隧道,要么在内网里用。这一点后面会细说。
2.2 几个常见 VNC 服务端的对比
Ubuntu 14.04 的软件源里能直接装到的 VNC 服务端有好几个,我列个表对比一下:
| 服务端 | 安装包名 | 特点 | 适合场景 |
|---|---|---|---|
| TightVNC | tightvncserver | 轻量、稳定、配置简单、老系统兼容好 | 老系统、低配机器、快速部署 |
| TigerVNC | tigervncserver | 性能好、支持现代特性 | 新系统、对画质有要求 |
| x11vnc | x11vnc | 共享现有物理桌面,不是新建虚拟桌面 | 需要看到真实显示器画面 |
| vino | vino | GNOME 自带,图形化配置 | 桌面版系统、临时用 |
TightVNC 在 14.04 上是最省心的选择。原因有几个:它的依赖少,装完就能用;配置文件结构清晰,~/.vnc/xstartup这个脚本控制桌面启动,改起来直观;而且它对老版本 Xorg 的兼容性经过大量验证,不容易出现花屏、黑屏这类玄学问题。
TigerVNC 性能确实更好,但在 14.04 上装它有时候要处理额外的依赖,而且它的配置方式和 TightVNC 有差异,网上资料相对少。x11vnc 是另一个思路——它不创建新桌面,而是把当前物理显示器上的画面共享出去。如果你需要看到机器真实屏幕上显示的内容(比如某些工控软件必须接显示器才能启动),那 x11vnc 才是对的。但大多数场景下,我们要的是一个独立的虚拟桌面,TightVNC 更合适。
提示:如果你的机器是纯命令行环境,没有装桌面环境,TightVNC 也能跑,但你需要自己指定一个轻量桌面,否则连上去就是灰屏加一个 X 光标。后面会讲怎么配。
2.3 桌面环境的选择逻辑
VNC server 本身只负责“传画面”,它不提供桌面。桌面环境是另外一层东西。Ubuntu 14.04 默认是 Unity,但 Unity 对 VNC 不太友好——它依赖 3D 加速,在虚拟 X server 里经常起不来,连上去就是黑屏或者报错。
所以实际部署时,通常会给 VNC 配一个轻量桌面。常见选择:
- XFCE:轻量、稳定、兼容性好,是我最推荐的
- LXDE:更轻,但界面简陋一些
- GNOME Flashback:介于两者之间,如果机器上已经装了 GNOME 相关包,可以用这个
XFCE 在 14.04 上的包很全,sudo apt-get install xfce4就能装好,而且它对 X 的要求低,在 VNC 虚拟桌面里跑得很稳。我这些年配下来的经验是:老系统 + VNC + XFCE,这个组合基本不会出幺蛾子。
3. 动手之前:环境检查和依赖准备
3.1 确认系统版本和源状态
第一步永远是确认自己站在什么地基上。SSH 进去之后先跑:
lsb_release -a输出应该能看到Ubuntu 14.04.x LTS。然后检查软件源:
cat /etc/apt/sources.list14.04 已经过了官方支持期,默认源可能已经失效。如果apt-get update报 404,需要把源地址换成旧的归档地址。这一步很关键,源不通后面什么都装不了。
sudo sed -i 's/archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list sudo sed -i 's/security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list sudo apt-get update注意:改源之前先备份
sources.list,养成习惯。cp /etc/apt/sources.list /etc/apt/sources.list.bak,出问题能回滚。
3.2 安装 TightVNC 和 XFCE
源通了之后,两条命令搞定核心依赖:
sudo apt-get install tightvncserver sudo apt-get install xfce4 xfce4-goodiesxfce4-goodies里包含一些常用插件,比如终端、文件管理器,不装的话桌面会比较光秃。安装过程中如果问你要不要选默认显示管理器,选lightdm就行,别选gdm,gdm 在 VNC 场景下容易抢 X 的控制权。
装完之后验证一下:
which vncserver which vncpasswd两个路径都能找到,说明 TightVNC 装好了。
3.3 首次启动和密码设置
TightVNC 第一次启动时会让你设密码:
vncserver它会提示你输入并确认一个密码,这个密码是客户端连接时用的,最多 8 位。设完之后它会自动在:1这个 display 上启动一个会话,并在~/.vnc/下生成配置文件。
这时候其实已经可以连了,但连上去大概率是灰屏,因为默认的xstartup没配桌面。所以下一步就是改这个脚本。
先把这个临时会话杀掉:
vncserver -kill :1然后开始配置。
4. 核心配置:xstartup 脚本和桌面启动
4.1 xstartup 到底在干什么
~/.vnc/xstartup这个文件是 VNC 会话启动时执行的脚本。你可以把它理解成“这个虚拟桌面启动时要跑哪些东西”。VNC server 启动一个 X server,然后执行这个脚本,脚本里负责把窗口管理器、桌面面板、背景这些东西拉起来。
默认的xstartup内容很简单,通常只起了一个xterm或者什么都不起,所以连上去要么是灰屏,要么只有一个终端窗口。我们要把它改成启动 XFCE。
先备份默认的:
cp ~/.vnc/xstartup ~/.vnc/xstartup.bak然后编辑:
nano ~/.vnc/xstartup内容改成这样:
#!/bin/sh unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS exec startxfce4逐行解释一下:
unset SESSION_MANAGER:清掉可能存在的会话管理变量,避免和 VNC 的会话冲突unset DBUS_SESSION_BUS_ADDRESS:DBus 地址如果指向了物理桌面的会话,VNC 里会出各种奇怪问题,清掉让它自己重建exec startxfce4:启动 XFCE 桌面,exec是让这个进程替换当前 shell,这样 VNC 能正确跟踪桌面进程的生命周期
改完给执行权限:
chmod +x ~/.vnc/xstartup提示:这个脚本里不要写
&放到后台,也不要在exec后面再加别的命令。exec之后当前脚本就被替换了,后面的命令不会执行。这是很多人配完发现桌面起不来的原因之一。
4.2 启动参数和分辨率设置
重新启动 VNC server 时,可以指定分辨率和色深:
vncserver :1 -geometry 1440x900 -depth 24参数说明:
:1:display 编号,对应端口 5901。:2对应 5902,以此类推-geometry 1440x900:桌面分辨率。建议不要超过你本地显示器的分辨率,否则要滚动-depth 24:色深,24 位真彩色。老机器如果带宽紧张可以降到 16,画质会差一些但传输量小
分辨率的选择有个经验:如果你本地是 1920x1080,VNC 桌面设成 1600x900 或 1440x900 比较舒服,留点边距,操作起来不憋屈。设成和本地一样大也行,但有些客户端全屏后会有一点缩放模糊。
4.3 验证连接
在本地用 VNC Viewer 连机器IP:5901,输入之前设的密码,应该就能看到 XFCE 桌面了。
如果连上后是黑屏,先别急,检查两件事:
~/.vnc/xstartup是否有执行权限~/.vnc/*.log里有没有报错
日志文件在~/.vnc/目录下,名字类似机器名:1.log。里面会记录 X server 启动和 xstartup 执行的过程,报错信息通常很直接,比如“command not found”或者“cannot open display”。
5. 让 VNC 开机自启:两种靠谱做法
5.1 为什么不能直接往 rc.local 里塞
很多人第一反应是把vncserver命令写进/etc/rc.local。这个做法在 14.04 上能跑,但有个问题:rc.local执行时,网络和用户环境可能还没完全就绪,VNC 启动时如果依赖某些环境变量,会失败。而且它以 root 身份跑,生成的~/.vnc文件属主会变成 root,后面用普通用户操作就乱了。
更稳的做法是用 init 脚本或者用户级自启。14.04 用的是 Upstart,还没到 systemd,所以我们要用 Upstart 的 job 配置。
5.2 用 Upstart 配置开机自启
在/etc/init/下建一个文件:
sudo nano /etc/init/vncserver.conf内容:
description "Start VNC Server" author "admin" start on runlevel [2345] stop on runlevel [!2345] respawn respawn limit 3 30 setuid yourusername setgid yourusername exec /usr/bin/vncserver :1 -geometry 1440x900 -depth 24把yourusername换成实际用户名。几个关键点:
start on runlevel [2345]:在多用户模式下启动respawn:进程挂了自动重启,这个很实用,VNC 偶尔会因为客户端异常断开而崩,respawn 能救回来setuid/setgid:指定以哪个用户身份跑,这样~/.vnc的属主是对的
存盘后启动:
sudo start vncserver检查状态:
sudo status vncserver5.3 用户级自启的替代方案
如果你没有 root 权限,或者不想动系统级配置,可以在用户的 crontab 里加:
crontab -e加一行:
@reboot /usr/bin/vncserver :1 -geometry 1440x900 -depth 24@reboot是 cron 的特殊时间字段,表示开机时执行一次。这个方式简单,但缺点是 cron 环境比较干净,某些依赖用户登录环境的东西可能起不来。XFCE 一般没问题,但如果你的桌面需要读取.profile里的变量,就要注意了。
两种方式我都用过,Upstart 更正规,crontab 更省事。看你的权限和偏好选。
6. 安全加固:别让 VNC 裸奔
6.1 VNC 密码的局限
TightVNC 的密码认证有个硬伤:密码最多 8 位,而且早期版本的密码文件加密强度不高。8 位密码在今天的算力面前,暴力破解不是难事。所以光靠 VNC 自己的密码,安全性是不够的。
另外,RFB 协议传输本身不加密,画面和键盘输入在网络上是明文的。内网里问题不大,但如果你的网络环境不完全可信,就需要额外加一层保护。
6.2 SSH 隧道方案
最通用的做法是走 SSH 隧道。本地执行:
ssh -L 5901:localhost:5901 user@remote-host这条命令的意思是:把本地的 5901 端口转发到远端主机的 5901 端口,通过 SSH 加密通道。然后 VNC Viewer 连localhost:5901,流量就走 SSH 了。
这个方案的好处是:
- 不需要在防火墙上开 5901 端口
- 传输全程加密
- 认证走 SSH 的密钥体系,比 VNC 密码强得多
缺点是每次连之前要先建 SSH 隧道,多一步操作。可以写个脚本封装一下:
#!/bin/bash ssh -L 5901:localhost:5901 -N user@remote-host & sleep 2 vncviewer localhost:59016.3 限制监听地址
如果确实需要直接连 VNC 端口,至少限制它只监听内网地址。TightVNC 默认监听所有接口,可以通过-localhost参数让它只监听 127.0.0.1:
vncserver :1 -localhost -geometry 1440x900 -depth 24这样只有本机能连,外部必须通过 SSH 隧道进来。配合前面的隧道方案,安全性就到位了。
注意:加了
-localhost之后,直接连机器IP:5901会连不上,这是正常的。必须走隧道。
7. 常见问题排查速查
7.1 连上去灰屏或黑屏
这是最高频的问题。排查顺序:
- 检查
~/.vnc/xstartup是否有执行权限 - 检查脚本里
exec startxfce4这一行是否正确,startxfce4命令是否存在(which startxfce4) - 看
~/.vnc/*.log日志,找具体报错 - 确认 XFCE 装全了,
dpkg -l | grep xfce4看看包在不在
有个隐蔽的坑:如果之前用 root 跑过vncserver,~/.vnc目录下某些文件的属主会变成 root,普通用户读写不了,导致 xstartup 不执行。解决方法是把整个目录的属主改回来:
sudo chown -R yourusername:yourusername ~/.vnc7.2 桌面能起来但没面板没菜单
这种情况通常是 XFCE 的会话配置没加载。XFCE 第一次启动时会问你要不要用默认配置,如果 VNC 里没弹出来,可能是配置目录权限问题。检查~/.config/xfce4/的属主,必要时删掉让它重建:
mv ~/.config/xfce4 ~/.config/xfce4.bak然后重启 VNC,XFCE 会重新生成默认配置。
7.3 连接被拒绝
分几种情况:
Connection refused:VNC server 没在跑,或者端口不对。ps aux | grep vnc看看进程在不在Connection timed out:防火墙挡了。检查iptables规则,或者云主机的安全组- 密码正确但连不上:可能是 display 编号冲突,换个编号试试,比如
:2
7.4 画面卡顿、延迟高
VNC 的性能受几个因素影响:
| 因素 | 影响 | 调整方法 |
|---|---|---|
| 色深 | 24 位比 16 位数据量大 | 降到-depth 16 |
| 分辨率 | 越大传输量越大 | 降低-geometry |
| 桌面特效 | 动画、透明消耗带宽 | XFCE 里关掉合成器 |
| 网络质量 | 延迟和丢包直接影响体验 | 走有线、避开高峰 |
XFCE 关合成器:设置 → 窗口管理器微调 → 合成器 → 取消“启用显示合成”。
7.5 重启后 VNC 没起来
如果用 Upstart 配置了自启但没生效,检查:
sudo status vncserver看状态是stop/waiting还是start/running。如果是 stop,看/var/log/upstart/vncserver.log里的报错。常见原因是setuid指定的用户不存在,或者vncserver路径不对(Upstart 的 PATH 和登录 shell 不一样,最好写绝对路径/usr/bin/vncserver)。
8. 一些实操心得和收尾建议
配 VNC 这件事,说起来步骤不多,但细节坑不少。我这些年配下来,有几个习惯帮我省了很多时间。
第一,每次改配置之前先备份。xstartup、sources.list、Upstart 的 conf 文件,改之前都cp一份。出问题的时候,回滚比排查快得多。
第二,日志永远是最好的朋友。~/.vnc/*.log和/var/log/upstart/这两个地方,遇到问题先看日志,比在网上搜半天强。日志里的报错信息通常直接指向根因。
第三,display 编号要管理好。一台机器上跑多个 VNC 会话时,:1、:2、:3分别对应 5901、5902、5903。杀掉会话用vncserver -kill :N,别直接kill进程号,那样可能留下锁文件,下次启动会报“A VNC server is already running”。
第四,老系统的源问题要提前解决。14.04 的官方源已经归档,不换成old-releases地址,apt-get什么都装不了。这一步卡住的话,后面全白搭。
最后说一个实际场景里的取舍:如果你的机器只是偶尔需要图形界面,其实可以考虑不装完整桌面,只装一个轻量窗口管理器加几个必要应用,比如openbox加xterm。这样 VNC 会话启动更快,资源占用更小。但如果你需要给不熟悉命令行的同事用,那还是 XFCE 这种完整桌面更友好,有菜单、有文件管理器、有终端,上手成本低。
VNC 这东西不新,但在老系统维护这个场景里,它依然是最直接、最可控的远程图形方案。把上面这套流程走一遍,基本能覆盖 90% 的需求。剩下的 10%,多半是网络环境和权限的边角问题,对着日志慢慢啃就行。