openstack面板或命令行提供两种方式来对客户虚拟机进行远程桌面访问,vnc控制台和spice html5。
vnc控制台
openstack提供一个组件nova-novncproxy,它允许用户通过浏览器或vnc客户端来访问虚拟机。
通常,通过websocket来访问虚拟时,vnc控制台工作步骤如下:
1. 用户通过vnc控制台发送一个url请求,url的格式是:http://ip:port/?token=xxx,该地址实际上就是vnc控制台代理的地址;
2. openstack获取url地址,通过nova api发送消息给compute节点;
3. compute节点libvert driver获取到vnc 链接的消息;
4. 同时nova api发送认证请求给nova-consoleauth来验证token;
5. vnc proxy与nova-consoleauth交互来验证token,并将token映射到虚拟机所在的宿主机的ip地址和某个端口,该端口就是虚拟机启动时所监听的端口;
6.compute通过nova.conf文件选项vncserver_proxyclient_address指定代理用于连接的地址;
7. vnc proxy与虚拟机所在的宿主机的vncserver建立连接,并开始代理,直到浏览器session结束。
openstack实现vnc控制台远程访问虚拟机的实现方法可以概括如下:
通常情况下,为了提供完整的vnc功能,openstack服务器需要部署三个服务:
· nova-consoleauth: 提供token验证,维护token与ip地址、端口号的映射。通常部署在控制节点上。
· nova-novncproxy: 支持基于浏览器的novnc 客户端,通常与nova-api部署在一起,它作为公共网络和专用计算主机网络之间的代理运行。
· nova-xvpvncproxy: 支持基于java的vnc客户端,,通常与nova-api部署在一起,它作为公共网络和专用计算主机网络之间的代理运行。
此外还需要对compute节点进行适当的配置。在nova.conf文件中配置如下内容:
· vnc_enabled=true 启用虚拟机的vnc功能。
· vncserver_listen=0.0.0.0 默认是127.0.0.1,即只可以从本机进行访问,通常情况下是配置为管理网的ip地址。设置为0.0.0.0主要是考虑到虚拟机热迁移时,目的宿主机没有相应的ip地址,热迁移会失败。
· vncserver_proxyclient_address=127.0.0.1 该地址指明vnc proxy应该通过那个ip地址来连接vncserver,通常是管理网ip地址。
· novncproxy_base_url=http://127.0.0.1:6080/vnc_auto.html 指定vnc控制台代理的地址,通过这个地址连接到vncserver。
· xvpvncproxy_base_url=http://127.0.0.1:6081/console 指定nova xvp vnc控制台代理的地址。
计算节点在nova.conf文件中,通过vncserver_proxyclient_address参数指定vncserver的监听地址及vnc proxy应该通过哪个地址连接到vncserver。vnc proxy充当了公网和计算节点之间的桥梁。
另外,对于vnc proxy的配置则相对简单,只需要设置其监听的主机和端口即可。具体如下:
· novncproxy_host=$service_host 通常为宿主机的管理网ip。
· novncproxy_host=6080 vnc控制台访问的地址端口
· xvpvncproxy_host=$service_host 通常为宿主机的管理网ip。
· xvpvncproxy_port=6081 xvp vnc控制台访问的地址端口
完成以上配置后,openstack服务器在启动一个虚拟机时, kvm将vnc的参数加到虚拟机实例对应的libvirt文件中(/etc/libvirt/qemu/instance***.xml),此虚拟机启动完成后将支持vnc控制台的访问。
<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'/>
spice html5
openstack计算机支持向用户提供vnc控制台来远程访问虚拟机,但是vnc协议的使用也是受限的,缺乏对多显示器、双向音频、可靠的剪切和粘贴、视频流等的支持。spice是一种新的协议,旨在解决vnc中的限制,并提供良好的远程桌面支持。
spice协议支持共享了一个与vnc类似的实现结构。openstack面板在其控制台选项卡中使用一个spice-html5小部件,通过使用spice–over-websockets与nova-spicehtml5proxy服务通信,nova-spicehtml5proxy服务通过使用spice直接与hypervisor进程通信。
spice控制台的访问实现配置必须显式禁用vnc。在[default]部分将vnc_enabled选项设置为false,以禁用vnc控制台。然后配置spice的相关参数如下:
[spice]
agent_enabled = false
enabled = true
html5proxy_base_url = http://ip_address:6082/spice_auto.html
html5proxy_host = 0.0.0.0
html5proxy_port = 6082
keymap = en-us
server_listen = 127.0.0.1
server_proxyclient_address = 127.0.0.1
以上参数的含义与vnc配置类似,不再详述。
安全的vnc访问
默认的vnc服务器访问不使用任何形式的身份验证。 在前面的示例中,任何用户都可以从网络上的任何主机连接和查看虚拟机的vnc会话。这样的话就会存在安全漏洞:
nessus扫描漏洞:vnc server unauthenticated access。对此,我们可以将多种安全级别应用于vnc客户端/服务器连接。其中包含两种身份验证类型:sasl和单密码身份验证,以及使用密码保护的x509证书认证。
使用单密码的身份认证
这种配置比较简单,直接修改虚拟机对应的xml配置文件,添加passwd属性即可。
<graphics type='vnc' port='-1' autoport='yes' listen='192.168.1.5' passwd='your-password-here' keymap='en-us'/>
? 使用sasl的用户名和密码认证
sasl(simple authentication and security layer)提供用户名和密码身份验证以及数据加密(默认情况下为digest-md5)。要配置sasl身份验证,请执行以下操作:
1. 更改/etc/libvirt/libvirtd.conf中的配置,如下所示:
a.启用tcp连接支持sasl:
auth_tcp = "sasl"
b.启用tls/ssl连接sasl:
auth_tls = "sasl"
2. 重启libvertd
rclibvirtd restart
3. libvirt关于sasl配置文件位于/etc/sasl2/libvirtd.conf。 通常,无需更改默认值。 但是,如果在tls之上使用sasl,则可以通过注释mech_list来关闭会话加密以避免额外开销 - tls连接已加密。 对于tcp连接,此参数必须设置为digest-md5:
mech_list: digest-md5 # mandatory for tcp connections
#mech_list: digest-md5 # apply default (username+password) tls/ssl only!
4. 由于sasl维护自己的用户数据库,默认情况下如果未配置任何sasl用户,则无法进行登录。可以使用以下命令添加,列出和删除用户:
mercury:~ # saslpasswd2 -a libvirt tux # add user tux
password:
again (for verification):
mercury:~ # sasldblistusers2 -f /etc/libvirt/passwd.db # list users
tux@mercury.example.com: userpassword
mercury:~ # saslpasswd2 -a libvirt -d tux # delete user tux
? 使用x509证书认证
此方法是在vnc服务器上启用tls(transport layer security)加密。这要求vnc客户端可以访问x509客户端证书,通过限制对这些证书的访问,可以在客户端间接控制访问。具体实现步骤如下:
首先,生成x509客户端/服务器正确(这里不详细介绍,请自行搜索)。下面,我们假设服务器x509证书分布在服务器的以下位置:
/etc/pki/ca/cacert.pem
/etc/pki/libvirt/servercert.pem
/etc/pki/libvirt/private/serverkey.pem
而客户端的证书分布在客户端的以下位置:
/etc/pki/ca/cacert.pem
/etc/pki/libvirt-vnc/clientcert.pem
/etc/pki/libvirt-vnc/private/clientkey.pem
证书到位后,可以为libvirt启用tls支持。
对于vm host server,需要进行如下配置:
1. 默认情况下,libvirt使用tcp端口16514接受安全的tls连接。 在防火墙中打开此端口。
2. 编辑/etc/libvirt/libvirtd.conf,设置listen_tls=1;
3. 创建目录/ etc / pki / libvirt-vnc并将证书链接到此目录
mkdir -p /etc/pki/libvirt-vnc && cd /etc/pki/libvirt-vnc
ln -s /etc/pki/ca/cacert.pem ca-cert.pem
ln -s /etc/pki/libvirt/servercert.pem server-cert.pem
ln -s /etc/pki/libvirt/private/serverkey.pem server-key.pem
4. 编辑/etc/libvirt/qemu.conf,设置以下参数:
vnc_listen = "0.0.0.0"
vnc_tls = 1
vnc_tls_x509_verify = 1
5、重启libvirt
rclibvirtd restart
最后,测试客户端/服务器的设置是否正确:
virsh -c qemu+tls://mercury.example.com/system list –all
将mercury.example.com替换为虚拟机所在主机的hostname
如果配置正确,你将看到虚拟机所在host主机上注册了libvirt的所有虚拟机实例列表。
访问权限控制
每个x509证书都由两部分组成:公共证书和私钥。 客户端需要使用两个部分进行身份验证。 因此,对客户端证书及其私钥具有读访问权限的任何用户都可以访问虚拟主机。 另一方面,配备完整服务器证书的任意机器可以伪装成vm主机服务器。因此需要尽可能地控制对密钥文件的访问来限制访问权限。
本期作者 启迪云 黄冬琪