WebSocketProxy 中加密和身份验证的支持

https://blueprints.launchpad.net/nova/+spec/websocket-proxy-to-host-security

目前,虽然 noVNC、HTML5 SPICE 和串口控制台客户端可以使用 TLS 加密的 WebSocket 与 nova websocket 代理服务器通信(并使用 Nova 控制台令牌进行身份验证),但加密和身份验证到此为止。WebSocket 代理和计算节点 VNC、SPICE 和串口控制台服务器之间既没有加密也没有身份验证。

本文档描述了为所有三种服务添加 TLS 以提供加密,并使用 x509 证书来验证与计算节点控制台服务器的连接尝试的身份验证。

问题描述

目前,WebSocket 代理服务器和计算节点 VNC、SPICE 和串口控制台服务器之间既没有身份验证也没有加密。如果恶意实体能够访问 OpenStack 部署的“内部”网络,他们可以执行三种攻击

  • 被动窃听代理和计算节点之间的所有流量。这可能允许攻击者识别与租户用户密码相关的击键,或查看虚拟桌面上显示的敏感信息。

  • 主动冒充代理服务器,连接到计算节点 VNC、SPICE、串口控制台服务器,查看租户的数据并与其机器交互。

  • 主动冒充计算节点,为代理服务器提供欺骗性的远程桌面进行连接。这允许攻击者修改桌面上的信息以达到自己的目的。

用例

这解决了 VNC、SPICE 或串口控制台为 Nova 的生产部署启用,并且 Nova WebSocketProxy 正在运行的情况。

目标是提供针对上述三种攻击场景的保护。它们将按以下方式被阻止

  • 通过使用 TLS 加密远程桌面会话数据,将阻止对 VNC、SPICE 和串口控制台之间代理和计算节点流量的被动窃听。

  • 通过启用 x509 证书,将阻止对 VNC 和串口控制台的代理服务器的积极冒充。代理服务器必须在连接时向计算节点提供自己的证书,计算节点将根据其允许的白名单验证该证书。目前 SPICE 不支持验证客户端 x509 证书。如果 SPICE 维护者开发了此功能,它也将添加到 Nova 中。

  • 通过使用 x509 证书,将阻止对 VNC、SPICE 和串口控制台的计算节点的积极冒充。计算节点会将证书发送到代理服务器,然后代理服务器将根据 CA 证书验证该证书。

这种保护基于攻击者无法从用于计算节点和代理服务器的机构获得 x509 证书的假设。

提议的变更

此蓝图将在 websocket 代理类中引入回调函数,以启用安全功能的协商,例如 TLS 加密、x509 证书验证和其他身份验证方案。这些钩子能够选择性地执行协议特定的握手,然后修改代理和计算节点之间的套接字,用 TLS 包装的套接字或等效套接字替换默认的明文套接字。

目标是实现 VNC 的 VeNCrypt 身份验证方案,该方案需要提供一个能够执行基本的 RFB 协议握手/协商的安全代理钩子。

对于 SPICE 和串口控制台,只需用 TLS 包装的套接字替换默认的明文套接字就足够了。无需参与 SPICE 协议协商,因为 TLS 在协议开始之前就已经启用。

这不会影响迁移,因为该更改不需要更新来宾 XML 配置。它只是计算节点上的主机级别配置设置。

备选方案

  • 实现端到端安全性:这将需要支持 HTML5 客户端中更高级的加密和身份验证。不幸的是,这需要在浏览器中进行密码学,在更多浏览器开始实现 HTML5 WebCrypto API 之前,这实际上是不可行的。端到端安全性还将意味着远程租户客户端能够直接查看与计算节点关联的 x509 证书。这迫使部署者对云内部和公共互联网上的连接使用相同的 x509 证书颁发机构。从可管理性的角度来看,完全分离用于内部网络的 CA 和用于面向公众的租户服务器的 CA 是非常可取的。

  • 使用像 stunnel 这样的工具:这存在一些问题。首先,它将我们锁定到特定的身份验证机制——stunnel 对于 TLS 来说很好,但如果我们要使用 SASL,则无法工作。第二个问题是它绕过了正常的 VNC 安全协商,后者在明文中执行初始握手,然后在稍后进行安全协商。期望保持在标准 RFB(VNC)规范的范围内。第三个问题是这将回避身份验证问题——除非您明确设置防火墙以阻止对普通 VNC 端口的远程连接(这需要部署者进行更多设置——我们希望使其易于使用),否则恶意实体仍然可以连接到未经过身份验证的端口。

数据模型影响

无。

REST API 影响

无。

安全影响

实际使用的加密将取决于所使用的驱动程序。确保用于任何已实现驱动程序的库实际上是安全的非常重要。

假设驱动程序是安全的并且实现了身份验证和加密,则部署的安全性将得到加强。

对于新部署,所有计算节点,因此所有 VM 都可以立即启用 TLS。控制台代理节点可以因此强制所有连接使用 TLS。但是,在升级现有部署时,控制台代理节点需要允许某些 VM / 计算节点使用非 TLS 连接。在此过渡期间,控制台代理可能会受到 MITM 降级攻击,攻击者会剥离 TLS。这与所有现有 Nova 版本中以明文运行所有计算节点的安全风险没有区别。它只是意味着在所有计算节点和正在运行的 VM 都升级为使用 TLS 之前,无法获得完整的安全优势。完成此操作并设置 tls_required 配置选项为 true 后,将不再可能进行降级攻击。

通知影响

无。

其他最终用户影响

无。

性能影响

最小。额外的加密很可能通过基于 C 的 Python 库执行,因此开销相对较低。

其他部署者影响

对于 VNC,部署者必须启用使用“vencrypt”身份验证方案。这将通过一个新的 [vnc] auth_schemes 配置参数来完成,该参数接受一个字符串列表,用于标识要尝试的 VNC 身份验证方案。

当选择 vencrypt 方案时,部署者还必须为 novncproxy 服务提供 x509 证书配置

[vnc]
tls_ca_certs = /path/to/ca-cert-bundle.pem
tls_client_cert = /path/to/client-cert.pem
tls_client_key = /path/to/client-key.pem

此外,还需要配置虚拟化主机以启用 VNC 使用 TLS。对于 QEMU/KVM 计算节点,这将涉及修改 /etc/libvirt/qemu.conf 并向计算节点颁发 x509 证书。(参见 参考文献)。

在为现有部署启用 vencrypt 时,将需要两个阶段。最初,[vnc]auth_schemes 配置参数需要列出 vencryptnone 身份验证方案。这允许代理连接到未启用 TLS 的预先部署的计算主机和新更新的启用 TLS 的计算主机。一旦所有计算主机都更新为启用 TLS,[vnc] auth_schemes 配置参数可以切换为仅允许 vencrypt

对于 SPICE,部署者还必须为 spicehtml5proxy 服务提供 x509 证书配置

[spice]
tls_ca_certs = /path/to/ca-cert-bundle.pem
tls_required = <boolean>

请注意,SPICE 当前不使用客户端证书,因此没有与 [vnc] tls_client_cert 参数等效的内容。

此外,还需要配置虚拟化主机以启用 SPICE 使用 TLS。对于 QEMU/KVM 计算节点,这将涉及修改 /etc/libvirt/qemu.conf 并向计算节点颁发 x509 证书。(参见 参考文献)。

在为现有部署启用 TLS 时,将需要两个阶段。最初,[spice] tls_required 配置参数将设置为 False。这允许代理连接到未启用 TLS 的预先部署的计算主机和新更新的启用 TLS 的计算主机。一旦所有计算主机都更新为启用 TLS,[spice] tls_required 配置参数可以切换为 True

对于串口控制台,部署者必须通过提供 CA 证书捆绑包,以及可选的客户端证书和密钥来启用 TLS 的使用

[serial_console]
tls_ca_certs = /path/to/ca-cert-bundle.pem
tls_client_cert = /path/to/client-cert.pem
tls_client_key = /path/to/client-key.pem
tls_required = <boolean>

此外,还需要配置虚拟化主机以启用串口使用 TLS。对于 QEMU/KVM 计算节点,这将涉及修改 /etc/libvirt/qemu.conf 并向计算节点颁发 x509 证书。(参见 参考文献)。

在为现有部署启用 TLS 时,将需要两个阶段。最初,[serial_console] tls_required 配置参数将设置为 False。这允许代理连接到未启用 TLS 的预先部署的计算主机和新更新的启用 TLS 的计算主机。一旦所有计算主机都更新为启用 TLS,[serial_console] tls_required 配置参数可以切换为 True

开发人员影响

其他非 QEMU 虚拟机不支持 VNC / SPICE / 串口 TLS 加密,因此这项工作仅与 libvirt 和 QEMU/KVM 相关。如果其他虚拟机以后获得 TLS 支持,则应该可以轻松地使用为 libvirt 和 QEMU 完成的增强功能来启用它。

实现

负责人

主要负责人

Stephen Finucane <stephenfin>

其他贡献者

Daniel Berrangé <berrange>

工作项

  1. 修改 websocket 代理基类以添加子类可以用来实现加密和身份验证的钩子。

  2. 创建一个用于实现 VNC 身份验证机制的框架。

  3. 创建一个 websockets 代理安全驱动程序,该驱动程序可以在适当的时候执行 VNC 协议协商,调用 VNC 身份验证方案。

  4. 修改 novncproxy 服务器以启用 VNC 安全驱动程序

  5. 修改 spicehtml5proxy 服务器以使其能够在需要时打开 SSL 套接字

  6. 修改 devstack 以使其能够为计算节点和安全代理节点生成合适的证书并为 VNC、SPICE 和串口控制台启用 TLS。

  7. 修改 tempest 以执行远程控制台服务的黑盒测试,以验证在启用 TLS 时是否可以成功建立控制台连接。

  8. 修改文档以描述使用 TLS 安全启用部署计算节点和控制台代理服务器的过程。

依赖项

VNC 和 SPICE 功能的支持已在 Nova 支持的所有 QEMU 和 Libvirt 版本中可用,因此可以使用当前 gate CI 节点进行测试。

对串口控制台 TLS 功能的支持需要 QEMU >= 2.6 和 libvirt >= 2.2.0。缺少这些版本的部署必须继续以明文模式使用串口控制台,直到升级为止。

测试

Tempest 已得到增强,以验证打开 VNC 和 SPICE 的远程控制台的能力。将包含单元测试。

文档影响

我们需要记录新的配置选项,以及如何为 TLS 驱动程序生成证书(参见 其他部署者影响)。

参考资料

历史

修订版

发布名称

描述

Kilo

引入

Liberty

重新提出

Mitaka

重新提出

Newton

重新提出

Ocata

重新提出

Pike

重新提出

Queens

重新提出