用 VNC 和 SSH 保护对 IBM Cloud 实例的多用户访问

通过配置云实例和客户端实现安全的远程图形化访问

学习如何通过配置服务器和客户端使用 Secure Shell (SSH) 和 Virtual Network Computing (VNC),从而对 IBM Smart Business Development and Test on the IBM Cloud 提供的云实例进行安全的远程图形化访问。

Bill Hudacek, 资深 IT 架构师, IBM

Bill Hudacek 在 UNIX 和 Linux 领域有 20 年工作经验,是一位才能全面的专家。他当前是 IBM Testing Services for the Cloud - performance testing(这是与 IBM Smart Business Development and Test on the IBM Cloud 相关的一项 IBM 服务)的首席架构师。过去,他做过 UNIX/C 系统程序员和应用程序开发人员、UNIX 系统经理以及 J2EE/JavaEE/SOA 架构师和开发人员。除了关注云计算之外,他还对性能和团队生产力很感兴趣。Bill 一直在探索让工作更智能化的方法。



2011 年 7 月 04 日

本文为需要安全地访问 IBM® Smart Business Development and Test on the IBM Cloud(后面简称为 IBM Cloud)上多个虚拟 Linux® 实例的团队提供一个解决方案。通过使用 SSH 和 VNC,可以满足大多数组织的安全需求,同时满足团队成员的需要。学习如何配置云实例和 Windows™ 客户端。

  • 云服务器:
    • 创建本地用户 ID
    • 添加 VNC 服务定义
    • 安装 xinetd VNC 服务定义文件
    • 定制 X11 显示管理程序 ("Greeter")
    • 修改系统的默认运行级别
    • 创建 ssvnc 概要文件(用于分发给团队成员)
    • 把 SSH 秘密密钥转换为 PuTTY 格式(用于分发给团队成员)
  • Windows 客户端:
    • 下载 ssvnc
    • 设置 HOME 环境变量
    • 创建 ssvnc 概要文件目录
    • 创建运行 ssvnc 会话的快捷方式
    • 配置基于 Windows 的 SSH 代理

在开始之前,要注意几点。在本文中,Windows 是指 32 位 Windows XP;对于 64 位 Windows 版本,已经报告了结果有问题。对于运行 Linux 的用户,由于桌面环境提供很强的 SSH 支持,有可能实现更无缝的解决方案。本文不讨论来自 Linux 客户端的访问。最后,使用 SSH 所涉及的低层机制超出了本文的范围。

术语

Virtual Network Computing (VNC) 是一种独立于平台的图形化桌面共享系统,它使用 RFB 协议远程控制另一台计算机。它把客户端计算机上的键盘和鼠标事件传输到运行 ‘服务器’ 的计算机,并通过网络把图形屏幕更新发回客户端。

RFB 协议 ("remote framebuffer") 是一种用于远程访问图形用户界面的简单的协议。因为它在帧缓冲区级上工作,所以适用于所有窗口系统和应用程序。

ssvnc 把加密的安全网络连接与 VNC 集成起来;它为 Windows、MacOSX 和 UNIX 提供 GUI 并创建 SSL 或 SSH 隧道以连接任何远程系统,然后通过隧道自动地运行 VNC(它还支持 VeNCrypt 加密;这给 VNC 增加了 TLS/X.509 加密和身份验证功能)。

Secure Shell 隧道由通过 SSH 协议连接创建的加密的隧道组成。通过建立 SSH 隧道,用户可以经过加密的通道在网络上传输未加密的通信流。SSH 客户端把数据从指定的本地端口传输到远程计算机上的端口;建立隧道之后,用户可以通过连接指定的本地端口访问远程计算机上的网络服务。注意,本地端口的端口号不必与远程端口相同。通常,还把远程服务配置为只监听 'loopback adapter',这样就不可能以不安全的方式访问此服务。

Transport Layer Security (TLS) 是一种密码学协议,为 Internet 通信提供安全性;它在传输层上使用对称密码学技术对网络连接进行加密以保证私密性,使用带密钥的消息身份验证码保证消息的可靠性。SSL 是它的前身。

X.509 是用于单点登录和特权管理基础结构的公共密钥基础结构的 ITU-T 标准;它指定公共密钥证书、证书撤消列表和属性证书的标准格式以及一种认证路径检验算法。

一元身份验证是指一类向计算服务表明自己身份的方法,这类方法要求提供的信息是 “您知道的某种东西”,比如用户 ID 和密码。

二元身份验证是指另一类向计算服务表明自己身份的方法,这类方法要求提供的信息是 “您知道的某种东西” 以及 “您拥有的某种东西”。基于 SSH 密钥的身份验证和基于 SSL 证书的相互身份验证属于这类身份验证方法。

针对云调整后的 VNC

在这个实现中,VNC 的行为要适应云本身灵活且动态的特点。

  • 用户可以选择他们喜欢的显示窗口大小。
  • 任意数量的用户可以同时登录,他们可以使用相同或不同的显示窗口大小。
  • 不共享会话。
  • 当网络连接终止时,用户的会话结束。

经过调整的二元身份验证

如果使用本文描述的解决方案,登录 IBM Cloud 系统的过程需要两个东西:

  • SSH 密钥(它由密码段保护)
  • Linux 用户 ID(有相应的密码)

SSH 密钥实际上由两部分组成:

  • 一部分已经放在云实例上(公共密钥)。
  • 您必须拥有另一部分(秘密密钥)。

对于新的基于 Linux 的云实例,IBM Cloud 会自动地创建用户 idcuser;这个用户 id 使用 SSH 访问每个全新的云实例。尽管本文讨论的是使用您创建的新用户账号进行多用户访问,但是如果只有您一个人使用您的云账号,那么只需使用 idcuser 访问云实例即可,因为 SSH 已经提供了二元身份验证(定义见 边栏)。但是,必须给 idcuser 设置密码(在默认情况下它没有密码)。

团队常常以共享方式使用一组云实例。尽管在某些安全要求高的场景中可能(甚至希望)要求每个成员使用独特的 SSH 密钥访问得到授权的云实例,但是更常见的做法是把相同的 SSH 秘密密钥分发给所有团队成员,本文假设是这种情况。在以这种方式使用时,尽管 SSH 仍然提供二元身份验证,但是 SSH 密钥不足以识别访问云实例的用户的身份。因此,应该在每个云实例上创建用户账号。这些账号还让您能够向团队成员授予对特定实例的访问权(如果需要的话),而不是允许所有团队成员访问所有云实例。

本文提供的解决方案能够满足这样的团队的需求并实现最佳实践。这个解决方案让每个用户使用传统的 X11 Greeter 应用程序登录远程系统,提供 “您知道的某种东西、您拥有的某种东西以及您知道的其他东西”(可以称之为 “二元加一元身份验证”)。


服务器设置

对于云 Linux 管理员,好消息是:在所有正在运行的云实例上,不需要修改防火墙设置,因为所有通信流都通过 SSH 传输,因此使用端口 22 —— 这是在新供应的 Red Hat Enterprise Linux (RHEL) 云实例上打开的惟一 TCP 端口。

创建本地用户 ID

必须在每个云实例上创建用户账号。在新的云实例上,可以从命令行 PuTTY/SSH 会话执行以下 shell 代码,从而创建一个新的用户账号:

# (assume here we already have $userName and 'plaintext' $password...)
# Convert password to already-hashed string we can insert into
# /etc/password; choose your own 'salt' if you like.
etcPassEntry=$(echo "$password" | openssl passwd -stdin -crypt -salt AZ )
sudo /usr/sbin/useradd -c 'auto-generated by script' -m -n -g users  \
  --password "$etcPassEntry" "$userName"

在云实例中添加 VNC 服务定义

在 /etc/services 的底部添加以下代码行:

vnc8x6         5908/tcp
vnc10x7        5910/tcp
vnc11x8        5911/tcp
vnc12x10       5912/tcp
vnc14x10       5914/tcp
vnc16x12       5916/tcp

注意,显示器大小与选择的 VNC 端口紧密相关。

安装 xinetd VNC 服务定义文件

安装 /etc/xinet.d VNC 服务定义文件(对于上面的每个服务,应该各有一个文件)。下面的示例文件定义一个服务,文件名是 /etc/xinet.d/vnc8x6。文件名和服务名应该与在 /etc/services 中添加的代码行的第一个单词(在这里是 vnc8x6)匹配。

service vnc8x6
{
    disable = no
    socket_type = stream
    protocol = tcp
    only_from = 127.0.0.1
    wait = no
    user = nobody
    server = /usr/bin/Xvnc
 # the two lines below must be joined to make a single line in the file you create
       server_args = -inetd -geometry 800x600 -depth 16 -query localhost
         -once securitytypes=none -fp unix/:7100 -desktop "vhost0###@8x6"
   }

字符串 vhost0###@8x6 作为 VNC 窗口的标题。因为可以同时打开许多窗口,所以最好把它设置为短主机名!

定制 X11 显示管理程序 ("Greeter")

编辑文件 /etc/gdm/custom.conf,做以下修改:

[xdmcp]
Enable=true

修改系统的默认运行级别

  1. /etc/inittab 文件中把系统的默认运行级别由 3 改为 5。在文本编辑器中(比如 sudo vi /etc/inittab),修改 initdefault 项:
    id:5:initdefault:
  2. 重新启动 'xinetd':
    sudo /sbin/service xinetd restart
  3. 这让系统把运行级别由 3 (networking) 改为 5 (X11)。可以重新启动实例,但是这更容易更快:
    sudo init 5

为云实例创建 ssvnc 概要文件

这些概要文件用于客户端(您的用户)而不是云实例,但是在有实例配给(创建)时,您很可能希望创建或生成这些概要文件,并且任何自动化都可能发生在 Linux 服务器或桌面平台上,所以放在本节讨论。

下面的 shell 代码片段为希望支持的各种分辨率创建一整套配置文件。

# hostName can be either shortname or FQDN
# vhost0022 is just an example here - use your own host name
hostName="vhost0022"
# userName will typically be 'idcuser'
userName="idcuser"
for thePort in 8 10 11 12 14 16; do
    thePort4Digit=$(echo "$thePort" | awk '{printf("%d", 5900+$1)}')
    profileName=$hostName-$userName-$thePort.vnc
    cat template-user-port.vnc | sed -e "s/@theHost@/$hostName/" \
            -e "s/@theUser@/$userName/"\
            -e "s/@thePort@/$thePort/"\
            -e "s/@thePort4Digit@/$thePort4Digit/" > $profileName
done
zip "$hostName-$userName-VNC-files.zip" $hostName*vnc >&2

上面的片段使用模板文件 template-user-port.vnc

[connection]
host=@theUser@@@theHost@
port=@thePort4Digit@
proxyhost=
proxyport=
disp=@theUser@@@theHost@:@thePort@

[options]
compresslevel_text=Compress Level: 1
ssvnc_escape=default
use_compresslevel=1
use_send_clipboard=1
use_ssh=1

把 SSH 秘密密钥转换为 PuTTY 格式

对于新的云实例,要执行的最后一步是把 OpenSSH 秘密密钥转换为 PuTTY 可以使用的格式。这要使用 PuTTYgen。在 PuTTYgen 中,从 conversion 菜单中选择 import,选择自己的 OpenSSH 密钥文件(例如 id_rsa)并输入密码。导入密钥之后,把它保存到磁盘上(在 c:\ssvnc\Windows\certs 目录中)。应该把扩展名为 ".ppk" 的文件分发给团队成员;他们应该把它保存在同一位置。


客户端设置

下载 ssvnc

下载 ssvnc(见 参考资料)之后,把文件解压到 C: 驱动器上的顶级目录。如果文件正常地解压,会创建子目录 C:\ssvnc。在解压程序中一定要选择 “保留目录” 或相似的选项,从而创建目录结构,然后继续执行下一步。

设置 HOME 环境变量

  1. 右键单击桌面上的 My Computer 并选择 Properties,然后选择 Advanced 选项卡(图 1)。
    图 1. 系统属性
    系统属性
  2. 如果已经设置了 HOME 变量,那么只需记下其内容(稍后需要它);否则,单击 Environment Variables 按钮,然后单击 New 以添加 HOME 变量。图 2 给出一个示例(我使用 c:\bgh,因为我的 Windows 账号是 bgh)。
    图 2. 定义 HOME 环境变量
    定义 HOME 环境变量
  3. 单击 OK 三次以保存更改。

创建 ssvnc 概要文件目录

  1. 打开 Windows® Explorer,进入 C: 驱动器,(如果需要的话)创建自己的主目录(即在前面为 HOME 变量指定的目录)。在这个目录中,创建子目录 ss_vnc
  2. 双击新创建的子目录让它成为当前目录,创建另一个子目录 profiles。现在有了 %HOME%\ss_vnc\profiles 目录:
    图 3. 嵌套的目录
    嵌套的目录

创建运行 ssvnc 会话的快捷方式

获得包含 ssvnc 配置的 zip 文件之后,会发现其内容与图 4 相似:

图 4. 典型的 ssvnc 概要文件 zip 存档文件的内容
典型的 ssvnc 概要文件 zip 存档文件的内容

把这些文件解压到前一小节创建的目录中 (%HOME%\ss_vnc\profiles)。

配置基于 Windows 的 SSH 代理

当要安全地连接远程系统时,首先打开包含 SSH 密钥的秘密部分的 PPK 文件。输入私有密钥的密码以 “解锁” 它。通常,每次连接使用此密钥的任何远程云实例时,都必须输入这个密码,但是有一种安全的方法可以避免这种麻烦:使用 SSH 代理。

在 Windows 上,SSH 代理称为 Pageant,它是 ssvnc 中的 PuTTY SSH 工具集的一部分。登录之后,Pageant 提示输入 SSH 密码;然后它替您保存解锁后的密钥。当连接云实例时,ssvnc 包向 Pageant 请求 SSH 秘密密钥。直到退出并重新登录为止,都不需要再次输入密码。如果在同一会话中连接两个或更多服务器,这个工具很方便。(当然,如果对于每个用户和每个实例使用不同的 SSH 密钥,Pageant 只能为对每个实例的第二次和后续连接提供密钥,但这是实现更高的安全性要付出的代价。)

您应该会收到一个或更多 PuTTY SSH 秘密密钥(PPK 文件)。这些 PPK 文件必须保存在子目录 c:\ssvnc\Windows\certs 中。SSH 密钥文件名应该都是以 id_rsa.ppk 结尾的。例如,密钥文件可能名为 CloudCustomer-Dev-Team-12-Provisioning-Key-id_rsa.ppk

如何配置 SSH 代理

要把 Pageant 设置为在您登录 Windows 时启动。为此,需要 Pageant 程序的路径和 SSH 密钥文件的路径。

  1. 在 Windows 中,右键单击 Start 并选择 Explore
  2. 双击 Programs 子目录打开它,然后双击 Startup 子目录。
  3. 右键单击 Windows Explorer 窗口的右边并选择 New,然后选择 Shortcut(见图 5)。
    图 5. 创建快捷方式
    创建快捷方式
  4. 快捷方式的 "location" 应该与 C:\ssvnc\Windows\util\pageant.exe c:\ssvnc\Windows\certs\<NAME>-id_rsa.ppk 相似。单击 Next,然后单击 Finish
  5. 不需要重新启动计算机或退出并重新登录。只需双击刚创建的快捷方式。应该会提示输入密码(图 6):
    图 6. SSH 代理提示
    SSH 代理提示
  6. 如果正确地输入密码并单击 OK,那么不会看到反馈。如果输入错误,提示再次出现。成功地输入密码之后,在系统托盘上找到计算机带黑帽子的图标(系统托盘通常在屏幕的右下角):
    计算机带黑帽子
  7. 双击这个图标,应该会看到一个窗口。
    图 7. Pageant 密钥列表
    Pageant 密钥列表

如果看到一个包含一行或多行的窗口(见图 7),那么恭喜!

创建运行 ssvnc 会话的快捷方式

在图 4 中,文件名(比如 vhost0022.site1.compute.ihost.com-8.vnc)中的数字表示 ssvnc 配置文件的 VNC 窗口显示器大小(完整的列表见表 1)。

您选择的概要文件创建的窗口一定要小于 物理显示器的分辨率;如果物理显示器屏幕容纳不下整个窗口,那么与远程计算机交互会非常困难(尤其是因为大多数 Linux 桌面环境都把菜单放在屏幕的顶部和底部)。对屏幕大小的进一步说明参见 附录:显示器分辨率和 VNC 显示器大小

表 1. VNC 窗口尺寸与 VNC 文件名的对应关系
文件名中的数字VNC 窗口大小
8800x600
101024x768
111152x864
121280x1024
141400x1050
161600x1200

按以下步骤创建一个快捷方式:

  1. 在桌面上,创建一个快捷方式以连接云实例(同样使用示例所示的 vhost0022)。快捷方式的命令行(即 "location")像下面这样:
    C:\ssvnc\Windows\sshvnc.bat vhost0022.site1.compute.ihost.com-10.vnc

    注意,输入的是 ssvnc 配置文件的文件名,而不是主机名,而且不包含目录。
  2. 单击 Next。可能希望给快捷方式指定 vhost0022-small 或 vhost0022-large 这样的名称,或者只是 vhost0022(如果不使用多种分辨率的话)。
  3. 单击 Finish。应该为每个主机和每个主机的每种分辨率创建快捷方式。

现在设置完成了。应该能够访问云实例 GUI 了。


登录过程

首先,讲解如何通过 ssvnc 登录;然后指出关于登录过程要记住的一些事项。

通过 SSH 连接登录

  1. 双击刚才创建的桌面快捷方式之一。一个或两个窗口弹出,然后消失。

    注意:如果是第一次连接这个云实例,会看到与图 8 相似的代码。

    图 8. 提示您把服务器的 SSH 密钥添加到 PuTTY 缓存中
    提示您把服务器的 SSH 密钥添加到 PuTTY 缓存中
  2. 您可能已经猜到了,服务器按与客户端相同的方式保存 SSH 密钥的一部分。如果愿意,可以比较服务器提供的密钥指纹(它与在把密钥装载进 puttygen 进行转换时看到的值相同)。在第一次连接云实例时,如果输入 "Y",以后就不会再提示。
  3. 过一会儿,VNC 客户端打开登录屏幕。
    图 9. VNC 窗口登录提示
    VNC 窗口登录提示
  4. 窗口的大小取决于选择的 ssvnc 概要文件。使用您的用户 ID 和密码登录远程服务器。
  5. 完成工作之后,关闭会话(使用 System 菜单中的 logout 菜单项)。

关于登录过程要记住的一些事项

下面是关于登录过程要记住的一些事项:

  • 如果觉得需要作为两个不同的用户登录(从本地计算机),是可以的。
  • 您的会话并不会保持活跃状态,等待您以后回来;当到云实例的连接终止时,会话就结束了。
  • 在终端(通过 Accessories 菜单打开的命令行窗口)中,可以使用以下两个命令显示登录的其他用户以及他们已经空闲了多长时间:
    $ w
     04:25:06 up 2 days, 12:20,  4 users,  load average: 1.02, 0.24, 0.07
    USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
    user1    localhos localhost.locald 04:17    0.00s  0.00s  0.10s -/usr/bin/ksh [...] 
    user1    pts/0    localhost.locald 04:17    0.00s  0.11s  0.11s -ksh
    user2    pts/1    localhost.locald 04:25    9.00s  0.14s  0.12s -ksh
    
    $ who -HTu
    NAME       LINE         TIME             IDLE          PID COMMENT
    user1    ? localhost.localdomain:12 2011-03-01 04:17 ? 11042 (localhost.localdomain)
    user1    + pts/0        2011-03-01 04:18   .  11198 (localhost.localdomain:12.0)
    user2    + pts/1        2011-03-01 04:25   .   13444 (localhost.localdomain:10.0)

结束语

本文讨论了如何通过配置 IBM Cloud 上的云实例支持使用 ssvnc,让团队成员能够安全地对虚拟机进行远程图形化访问。介绍了充分利用此功能所需的 Windows 客户端配置步骤,包括如何下载 ssvnc、设置 HOME 环境变量、创建 ssvnc 概要文件目录、创建运行 ssvnc 会话的快捷方式和配置 SSH 代理。本文还讨论了通过 ssvnc 登录和 VNC 显示器大小,包括与登录相关的几个注意事项。


附录:显示器分辨率和 VNC 显示器大小

下表列出对于每种显示器分辨率最合适的 VNC 概要文件,给出分辨率的 “名称”(标识符)和相应的显示器大小(以像素为单位)。

名称分辨率(以像素为单位) ssvnc 概要文件名
XGA1024x768vhost0022.site1.compute.ihost.com-8.vnc
WXGA1280x768vhost0022.site1.compute.ihost.com-8.vnc
WXGA1280x800vhost0022.site1.compute.ihost.com-10.vnc
SXGA1280x1024vhost0022.site1.compute.ihost.com-11.vnc
SXGA+1400x1050vhost0022.site1.compute.ihost.com-12.vnc
UXGA1600x1200vhost0022.site1.compute.ihost.com-14.vnc
WSXGA+1680x1050vhost0022.site1.compute.ihost.com-14.vnc
HD 10801920x1080vhost0022.site1.compute.ihost.com-14.vnc
WUXGA1920x1200vhost0022.site1.compute.ihost.com-14.vnc
QXGA2048x1536vhost0022.site1.compute.ihost.com-16.vnc
WQXGA2560x1600vhost0022.site1.compute.ihost.com-16.vnc
QSXGA2560x2048vhost0022.site1.compute.ihost.com-16.vnc

前两列显示一些物理显示器的分辨率。对于每种分辨率,第三列中给出最合适的 VNC 概要文件名(这是在显示器能够完全容纳的前提下最大的 VNC 窗口。如果 VNC 窗口太大,那么不得不向上滚动才能看到顶部菜单,向下滚动才能看到底部菜单/任务栏。这是严重的易用性问题)。

参考资料

学习

获得产品和技术

  • 查看可以在 IBM Smart Business Development and Test on the IBM Cloud 上使用的 产品映像

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Cloud computing
ArticleID=696998
ArticleTitle=用 VNC 和 SSH 保护对 IBM Cloud 实例的多用户访问
publish-date=07042011