最近在搞VDI安全研究,公司正好用的是redhat的spice协议,所以正好想把研究结果做个总结记录。
Spice协议是redhat开发的开源的桌面虚拟化数据传输协议,提供客户端访问远程机器显示和设备(如键盘、鼠标、音频、usb)。Spice实现了类似于与本地机器交互的用户体验,同时尝试将大部分密集型CPU和GPU任务转移给客户端。
Spice的基本构建块是Spice协议、Spice服务器和Spice客户端。与spice相关的组件包括QXL设备和客户QXL驱动程序。
Spice服务器
Spice服务器是一个libspice(一个VDI可插入的库)的实现。VDI是virtual device interface的简称,VDI定义了一个接口集合,这个接口提供了一个开放虚拟设备(比如显示设备,键盘,鼠标)的方法并且让不同的spice组件与其他的设备进行交互。在一方面,这个服务器与远程的客户端使用spice协议交流,在另一方面,服务器与VDI主机应用进行交流(例如QEMU)。
Spice客户端
Spice跨平台(linux&windows)客户端是面向终端用户的接口
QXL 设备和驱动
Spice服务器支持QXL VDI接口,当libspice库被QEMU使用时,一个特殊的QEMU QXL PCI设备被使用,这个设备是为了改善远端的展示行为和优化客户系统的图形功能,QXL设备要求客户的QXL驱动功能完备。然而,标准的VGA是支持没有驱动存在的。
VDI端口设备
Spice协议支持在客户端和服务器代理端的交流,当使用QEMU时spice代理存在在客户端中,VDI端口是一个QEMU PCI设备,这个QEMU PCI设备作为交流所用的代理被使用。
Spice代理
Spice代理是一个为了增强用户体验和执行客户管理任务可选择的组件。例如:当使用了客户端的鼠标模块时候,一个代理注入了鼠标位置并且声明了客户的状态。另外,它也被用作一种展示客户设置的结构。
服务器和客户端通过channel来信息交互,每个channel是专用的一种特殊的数据类型,这个可用的channel是:
Spice提供了几种图像压缩算法,可以在服务器启动时选择,并在运行时动态选择。Quic是Spice专有的图像压缩工具,它是基于SFALIC算法。LZ算法,调整到图像,是另一个选择。Quic和LZ都是局部算法,它们独立地对每个图像进行编码。Global LZ (GLZ)是Spice的另一个专有技术,它使用LZ和基于历史的全局字典。GLZ利用图像之间的重复模式来减少流量和节省带宽,这在广域网路环境中是至关重要的。Spice还为每幅图像提供了自动压缩选择模式,其中LZ/GLZ和Quic之间的选择是基于图像属性的直观选择。从概念上讲,LZ/GLZ能更好地压缩人工图像,而Quic能更好地压缩真实图像。
Spice对发送到客户端的图像使用无损压缩,而不是有损压缩,以避免破坏重要的显示对象。
Spice实现了客户端映像缓存,以避免向客户端进行冗余传输。缓存适用于发送到客户机的任何类型的图像数据,包括像素映射、调色板和游标。从驱动程序到达的每个映像都有一个惟一的id和一个缓存提示。不相同的图像具有不同的id,而相同的图像共享相同的id。缓存提示建议服务器缓存图像。Pixmap缓存在所有显示之间共享。每个连接定义一个缓存,服务器和客户端之间同步缓存。,在每个时刻,服务器确切地知道哪些映像在客户端缓存中。此外,服务器将决定是否从缓存中添加或删除项。客户端缓存大小由客户端设置,并通过显示通道初始化消息传输到服务器。服务器监视当前缓存容量,当缺少空间时,它会删除最近最少使用的缓存项,直到有足够的可用缓存空间。服务器用这些项发送一个invalidate命令,客户端删除这些项。
Spice通信会话被分成多个沟通渠道(例如,每一个频道都是远程设备)为了有能力控制通信和执行根据通道类型的消息(例如QoS加密), 并添加和删除沟通渠道在运行时(这是由spice协议定义)。
a). main channel作为主要的spice会话连接
b). display channel 用于接收远程显示更新
c). input channel用于发送鼠标和键盘事件
d). cursor channel用于接收指针形状和位置
e). playback用于接收音频流
f). record channel用于发送音频捕获
1). 客户端首先发起一个请求SpiceLinkMessage,这个请求中包含一个一些基础信息,如magic, version, session_id等
2). 服务端收到客户端发来的请求后,会回复SpiceReplyMessage,在这个应答中包含了SPICE_LINK_ERR_?, 如果没有错误代码,则建立有效的连接。
3). 根据服务端 的返回,客户端选择spice授权认证方式, 并告知服务端
4). 服务端生成一个1024 bit RSA key, 将public key部分发送给客户端
5). 客户端使用服务端发来的public key加密password, 这里类似于https的原理。加密password后,将其发送给服务端
6). 服务端解密password,将他与服务端的ticketing进行比较,确保它在允许范围内收到
ticketing是spice中实现的一种机制,用于确保只打开来自授权来源的连接
Ticketing 中应该包含 password + time validity
1. 只有在SPICE_CHANNEL_MAIN建立连接后, 才允许其他channel建立连接
2. 一个spice会话只允许一个SPICE_CHANNEL_MAIN连接
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。