如何在CentOS7上为GNOME桌面安装和配置VNC远程访问
介绍
VNC 或虚拟网络计算是一种独立于平台的协议,它使用户能够连接到远程计算机系统并从图形用户界面 (GUI) 使用其资源。
这就像远程控制应用程序:客户端计算机的击键或鼠标点击通过网络传输到远程计算机。 VNC 还允许在两台计算机之间共享剪贴板。 如果您来自 Microsoft Windows 服务器背景,VNC 很像远程桌面服务,除了它也可用于 OS X、Linux 和其他操作系统。
与网络世界中的所有其他事物一样,VNC 是基于客户端服务器模型的:VNC 服务器运行在远程计算机上——您的 Droplet——它为传入的客户端请求提供服务。
目标
在本教程中,我们将学习如何在 CentOS 7 上安装和配置 VNC 服务器。 我们将安装 TigerVNC 服务器,该服务器可从 TigerVNC GitHub 存储库 免费获得。
为了演示 VNC 的工作原理,我们还将在您的 CentOS 服务器上安装 GNOME 桌面。 我们将创建两个用户帐户并为他们配置 VNC 访问。 然后,我们将测试他们与远程桌面的连接,最后,学习如何通过 SSH 隧道保护远程连接。
先决条件
本教程中显示的命令、软件包和文件在 CentOS 7 的最小安装上进行了测试。 我们会推荐以下内容:
- 发行版:CentOS 7, 64 位
- 资源需求:具有 2 GB RAM 的 Droplet
- 要遵循本教程,您应该使用 sudo 用户。 要了解 sudo 权限是如何工作的,可以参考 这个 DigitalOcean 教程
警告: 您不应在生产 Linux 服务器上运行本教程中的任何命令、查询或配置。 这可能会导致安全问题和停机。
第 1 步 — 创建两个用户帐户
首先,我们将创建两个用户帐户。 这些帐户将从 VNC 客户端远程连接到我们的 CentOS 7 服务器。
- joevnc
- 珍妮弗
运行以下命令为 joevnc 添加用户帐户:
sudo useradd -c "User Joe Configured for VNC Access" joevnc
然后运行 passwd 命令更改 joevnc 的密码:
sudo passwd joevnc
输出将要求我们输入新密码。 提供后,该帐户就可以登录了:
Changing password for user joevnc. New password: Retype new password: passwd: all authentication tokens updated successfully.
接下来,为 janevnc 创建一个帐户:
sudo useradd -c "User Jane Configured for VNC Access" janevnc
设置 janevnc 的密码:
sudo passwd janevnc
第 2 步 — 安装 GNOME 桌面
现在我们将安装 GNOME 桌面。 GNOME 是一种协作努力:它是一个免费和开源软件的集合,构成了一个非常流行的桌面环境。 还有其他桌面环境,如 KDE,但 GNOME 更受欢迎。 我们的 VNC 用户将使用 GNOME 从其桌面与服务器交互:
sudo yum groupinstall -y "GNOME Desktop"
根据您的网络速度,这可能需要几分钟。
安装软件包组后,重新启动服务器:
sudo reboot
故障排除——服务器卡在启动阶段
根据您的服务器的设置方式,当机器启动时,它可能会保持在启动阶段,显示如下消息:
Initial setup of CentOS Linux 7 (core) 1) [!] License information (Licence not accepted) Please make your choice from above ['q' to quit | 'c' to continue | 'r' to refresh]:
要解决这个问题,请按 1(读取许可证),然后按 2(接受许可证),然后按 C(继续)。 您可能必须按 C 两次或更多次。 下图显示了这一点:
如果您没有看到此错误并且启动过程很顺利,那就更好了——您可以继续下一步。
第 3 步 — 安装 TigerVNC 服务器
TigerVNC 是允许我们建立远程桌面连接的软件。
安装 Tiger VNC 服务器:
sudo yum install -y tigervnc-server
这应该显示如下输出:
Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile . . . Running transaction Installing : tigervnc-server-1.2.80-0.30.20130314svn5065.el7.x86_64 1/1 Verifying : tigervnc-server-1.2.80-0.30.20130314svn5065.el7.x86_64 1/1 Installed: tigervnc-server.x86_64 0:1.2.80-0.30.20130314svn5065.el7 Complete!
现在我们已经安装了 VNC 服务器和 GNOME 桌面。 我们还创建了两个用户帐户,用于通过 VNC 进行连接。
第 4 步 — 为两个客户端配置 VNC 服务
VNC 服务器在首次安装时不会自动启动。 要检查这一点,请运行以下命令:
sudo systemctl status vncserver@:.service
输出将是这样的:
vncserver@:.service - Remote desktop service (VNC) Loaded: loaded (/usr/lib/systemd/system/vncserver@.service; disabled) Active: inactive (dead)
您还可以运行以下命令:
sudo systemctl is-enabled vncserver@.service
这应该显示如下输出:
disabled
那么为什么会被禁用呢? 这是因为每个用户都将启动一个单独的 VNC 服务守护程序实例。 换句话说,VNC 不会作为一个单独的进程来服务每个用户请求。 每个通过 VNC 连接的用户都必须启动一个新的守护进程实例(或者系统管理员可以自动执行此操作)。
CentOS 7 使用 systemd 守护进程来启动其他服务。 在 systemd 下本机运行的每个服务都有一个 服务单元文件 ,由 yum 安装程序放置在 /lib/systemd/system
目录下。 在启动时自动启动的进程有一个指向此服务单元文件的链接,该文件位于 /etc/systemd/system/
目录中。
在我们的例子中,在 /lib/systemd/system/
目录中创建了一个通用服务单元文件,但在 /etc/systemd/system/
下没有建立链接。 要对此进行测试,请运行以下命令:
sudo ls -l /lib/systemd/system/vnc*
你应该看到:
-rw-r--r--. 1 root root 1744 Jun 10 16:15 /lib/systemd/system/vncserver@.service
然后在/etc/systemd/system/
下查看:
sudo ls -l /etc/systemd/system/*.wants/vnc*
这个不存在:
ls: cannot access /etc/systemd/system/*.wants/vnc*: No such file or directory
因此,第一步是为我们的两个用户启动两个新的 VNC 服务器实例。 为此,我们需要在 /etc/system/system
下制作两个通用 VNC 服务单元文件的副本。 在下面的代码片段中,您制作了两个具有两个不同名称的副本:
sudo cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:4.service sudo cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:5.service
那么为什么我们要在复制的文件名中添加两个数字(以及冒号)?
这又回到了单个 VNC 服务的概念。 VNC 本身在端口 5900 上运行。 由于每个用户都将运行自己的 VNC 服务器,因此每个用户都必须通过单独的端口进行连接。 在文件名中添加一个数字告诉 VNC 将该服务作为 5900
的 子端口 运行。 所以在我们的例子中,joevnc 的 VNC 服务将在端口 5904 (5900 + 4) 上运行,而 janevnc 的 VNC 服务将在 5905[ 上运行X131X] (5900 + 5)。
接下来为每个客户端编辑服务单元文件。 使用 vi 编辑器打开 /etc/systemd/system/vncserver@:4.service
文件:
sudo vi /etc/systemd/system/vncserver@:4.service
看一下“Quick HowTo”部分就告诉我们我们已经完成了第一步。 现在我们需要完成剩下的步骤。 评论还告诉我们,VNC 是一个不受信任的连接。 我们稍后会谈到这个。
现在,编辑文件的 [Service]
部分,将 <USER>
的实例替换为 joevnc
。 此外,在 ExecStart
参数的末尾添加 -geometry 1280x1024
子句。 这只是告诉 VNC 它应该开始的屏幕大小。 您将总共修改两行。 这是编辑后的文件的样子(请注意,未显示整个文件):
# The vncserver service unit file # # Quick HowTo: # 1. Copy this file to /etc/systemd/system/vncserver@:<display>.service # 2. Edit <USER> and vncserver parameters appropriately # ("runuser -l <USER> -c /usr/bin/vncserver %i -arg1 -arg2") # 3. Run `systemctl daemon-reload` # 4. Run `systemctl enable vncserver@:<display>.service` # . . . [Unit] Description=Remote desktop service (VNC) After=syslog.target network.target [Service] Type=forking # Clean any existing files in /tmp/.X11-unix environment ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' ExecStart=/sbin/runuser -l joevnc -c "/usr/bin/vncserver %i -geometry 1280x1024" PIDFile=/home/joevnc/.vnc/%H%i.pid ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' [Install] WantedBy=multi-user.target
保存文件并退出 vi。
同样,在 vi 中打开 /etc/systemd/system/vncserver@:5.service
文件并为用户 janevnc 进行更改:
sudo vi /etc/systemd/system/vncserver@:5.service
这里只是标记了更改的 [Service]
部分:
[Service] Type=forking # Clean any existing files in /tmp/.X11-unix environment ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' ExecStart=/sbin/runuser -l janevnc -c "/usr/bin/vncserver %i -geometry 1280x1024" PIDFile=/home/janevnc/.vnc/%H%i.pid ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
接下来,运行以下命令以重新加载 systemd 守护程序,并确保 VNC 在引导时为两个用户启动。
sudo systemctl daemon-reload
启用第一个服务器实例:
sudo systemctl enable vncserver@:4.service
输出:
ln -s '/etc/systemd/system/vncserver@:4.service' '/etc/systemd/system/multi-user.target.wants/vncserver@:4.service'
启用第二个服务器实例:
sudo systemctl enable vncserver@:5.service
输出:
ln -s '/etc/systemd/system/vncserver@:5.service' '/etc/systemd/system/multi-user.target.wants/vncserver@:5.service'
现在您已经配置了两个 VNC 服务器实例。
第 5 步 — 配置您的防火墙
接下来,我们需要配置防火墙以允许 VNC 流量仅通过端口 5904 和 5905。 CentOS 7 通过 firewalld 守护进程使用动态防火墙; 该服务不需要重新启动以使更改生效。
firewalld 服务应该在系统启动时自动启动,但最好检查一下:
sudo firewall-cmd --state
这应该显示:
running
如果由于某种原因状态为“未运行”,请执行以下命令以确保其正在运行:
sudo systemctl start firewalld
现在添加端口 5904 和 5905 的规则:
sudo firewall-cmd --permanent --zone=public --add-port=5904-5905/tcp
输出:
success
重新加载防火墙:
sudo firewall-cmd --reload
输出:
success
第 6 步 — 设置 VNC 密码
我们距离看到 VNC 的实际应用仅一步之遥。 在此步骤中,用户需要设置他们的 VNC 密码。 这些是 而不是 用户的 Linux 密码,而是登录 VNC 会话的密码。
打开另一个与 CentOS 7 服务器的终端连接,这次以 joevnc 身份登录。
ssh joevnc@your_server_ip
执行以下命令:
vncserver
如下输出所示,服务器将要求 joevnc 设置 VNC 密码。 输入密码后,程序还会显示在用户主目录中创建的许多文件:
You will require a password to access your desktops. Password: Verify: xauth: file /home/joevnc/.Xauthority does not exist New 'localhost.localdomain:1 (joevnc)' desktop is localhost.localdomain:1 Creating default startup script /home/joevnc/.vnc/xstartup Starting applications specified in /home/joevnc/.vnc/xstartup Log file is /home/joevnc/.vnc/localhost.localdomain:1.log
让我们看一下 New 'localhost.localdomain:1 (joevnc)' desktop is localhost.localdomain:1
行。 localhost.localdomain 是我们示例中的服务器名称; 在你的情况下,它可能会有所不同。 注意服务器名称后面的数字:(1,用冒号分隔)。 这不是 joevnc 的服务单元文件中的编号(即 4)。 那是因为这是 显示编号 joevnc 的会话将在此服务器上运行,而不是服务的端口号 (5904
) 本身。
接下来打开一个新的终端会话并以 janevnc 身份登录。 同样在这里,启动 VNC 服务器并为 janevnc 设置密码:
vncserver
您应该会看到类似的输出,显示 janevnc 的会话将在显示 2 上运行。
最后,从 主终端会话 重新加载服务:
sudo systemctl daemon-reload sudo systemctl restart vncserver@:4.service sudo systemctl restart vncserver@:5.service
第 7 步 — 使用 VNC 客户端连接到远程桌面
在本教程中,我们假设用户 joevnc 和 janevnc 正在尝试从他们的 Windows 计算机连接到 CentOS 7 服务器。
他们每个人都需要一个用于 Windows 的 VNC 客户端来登录远程桌面。 这个客户端就像 PuTTY 之类的终端客户端,只是它显示图形输出。 有各种可用的 VNC 客户端,但我们将使用 RealVNC,在 here 可用。 Mac OS X 的 VNC 查看器可在同一页面上下载,Mac 版本与 Windows 版本非常相似。
当 VNC Viewer 启动时,它会显示如下对话框:
在 VNC Server 字段中,添加 CentOS 7 服务器的 IP 地址。 在服务器 IP 后面指定端口号 5904,用冒号分隔(:)。 我们使用 5904 因为那是 joevnc 的 VNC 服务端口。
我们还决定让 VNC Viewer 选择加密方法。 此选项只会加密通过网络发送的密码。 与服务器的任何后续通信都将不加密。 (我们将在最后一步建立一个安全的 SSH 隧道。)
事实上,一条警告消息表明:
暂时接受警告。 将显示密码提示:
输入您之前设置的 joevnc 的 VNC 密码。
一个新窗口打开,显示我们远程 CentOS 服务器的 GNOME 桌面:
接受默认的欢迎消息。
现在 joevnc 可以启动像 GNOME 计算器这样的图形工具:
您可以保持此桌面连接处于打开状态。
现在 janevnc 也可以与 CentOS 服务器启动另一个 VNC 会话。 IP地址相同,端口为5905:
当 janevnc 通过 VNC 查看器登录时,会显示一个带有欢迎消息的空桌面,就像为 joevnc 显示的一样。 换句话说,两个用户不共享桌面实例。 joevnc 的桌面应该仍然显示计算器。
要关闭远程桌面会话,只需关闭窗口即可。 但是,这不会在服务器的后台停止用户的 VNC 服务。 如果服务没有停止或重新启动并且机器没有重新启动,那么下次登录时将显示相同的桌面会话。
关闭 joevnc 和 janevnc 的 VNC 查看器窗口。 也关闭他们的终端会话。 在主终端窗口中,检查 VNC 服务是否仍在运行:
sudo systemctl status vncserver@:4.service
输出显示远程桌面仍在运行:
vncserver@:4.service - Remote desktop service (VNC) Loaded: loaded (/etc/systemd/system/vncserver@:4.service; enabled) Active: active (running) since Sat 2014-11-01 12:06:49 EST; 58min ago Process: 2014 ExecStart=/sbin/runuser -l joevnc -c /usr/bin/vncserver %i -geometry 1280x1024 (code=exited, status=0/SUCCESS) . . .
检查第二个服务:
sudo systemctl status vncserver@:5.service
这个也在运行:
vncserver@:5.service - Remote desktop service (VNC) Loaded: loaded (/etc/systemd/system/vncserver@:5.service; enabled) Active: active (running) since Sat 2014-11-01 12:42:56 EST; 22min ago Process: 3748 ExecStart=/sbin/runuser -l janevnc -c /usr/bin/vncserver %i -geometry 1280x1024 (code=exited, status=0/SUCCESS) . . .
如果此时您想重新登录 joevnc 的桌面,您会看到相同的计算器应用程序打开。
这给系统管理员带来了一些有趣的挑战。 如果您有许多用户通过 VNC 连接到服务器,您可能需要设计一些方法来在不再需要时停止他们的 VNC 服务。 这可能会节省一些宝贵的系统资源。
故障排除 - VNC 服务崩溃
在您测试和使用 VNC 时,您有时可能会发现服务已崩溃并且无法恢复。 当您尝试检查状态时:
sudo systemctl status vncserver@:4.service
可能会出现此长错误消息:
vncserver@:4.service - Remote desktop service (VNC) Loaded: loaded (/etc/systemd/system/vncserver@:4.service; enabled) Active: failed (Result: exit-code) since Fri 2014-11-07 00:02:38 EST; 2min 20s ago Process: 2221 ExecStart=/sbin/runuser -l joevnc -c /usr/bin/vncserver %i -geometry 1280x1024 (code=exited, status=2) Process: 1257 ExecStartPre=/bin/sh -c /usr/bin/vncserver -kill %i > /dev/null 2>&1 || : (code=exited, status=0/SUCCESS)
尝试启动服务不起作用:
sudo systemctl start vncserver@:4.service
启动失败:
Job for vncserver@:4.service failed. See 'systemctl status vncserver@:4.service' and 'journalctl -xn' for details.
通常原因很简单。 检查/var/log/messages
:
sudo tail /var/log/messages
相关的错误将如下所示:
Nov 7 00:08:36 localhost runuser: Warning: localhost.localdomain:4 is taken because of /tmp/.X11-unix/X4 Nov 7 00:08:36 localhost runuser: Remove this file if there is no X server localhost.localdomain:4 Nov 7 00:08:36 localhost runuser: A VNC server is already running as :4 Nov 7 00:08:36 localhost systemd: vncserver@:4.service: control process exited, code=exited status=2 Nov 7 00:08:36 localhost systemd: Failed to start Remote desktop service (VNC). Nov 7 00:08:36 localhost systemd: Unit vncserver@:4.service entered failed state. Nov 7 00:08:36 localhost systemd: Failed to mark scope session-c3.scope as abandoned : Stale file handle
补救方法是删除/tmp文件夹下的文件:
sudo rm -i /tmp/.X11-unix/X4
输出:
rm: remove socket ‘/tmp/.X11-unix/X4’? y
然后启动VNC服务:
sudo systemctl start vncserver@:4.service
一般故障排除
虽然比较少见,但在使用 VNC 时可能会遇到其他错误。 例如,您的远程桌面屏幕可能会变为空白或挂起,会话可能会因隐秘的错误消息而崩溃,VNC 查看器可能无法正确连接或将命令传输到 GUI 以启动应用程序等。
我们建议检查 /var/log/messages
文件以获得更好的理解。 有时您可能需要重新启动服务器,或者在极端情况下重新创建 VNC 服务。
系统资源也可能是罪魁祸首; 您可能需要为您的 Droplet 等添加额外的 RAM。
第 8 步 — 通过 SSH 隧道保护 VNC 会话
到目前为止,joevnc 和 janevnc 都通过未加密的通道访问他们的远程桌面。 正如我们之前看到的,VNC Viewer 在连接时会警告我们; 只有密码在会话开始时被加密。 任何后续的网络流量和数据传输都是开放的,任何人都可以在中间拦截。
关于 SSH 隧道
这就是 Secure Shell (SSH) 会话可以提供帮助的地方。 使用 SSH,VNC 可以在 SSH 加密会话的上下文中运行。 这被称为 隧道 。 实际上,VNC 流量搭载在 SSH 协议上,导致其与服务器的所有通信都被加密。 之所以称为 tunnelling,是因为 SSH 通过 VNC 提供环绕保护,并且 VNC 就像在 SSH 中的隧道中一样运行。 SSH 隧道也可用于 POP、X 或 IMAP 等其他协议。
SSH 隧道与 端口转发 一起工作,这基本上是将访问从一个特定端口转换到另一台机器上的不同端口的一种方式。 通过端口转发,当客户端应用程序连接到机器 A 上运行的端口 A 时,它会透明地转发到机器 B 上运行的端口 B。 客户端应用程序不知道此转换并认为它正在连接到原始端口。 端口转发是 SSH 协议的特性之一。
有关 SSH 隧道的更多详细信息,请阅读 本教程 。
在本教程中,我们将 VNC 配置为在端口 5904(用于 joevnc)和 5905(用于 janevnc)上运行。
通过端口转发,我们可以将本地 VNC 客户端设置为连接到本地客户端计算机上的端口 5900,这可以映射到远程服务器上的端口 5905。 这是 janevnc 连接的示例,但您可以轻松地对任何其他客户端执行相同的步骤。
当VNC客户端应用启动时,可以指向localhost上的端口5900,我们的端口转发会透明的传送到远程服务器上的端口5905 .
注意: 每次 都必须启动一个 SSH 部分 以确保连接安全。
操作系统
在您的 Mac 上,打开 终端 。
输入以下连接信息,确保将 your_server_ip
替换为远程服务器的 IP 地址:
ssh -L 5900:your_server_ip:5905 janevnc@your_server_ip -N
输入 janevnc 的 UNIX 密码。 连接将出现挂起; 只要您使用远程桌面,您就可以让它一直运行。
现在跳到 VNC 查看器说明。
视窗
为了保护 janevnc 的 VNC 会话,我们假设本地 Windows 计算机安装了 PuTTY。 PuTTY是免费的,可以从这里下载。
如果 janevnc 的 VNC 和终端会话尚未关闭,请立即关闭它们。
启动腻子。 在会话屏幕中,确保您指定服务器 IP 地址并为连接提供描述性名称,然后单击 保存 按钮以保存连接详细信息。 请注意我们是如何在 Hostname 字段中指定 username@your_server_ip
的:
接下来,在左侧导航窗格中展开 SSH 菜单项,并选择 X11 项。 这显示了会话的 X11 转发属性。 确保选中 Enable X11 forwarding 复选框。 这可确保 SSH 加密在服务器和客户端之间流动的 X Windows 流量:
最后,选择 SSH > Tunnels。 在 Source 端口字段中键入 5900
。 在 Destination 字段中,指定服务器的名称或 IP 地址,后跟冒号和目标用户的 VNC 端口号。 在我们的例子中,我们指定了 your_server_ip:5905
。
或者,您可以使用端口 5902。 在这种情况下,2 将是 janevnc 的显示编号(请记住 janevnc 运行 vncserver
命令时显示的消息)。
单击添加按钮,映射将添加到转发端口下。 这是我们为 SSH 会话添加端口转发的地方; 当用户通过端口 5900 连接到 localhost 时,连接将自动通过 SSH 隧道连接到远程服务器的端口 5905。
返回到 Sessions 项并保存 janevnc 的会话。 单击 Open 按钮,将为 janevnc 打开一个新的终端会话。 使用适当的 UNIX 密码以 janevnc 身份登录:
VNC 查看器
接下来再次启动 VNC Viewer。 这一次,在 VNC 服务器地址,输入 <^> 并让 VNC 服务器选择加密方法:
单击 连接 按钮。
您仍然会收到有关未加密会话的警告对话框,但这次您可以放心地忽略它。 VNC 查看器不知道它被转发到的端口(这是在刚刚启动的 SSH 会话中设置的)并假设您正在尝试连接到本地计算机。
接受此警告将显示熟悉的密码提示。 输入janevnc的VNC密码访问远程桌面。
那么你怎么知道会话被加密了呢? 如果您考虑一下,我们已经在 SSH 会话中设置了端口转发。 如果没有建立 SSH 会话,端口转发将无法工作。 事实上,如果您关闭终端窗口并退出 PuTTY 会话,然后尝试单独连接 VNC 查看器,则尝试连接到 localhost:5900
将显示以下错误消息:
因此,如果 localhost:5900
连接有效,您可以确信该连接已加密。
请记住,每次使用 VNC 时,您都需要先建立 SSH 连接,以确保您的连接始终是加密的。
结论
从 GUI 前端访问您的 CentOS Linux 系统可以使系统管理更加简单。 您可以从任何客户端操作系统进行连接,而不必依赖基于 Web 的托管控制面板。 与大多数控制面板相比,VNC 的占用空间要小得多。
虽然我们已经展示了两个普通用户如何与他们的 VNC 客户端连接,但这在严肃的生产环境中几乎不实用。 实际上,用户将有定制的应用程序或浏览器来访问服务器。 为每个用户运行多个 VNC 服务也会对系统资源造成不必要的负担,更不用说与之相关的固有风险。
如果您决定在生产 Linux 服务器上安装和运行 VNC,我们强烈建议您仅将其用于管理目的。