ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Ubuntu 16.04 配置 VNC 远程桌面:TigerVNC + systemd 完整指南

Ubuntu 16.04 配置 VNC 远程桌面:TigerVNC + systemd 完整指南 搞运维的人大多都碰过这种场景机房或内网里摆着一台 Ubuntu 16.04 的机器没有接显示器但业务方或者研发临时要看个图形界面、跑个 GUI 工具这时候远程桌面就成了刚需。Ubuntu 16.04 虽然已经退出常规维护期但企业内部存量服务器和工作站还大量跑着它VNC 仍然是这类环境里最常见也最直接的远程桌面方案。这篇文章不吹不黑只讲我在 16.04 上反复配置 VNC 的完整流程从服务端选型、安装、配置、systemd 托管到客户端连接、安全加固和问题排查都过一遍。重点不是“能连上就行”而是让你知道每一步为什么要这么干、踩了坑怎么定位。1. 设计思路拆解这个项目到底要解决什么问题1.1 为什么需要 VNCUbuntu 16.04 上远程桌面不是有现成的吗很多人会问Ubuntu 桌面版不是自带“桌面共享”功能吗为什么还要单独装 VNCUbuntu 16.04 默认桌面环境是 Unity系统里确实带了一个叫 vino 的 VNC 服务端也就是“桌面共享”的后台实现。但 vino 干的事情和运维场景里需要的 VNC 完全是两码事它是把当前已经在物理显示器上登录的桌面画面共享出去换句话说必须有人先在机器本地登录了图形会话远程才能连上。服务器放在机房没有接显示器没有人登录vino 就彻底歇菜了。运维场景真正需要的是“无头远程桌面”——机器不接屏幕、没有人登录我通过网络连上去之后系统自动帮我拉起一个全新的图形会话。这个会话和物理显示器没关系它跑在虚拟的显示设备上我用客户端看到的是一套独立桌面。实现这个逻辑就需要一个真正的 VNC Server比如 TigerVNC、x11vnc、x0vncserver 这类工具。另一个关键点是版本差异。Ubuntu 18.04、20.04 上配置 VNC 的很多教程用的是 GNOME 的 Wayland 会话和 16.04 的 Xorg Unity 配置路径完全不同网上刷到的教程经常直接照搬过来就翻车。所以我写这篇的时候默认系统是Ubuntu 16.04 Unity 桌面这也是存量机器里最主流的组合。1.2 主流 VNC 服务端怎么选TigerVNC 还是 x11vnc选型是整个配置过程中第一个坑选错了后面全白搭。我先把我实际用过的几个方案摆出来对比下服务端核心逻辑适合场景我在 16.04 上的评价vino共享当前已登录桌面临时给本地已登录用户看个屏幕不适合无人值守服务x11vnc复用已有的 X 显示:0需要远程控制物理显示器上的桌面对无头机器没意义它默认也要有个 X 在跑TigerVNC standalone独立启动虚拟 X 桌面多会话隔离无头服务器、多用户远程桌面首选稳定、权限清晰、systemd 好管x0vncserver抓取现有 X 输出做 VNC 转发和 x11vnc 类似不是独立会话不推荐我一般无脑选TigerVNC。原因有几个第一它提供独立的vncserver命令可以创建一个全新的虚拟桌面第二它支持按用户隔离配置每个人有自己的~/.vnc目录和密码权限不会互相打架第三和 systemd 配合很顺能实现开机自启这在机房无人值守场景是硬需求。如果你只是想让运维同事能看到物理屏幕上正在跑的东西那 x11vnc 也可以但那种场景一般发生在“机器就在旁边只是懒得走过去”的情况和本文讲的无头服务不是一个路子。2. 环境准备与基础安装2.1 先确认系统状态别在没桌面的系统上白忙活我得先泼一盆冷水VNC 服务端再厉害它也只是把图形会话转发给你看它自己不会生成桌面。如果你的 Ubuntu 16.04 是最小化安装压根没装桌面环境那即使 VNC 连上了看到的也只是一片灰屏或者一个只剩下鼠标指针的空壳。所以在安装 VNC 之前先跑这几个命令确认环境# 查看系统版本确认是 16.04 lsb_release -a # 查看当前是否有图形会话 echo $XDG_CURRENT_DESKTOP # 查看已安装的桌面环境相关包 dpkg -l | grep -E ubuntu-desktop|unity|xfce4|gnome如果$XDG_CURRENT_DESKTOP是空的dpkg也查不到ubuntu-desktop或类似的桌面包说明这就是个纯命令行系统。这种情况下你有两个选择安装完整的 Ubuntu 桌面sudo apt install ubuntu-desktop包很大几百 MB 到 1GB装完还要重启但最省心。装轻量级桌面 XFCEsudo apt install xfce4 xfce4-goodies体积小在远程桌面上跑起来也比 Unity 流畅不少。从运维角度我强烈建议对 16.04 这种老系统做远程桌面时用 XFCE。原因后面配置部分会细说这里先记住一个结论Unity 在虚拟 VNC 屏幕上渲染效率不高远程操作用起来有明显的卡顿感XFCE 会顺畅很多。2.2 安装 TigerVNC Server一条命令的事确认系统版本、桌面环境都就绪后安装 TigerVNC 非常简单# 先更新软件源索引 sudo apt update # 安装 TigerVNC 服务端和相关工具 sudo apt install tigervnc-standalone-server tigervnc-common这里多说一句Ubuntu 16.04 官方源里的 TigerVNC 版本比较老大概是 1.7 左右。对绝大多数场景完全够用不需要折腾第三方 PPA。如果你非要最新版可以加 PPA 编译安装但生产环境我一般遵循“能不动源就不动源”的原则老版本反而经过了更多环境验证。安装完成后可以用vncserver --version确认一下是否装好vncserver --version能弹出版本信息就算安装成功。这时候先别急着启动离真正能连上还差几个配置文件。3. 核心配置详解密码和 xstartup 是重中之重3.1 设置 VNC 访问密码vncpasswd 的隐藏坑VNC 密码和系统登录密码是两套体系必须单独设置。首次启动服务前先执行vncpasswd这个命令会要你输入两次密码密码会保存在~/.vnc/passwd文件里。操作本身很简单但有几个细节很容易坑到人第一传统 VNC 协议对密码长度有上限TigerVNC 在 16.04 上实际只取前 8 位。也就是说你设置了一个 16 位复杂密码后面 8 位会被静默丢弃客户端连的时候也只能用前 8 位验证。这个限制在 TigerVNC 1.8 之后才逐步放宽16.04 源里的老版本是实打实的 8 位限制。第二vncpasswd默认生成的文件权限是 600这个不要手贱去改。如果变成 644VNC Server 会因为“密码文件权限过于宽松”而拒绝启动这是安全机制。第三每个 Linux 用户有自己独立的 VNC 密码。比如你用root跑vncpasswd那密码就存在/root/.vnc/普通用户登录不了你的 VNC 会话。多用户服务器上要给每个人单独设密码互不干扰。3.2 编辑 xstartup决定你连接后看到什么xstartup 是 VNC 会话启动时自动执行的脚本位置在~/.vnc/xstartup。它干的事情简单说就是“VNC 服务拉起一个虚拟 X 窗口后在这个窗口里启动什么桌面”。第一次启动 VNC 之前这个文件还不存在vncserver 首次运行会生成一个默认的模板。默认模板通常指向系统默认桌面但 16.04 上经常失灵因为 Unity 桌面启动依赖很多环境变量默认模板里没带。所以我们要自己写一个。这是我用在 Ubuntu 16.04 上的标准写法#!/bin/sh # 清除会话管理器和 DBus 环境变量避免冲突 unset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS # 启动 XFCE 桌面 startxfce4 # 如果系统是 Unity 桌面则用下面这行替代上面那行 # gnome-session --sessionubuntu-2d # 避免会话窗口被锁屏卡住 xsetroot -solid grey写完记得给执行权限chmod 755 ~/.vnc/xstartup这里有几个点需要展开讲为什么unset SESSION_MANAGER和unset DBUS_SESSION_BUS_ADDRESS因为 VNC 启动的是全新会话如果系统里还残留着物理桌面或者之前会话留下的环境变量会导致新会话启动到一半就崩表现出来就是连接后灰屏或者桌面起不来。清理环境变量是一个保险动作成本低收益高。为什么推荐用 XFCE 而不是 Unity在虚拟屏幕上跑 Unity光是启动就要好几十秒而且打开菜单、拖动窗口都会明显卡顿。XFCE 轻量启动快远程操作体验好得多。如果公司内部合规要求必须用 Unity 桌面那就用注释里那行gnome-session --sessionubuntu-2d。还要注意16.04 的 Unity 是 2D 渲染模式配置远程桌面时务必要加--sessionubuntu-2d而不是直接写unity或者gnome-session。这个参数在新版本系统上已经不存在了很多从 18.04 教程抄过来的写法在 16.04 上根本起不来。3.3 首次启动会生成配置文件先手动跑一次写完 xstartup 后先手动启动一次 VNC Server把配置文件和日志生成出来# 第一个显示编号 :1端口对应 5901 vncserver :1如果一切正常会看到类似New Xtigervnc server ... is :1的输出。这时候在本地测试一下端口监听ss -tlnp | grep 5901能看到0.0.0.0:5901或127.0.0.1:5901的监听记录说明服务已经起来了。手动启动还有一个作用测试你的 xstartup 脚本能不能正常拉起桌面。如果启动后过两秒连接进去是灰屏多半是脚本写得有问题这时候去看日志cat ~/.vnc/*.logTigerVNC 会把启动过程中的报错写进~/.vnc/主机名:1.log排错就靠它了。4. 用 systemd 托管 VNC 服务实现开机自启4.1 手动启动的问题在哪手动跑vncserver :1能用但不够“运维”。问题很明显机器重启后 VNC 服务不会自动拉起如果人不在现场就彻底断了进程如果意外退出也没有守护机制帮你拉回来。正确做法是写一个 systemd service 文件把 VNC Server 托管起来。这也是 16.04 相比老教程最大的进步点早期的 Ubuntu 用的是init.d脚本维护起来很痛苦。我习惯把配置文件放在/etc/systemd/system/vncserver.service用模板方式支持多用户多会话。一个典型的配置模板[Unit] DescriptionVNC Server for %i Aftersyslog.target network.target [Service] Typeforking Userubuntu Groupubuntu WorkingDirectory/home/ubuntu PIDFile/home/ubuntu/.vnc/%H:%i.pid ExecStart/usr/bin/vncserver :%i -geometry 1280x800 -depth 24 -localhost ExecStop/usr/bin/vncserver -kill :%i [Install] WantedBymulti-user.target这里有几个地方要解释清楚%i是模板实例当你执行systemctl start vncserver1时%i就是 1对应的 VNC display 是:1端口是 5901。这样一套模板可以管理多个会话比如2对应 5902。User和Group决定了 VNC 进程以哪个身份运行必须和创建~/.vnc目录、跑vncpasswd的那个用户一致否则会读不到密码文件。ExecStart里的-geometry参数控制虚拟屏幕分辨率这个看业务需求一般 1280x800 是最稳妥的。-depth 24是颜色深度如果网络环境差可以降到 16但颜色会偏色我一般保持 24。-localhost参数表示 VNC 只监听本机回环地址这个不是必选项但如果你准备走 SSH 隧道访问 VNC强烈建议加上能挡掉一大批端口扫描攻击。这个策略我在下一节还会细讲。4.2 启动、开机自启与服务状态检查配置文件写好后依次执行# 重新加载 systemd 配置 sudo systemctl daemon-reload # 启动 :1 会话对应的 VNC 服务 sudo systemctl start vncserver1 # 设置开机自启 sudo systemctl enable vncserver1 # 查看服务状态 sudo systemctl status vncserver1如果状态显示active (running)说明托管成功。这时候再用ss -tlnp看端口监听情况会比手动启动时更规范因为 systemd 会统一管理进程生命周期而不只是后台挂一个进程。有一个注意点如果之前手动启动过vncserver :1再执行 systemd start 可能会报端口被占用。先跑vncserver -kill :1或者pkill -f Xtigervnc清掉旧进程再启动 systemd 服务否则会有个“地址已在使用”的经典报错。另外如果你改了任意配置文件包括 xstartup、systemd 模板记得重启对应的服务实例sudo systemctl restart vncserver1很多人改了 xstartup 后发现桌面没变化就是因为没有重启 VNC 进程。5. 防火墙和安全加固别把 VNC 裸奔到公网5.1 放行 VNC 端口前先搞清楚规则Ubuntu 16.04 默认可能没开防火墙如果你装完系统后手动启用了 UFW需要放行 VNC 端口。VNC 的端口规则很简单display:1对应 5901:2对应 5902依次类推。# 查看 UFW 状态 sudo ufw status # 放行 5901 端口按你的实际 display 号调整 sudo ufw allow 5901/tcp如果你用了-localhost参数VNC 只监听 127.0.0.1这时候 UFW 放不放行 5901 其实都不影响因为外部流量根本到不了这个端口。这点要提前想清楚别配置文件里写了-localhost又开着防火墙放行端口等于白折腾一遍。5.2 从安全角度考虑VNC 不适合裸奔公网说到底VNC 协议本身的设计侧重点是“远程显示”不是“加密传输”。虽然 TigerVNC 近几个版本在认证环节有改进但 16.04 源里的老版本整体安全强度有限密码也只有 8 位爆破成本极低。机房环境里有内网隔离还好一旦暴露到公网基本等于给扫描器送人头。我在实际项目里的推荐做法是第一VNC 只监听本机强制走 SSH 隧道访问。客户端机器上执行ssh -L 5901:localhost:5901 ubuntu服务器IP这个命令的意思是把本机的 5901 端口流量通过 SSH 加密通道转发到服务器的 5901 端口然后 VNC 客户端连接localhost:5901即可。这样数据在传输过程中是加密的VNC 也不直接暴露在网络上。第二如果团队里有人确实需要非加密直连那就把防火墙限制到固定的内网 IP 段不要懒省事直接ufw allow 5901/tcp。运维工作里安全策略不是成本是刚需。第三不要把 VNC 的 8 位密码设置成和系统密码一样VNC 密码泄露的风险和系统密码泄露的风险要隔离开这个习惯能救你一次。6. 客户端连接与环境验证6.1 Windows / Linux / macOS 客户端连接方式服务端配好剩下就是客户端连接。我自己最常用的组合是 Windows 下的 VNC Viewer。打开 VNC Viewer在地址栏输入服务器IP:5901如果是走 SSH 隧道地址就写localhost:5901回车后客户端会提示未加密连接的风险确认后输入 VNC 密码。这里有个体验细节VNC Viewer 会缓存访问过的服务器列表和密码公用的 Windows 机器上记得点掉“记住密码”选项防止密码泄露。Linux 桌面客户端一般直接装tigervnc-viewersudo apt install tigervnc-viewer vncviewer 192.168.1.100:5901macOS 用户更简单自带“屏幕共享”功能在 Finder 里按Cmd K输入vnc://192.168.1.100:5901macOS 的 VNC 客户端兼容性不错但连接非 Retina 分辨率的老 VNC Server 时画质会有点发虚不影响操作。6.2 连接后怎么确认环境真的可用很多场景下连上 VNC 不算完你得确认这个远程桌面“真的能干正事”。比如研发说要用 VNC 远程跑一下 RVIZ 或者其他 GUI 工具那就必须验证两件事桌面环境是否完整、OpenGL 渲染是否可用。在 VNC 会话里打开终端跑这两个命令# 确认当前显示环境变量 echo $DISPLAY # 检查图形渲染信息 glxinfo | grep OpenGL rendererecho $DISPLAY应该输出:1或localhost:10.0之类的内容这是 X11 应用定位显示位置的关键参数。如果应用启动时报“cannot open display”基本都是这个环境变量没传对。glxinfo需要额外安装mesa-utilssudo apt install mesa-utils如果能看到软件渲染器比如 llvmpipe说明 OpenGL 是通的大多数 GUI 程序都能跑。如果 VNC 会话里跑 RVIZ 这类重型三维可视化工具出现画面撕裂、无法显示模型通常不是 VNC 的问题而是这台机器没有 GPU 或者 GPU 驱动没装远程桌面只能走软件渲染性能上不去。这属于硬件层限制再调 VNC 参数也解决不了只能换机器或者接受降级体验。6.3 调整分辨率和画质的小技巧连上 VNC 后如果觉得画面卡顿、文字模糊有几个调优手段我不止一次用过实测有效把 VNC View 的“Picture Quality”从“自动”改成“高画质”或“中画质”不要开“最优先流畅度”否则文字会糊成一团。服务端分辨率不要盲目调大1280x800 是性能和显示面积的平衡点非要 1920x1080 也可以但网络环境一般的话体验会明显变肉。如果网络延迟很高可以在 VNC Viewer 的编码设置里选择压缩率更高的编码方式TigerVNC 默认的编码策略在局域网内表现不错跨公网时就得手动调。7. 常见问题排查速查一看就能定位问题7.1 连接被拒绝Connection refused / 10061这是 VNC 排错里遇到最多的错误Windows 下的 VNC Viewer 会直接弹 “Connection refused (10061)”Linux 下则提示 “Unable connect to socket: Connection refused (10061)”。这个报错的直接原因是“目标端口上没有服务在监听”。按这个思路自上而下排查排查点命令/方法解决思路服务是否运行systemctl status vncserver1或ps aux | grep Xtigervnc服务没起来就先启动并看日志端口是否监听ss -tlnp | grep 5901如果只看到 127.0.0.1:5901说明只能本机访问防火墙是否拦截sudo ufw status检查 5901 是否放行放行端口或调整监听地址策略客户端地址是否写对确认是IP:5901不是裸 IPdisplay :1 就是 5901:2 就是 5902监听地址限制看 vncserver 启动命令是否带-localhost如果带了这个参数但不走 SSH 隧道外部永远连不上最后一条是我自己踩过的深坑在 systemd 配置里加了-localhost第二天客户直接说“VNC 连不上了”实际上服务跑得好好的纯粹是策略冲突要么让客户走 SSH 隧道要么把-localhost去掉并靠防火墙保护。最怕的就是两个策略混在一起定位起来要绕半天。7.2 连接后灰屏或者只看到桌面壁纸连接成功但桌面起不来是 VNC 配置里第二大高频问题。灰屏的第一嫌疑是 xstartup 脚本问题。先确认你能看到的是完全灰色还是有一个空桌面。如果完全是灰色说明 X 服务起来了但桌面会话没有启动成功直接看~/.vnc/*.log里的报错。最常见的是 xstartup 里写的命令不存在或需要指定绝对路径比如startxfce4找不到时得改成/usr/bin/startxfce4。第二个常见原因是 xstartup 文件没有执行权限。很多人创建完文件忘了chmod 755VNC 启动时会认为脚本不可执行直接跳过桌面拉起流程。这个坑好排查也很好避免写完顺手敲一下 chmod 就行。第三个原因和环境变量冲突有关就是前面提到的SESSION_MANAGER和DBUS_SESSION_BUS_ADDRESS。如果本机上已经跑了一个图形会话某些环境变量会被继承到 VNC 会话里导致新会话起不来。xstartup 开头那两行unset干的就是这事儿。如果连上后能看到桌面壁纸但 Dock 栏、任务栏、启动器都没起来那说明桌面框架启动了一半就崩了。这种情况去日志里找段错误或者 D-Bus 相关错误十有八九是 Unity 会话的问题换 XFCE 能绕开一大批坑。7.3 密码认证失败的隐藏原因VNC 密码提示 incorrect 一般分三种情况输错密码这个没办法只能重试。密码文件权限不对确认一下ls -l ~/.vnc/passwd权限必须是-rw-------600。密码超过 8 位被截断。16.04 上 TigerVNC 的老版本只认前 8 位你客户端输入完整密码反而验证不过。这种情况只能vncpasswd重新设置把密码控制在 8 位以内或者升到新版本 TigerVNC。还有一种非常隐蔽的问题多用户服务器上 A 用户的 VNC 密码设置好了B 用户启动的 VNC 服务却读不到因为进程的运行用户不对。systemd 配置里User是谁密码就必须是谁的这个对照关系经常被忽略。7.4 VNC 会话里 GUI 程序打不开怎么办内网运维最常见的场景就是“VNC 连上后研发说跑不了 RVIZ 或者某个图形软件”。先别急着怀疑 VNC从三个方向排查第一DISPLAY 环境变量。打开终端跑echo $DISPLAY如果是空的手动指定一下export DISPLAY:1然后在同一个终端里再启动你的 GUI 程序。有些应用需要把 DISPLAY 环境变量带进 systemd 服务或者 crontab 任务这类情况要单独处理。第二权限问题。X11 的访问控制有时候会拒绝特定用户连接显示服务报xauth或者 “No protocol specified” 的错。遇到这种就检查~/.Xauthority是否存在且可读要么把当前用户加入 VNC 会话的 Xauthority 列表要么干脆临时关掉访问控制不建议长期开。第三OpenGL/GPU 渲染。Xorg 和 VNC 组合下很多应用默认启用硬件加速但无头服务器上根本没有 GPU或者 GPU 驱动没配好应用就会崩溃或黑屏。尝试给应用强制软件渲染常见做法是设置环境变量LIBGL_ALWAYS_SOFTWARE1再启动程序很多时候能解决问题。8. 我在实际运维中的几个小心得技术流程讲完最后分享几个不能量化的经验。第一Ubuntu 16.04 上配 VNC最好一次到位选 TigerVNC XFCE。我知道很多人纠结“系统自带的是 Unity硬要装个 XFCE 是不是多此一举”但 VNC 远程场景下 Unity 的体验确实一言难尽启动慢、特效卡、依赖重。XFCE 装完也就一两百 MB 的额外占用换来的是流畅得多的远程操作体验。为这个选择翻过车的不止我一个人你可以先试试完大概率回来换 XFCE。第二配置 VNC 之前先确认这几样东西系统装了桌面、密码文件权限是 600、xstartup 有执行权限、systemd 配置里 User 和 VNC 密码属主一致。这四项检查做完90% 的基础坑都避开了。别一上来就改配置基础没夯实越调越乱。第三旧系统的运维节奏是“能不动就不动”。16.04 源里的 TigerVNC 版本虽然是老但它和系统的兼容性已经经过了多年磨炼。不要为了追新版去加乱七八糟的 PPA除非有明确的安全合规要求。老版本 VNC 客户端兼容性更好至少我在 Win/Mac/Linux 各种客户端上都连过没出过协议不兼容的问题。最后再提一句如果你接手的环境后续有计划升级到 18.04 或 20.04VNC 配置思路要跟着变特别是桌面会话语法的写法几乎都变了xstartup 脚本不能直接拷贝。但系统底层的服务托管、安全加固、排错思路是一脉相承的这篇文章里的方法论换个版本照样能用。
返回列表