[ English | Indonesia | русский ]

使用 SSL 证书保护服务

OpenStack 安全指南》建议在 OpenStack 部署中的各种服务之间提供安全的通信。OpenStack-Ansible 项目目前提供了配置 SSL 证书以实现服务之间安全通信的能力

所有公共端点都位于 HAProxy 之后,因此对外可见的 https 服务的唯一证书管理是针对 HAProxy 的。某些内部服务,例如 RabbitMQ,也需要正确的 SSL 配置。

使用 OpenStack-Ansible 部署时,您可以使用在部署过程中生成的自签名证书,也可以提供来自您自己的受信任证书颁发机构的 SSL 证书、密钥和 CA 证书。高度安全的環境使用受信任的、用户提供的证书来尽可能多地保护服务。

注意

/etc/openstack_deploy/user_variables.yml 文件中执行所有 SSL 证书配置。不要编辑 playbook 或 role 本身。

OpenStack-Ansible 使用 ansible role ansible_role_pki 作为通用工具来管理和安装自签名证书和用户提供的证书。

注意

OpenStack-Ansible 示例配置旨在成为最小示例,并且在测试或开发用例中会将 external_lb_vip_address 设置为 HAProxy 外部端点的 IP 地址。对于生产部署,建议将 external_lb_vip_address 设置为通过 DNS 解析到外部端点 IP 的 FQDN。

自签名证书

自签名证书使您可以快速启动并加密传输中的数据。但是,它们不会为高度安全的環境中的公共端点提供高级别的信任。默认情况下,OpenStack-Ansible 使用自签名证书。使用自签名证书时,证书验证会自动禁用。

自签名证书可以在保护 OpenStack-Ansible 部署中的内部服务方面发挥重要作用,因为它们只能由与部署关联的私有 CA 颁发。使用 RabbitMQ 和 MariaDB 等后端服务之间的相互 TLS 以及自签名证书和强大的 CA 设置可以确保只有经过正确身份验证的客户端才能连接到这些内部服务。

生成和重新生成自签名证书颁发机构

自签名证书颁发机构在 playbook 的首次运行期间在部署主机上生成。

要重新生成证书颁发机构,必须将 openstack_pki_regen_ca 变量设置为要重新生成的根 CA 或中间 CA 的名称,或者设置为 true 以重新生成所有自签名证书颁发机构。

# openstack-ansible -e "openstack_pki_regen_ca=ExampleCorpIntermediate" certificate-authority.yml

请特别注意不要以可能使部署中现有的服务器证书失效的方式重新生成根或中间证书颁发机构。最好创建新的中间 CA 证书,而不是重新生成现有的证书,以维护现有的信任链。

生成和重新生成自签名证书

在 playbook 的首次运行期间,为每个服务生成自签名证书。

要重新生成服务的新的自签名证书,必须将 <servicename>_pki_regen_cert 变量设置为 true,可以通过以下方式之一实现

  • 要强制自签名证书重新生成,您可以将变量传递给 openstack-ansible 命令

    # openstack-ansible -e "haproxy_pki_regen_cert=true" haproxy-install.yml
    
  • 要强制每次 playbook 运行都重新生成自签名证书,请将适当的重新生成选项设置为 true。例如,如果您已经运行了 haproxy playbook,但您想重新生成自签名证书,请将 haproxy_pki_regen_cert 变量设置为 true/etc/openstack_deploy/user_variables.yml 文件中

    haproxy_pki_regen_cert: true
    

生成和重新生成自签名用户证书

自签名用户证书已生成,但未安装在 OpenStack-Ansible 之外的服务中。这些用户证书由与 OpenStack 服务使用的相同的自签名证书颁发机构签名,但旨在由用户应用程序使用。

要生成用户证书,请在 /etc/openstack_deploy/user_variables.yml 文件中定义一个以 user_pki_certificates_ 为前缀的变量。

示例

user_pki_certificates_example:
   - name: "example"
     provider: ownca
     cn: "example.com"
     san: "DNS:example.com,IP:x.x.x.x"
     signed_by: "{{ openstack_pki_service_intermediate_cert_name }}"
     key_usage:
       - digitalSignature
       - keyAgreement
     extended_key_usage:
       - serverAuth

使用以下命令生成证书

# openstack-ansible certificate-generate.yml

要重新生成服务的新的自签名证书,必须将 user_pki_regen_cert 变量设置为 true,可以通过以下方式之一实现

  • 要强制自签名证书重新生成,您可以将变量传递给 openstack-ansible 命令

    # openstack-ansible -e "user_pki_regen_cert=true" certificate-generate.yml
    
  • 要强制每次 playbook 运行都重新生成自签名证书,请将 user_pki_regen_cert 变量设置为 true/etc/openstack_deploy/user_variables.yml 文件中

    user_pki_regen_cert: true
    

用户提供的证书

为了在高度安全的環境中获得更高的信任度,您可以提供自己的 SSL 证书、密钥和 CA 证书。从受信任的证书颁发机构获取证书不在本文档的范围内,但 Linux 文档项目 证书管理 部分解释了如何创建自己的证书颁发机构并签名证书。

使用以下过程在 OpenStack-Ansible 中部署用户提供的 SSL 证书

  1. 将您的 SSL 证书、密钥和 CA 证书文件复制到部署主机。

  2. /etc/openstack_deploy/user_variables.yml 文件中指定 SSL 证书、密钥和 CA 证书的路径。

  3. 运行该服务的 playbook。

HAProxy 示例

要设置的变量提供部署节点上 HAProxy 配置的证书路径是

haproxy_user_ssl_cert: /etc/openstack_deploy/ssl/example.com.crt
haproxy_user_ssl_key: /etc/openstack_deploy/ssl/example.com.key
haproxy_user_ssl_ca_cert: /etc/openstack_deploy/ssl/ExampleCA.crt

RabbitMQ 示例

要部署 RabbitMQ 的用户提供的证书,请将证书复制到部署主机,编辑 /etc/openstack_deploy/user_variables.yml 文件并设置以下三个变量

rabbitmq_user_ssl_cert:    /etc/openstack_deploy/ssl/example.com.crt
rabbitmq_user_ssl_key:     /etc/openstack_deploy/ssl/example.com.key
rabbitmq_user_ssl_ca_cert: /etc/openstack_deploy/ssl/ExampleCA.crt

然后,运行 playbook 以应用证书

# openstack-ansible rabbitmq-install.yml

playbook 将您的用户提供的 SSL 证书、密钥和 CA 证书部署到每个 RabbitMQ 容器。

该过程对于其他服务而言是相同的。将先前的配置变量中的 rabbitmq 替换为 horizonhaproxykeystone,然后运行该服务的 playbook 以将用户提供的证书部署到这些服务。

Certbot 证书

HAProxy ansible role 支持使用 Certbot 自动部署公共端点的受信任 SSL 证书。每个 HAProxy 服务器将单独使用 Certbot 请求 SSL 证书。

Certbot 默认使用 Let’s Encrypt 作为证书颁发机构,可以通过在 /etc/openstack_deploy/user_variables.yml 文件中设置 haproxy_ssl_letsencrypt_certbot_server 变量来使用其他证书颁发机构

haproxy_ssl_letsencrypt_certbot_server: "https://acme-staging-v02.api.letsencrypt.org/directory"

Certbot 使用 http-01 类型的挑战来部署证书,因此要求公共端点可以直接被证书颁发机构访问。

使用 Let’s Encrypt 部署证书在 Ubuntu 24.04 (Noble Numbat) 上为 OpenStack-Ansible 进行了验证。其他发行版应该可以工作,但未经测试。

要使用 Certbot 部署证书,请将以下内容添加到 /etc/openstack_deploy/user_variables.yml 以在 HAProxy ansible role 中启用 Certbot 功能,并创建一个名为 certbot 的新后端服务来服务 http-01 挑战请求。

haproxy_ssl: true
haproxy_ssl_letsencrypt_enable: true
haproxy_ssl_letsencrypt_email: "email.address@example.com"

HAProxy 内部虚拟 IP (VIP) 的 TLS

除了负载均衡公共端点之外,HAProxy 还用于负载均衡内部连接。

默认情况下,OpenStack-Ansible 不会保护到内部 VIP 的连接。要启用此功能,必须在 /etc/openstack_deploy/user_variables.yml 文件中设置以下变量

openstack_service_adminuri_proto: https
openstack_service_internaluri_proto: https

haproxy_ssl_all_vips: true

运行所有 playbook 以配置 HAProxy 和 OpenStack 服务。

启用后,HAProxy 将在所有接口(内部和外部)上使用相同的 TLS 证书。目前在 OpenStack-Ansible 中,无法在不同的 HAProxy 接口上使用不同的自签名或用户提供的 TLS 证书。

使用内部和外部 VIP 上不同的 TLS 证书的唯一方法是使用 Certbot。

在现有部署中启用内部 VIP 上的 TLS 将导致一些停机时间,因为 HAProxy 仅在每个 OpenStack 服务的一个已知端口上侦听。这意味着一旦 HAProxy 更新为仅接受 HTTPS 连接,OpenStack 服务将停止工作,直到它们更新为使用 HTTPS。

为了避免停机时间,建议在所有服务配置正确之前启用 openstack_service_accept_both_protocols。它允许 HAProxy 前端侦听 HTTP 和 HTTPS 连接。

HAProxy 后端的 TLS

HAProxy 与服务后端之间的通信可以加密。目前默认情况下已禁用。可以通过设置以下变量为所有服务启用它

openstack_service_backend_ssl: true

也可以选择仅为单个服务启用它

keystone_backend_ssl: true
neutron_backend_ssl: true

默认情况下,将使用自签名证书来保护流量,但用户提供的证书也受支持。

Live 迁移的 TLS

使用 SSH 进行 VM 的实时迁移已被弃用,OpenStack Nova 文档 建议使用 QEMU 支持的更安全的本机 TLS 方法。OpenStack-Ansible 中使用的默认实时迁移方法已更新为使用 TLS 迁移。

QEMU 本机 TLS 要求所有计算主机接受端口 16514 和端口范围 49152 到 49261 上的 TCP 连接。

在某些计算节点使用 SSH 并且某些计算节点使用 TLS 进行实时迁移是不可能的,因为这将阻止计算节点之间的实时迁移。

如果在 OpenStack 升级期间需要实时迁移实例,则在升级之前或之后启用 TLS 实时迁移,则不会对启用 TLS 实时迁移产生任何问题。

要强制使用 SSH 而不是 TLS 进行实时迁移,必须将 nova_libvirtd_listen_tls 变量设置为 0/etc/openstack_deploy/user_variables.yml 文件中

nova_libvirtd_listen_tls: 0

VNC 的 TLS

在使用 VNC 进行控制台访问时,有 3 个连接需要保护,客户端到 HAProxy,HAProxy 到 noVNC 代理和 noVNC 代理到计算节点。OpenStack Nova 文档中的远程控制台访问 更详细地介绍了控制台安全性。

在 OpenStack-Ansible 中,TLS 到 HAProxy 在 HAProxy 中配置,HAProxy 到 noVNC 的 TLS 当前未启用,并且 noVNC 到计算节点的 TLS 默认情况下已启用。

更改不会应用于计算节点上任何现有的正在运行的客户机,因此在启动任何实例之前应进行此配置。对于现有部署,建议在启用之前将实例迁移到计算节点。

为了帮助从未加密的 VNC 到 VeNCrypt 的过渡,noVNC 代理身份验证方案最初允许使用变量 nova_vencrypt_auth_scheme 使用加密和未加密会话。在 OpenStack-Ansible 的未来版本中,这将仅限制为 VeNCrypt。

nova_vencrypt_auth_scheme: "vencrypt,none"

要不加密 noVNC 代理到计算节点的数据,必须将 nova_qemu_vnc_tls 变量设置为 0/etc/openstack_deploy/user_variables.yml 文件中

nova_qemu_vnc_tls: 0