安全概述¶
虽然 Bare Metal 服务旨在成为一个安全的应用程序,但重要的是要了解它今天涵盖的内容以及不涵盖的内容。
部署者必须正确评估其用例并采取适当的措施来保护其环境。本文档旨在概述 Bare Metal 服务操作员应注意的风险。它不打算作为保护数据中心或 OpenStack 部署的指南。
镜像校验和¶
Ironic 长期以来一直提供供应和检查正在部署的磁盘镜像校验和的能力。然而,Ironic 尚未明确的是“为什么?”,即“是为了安全?”还是“是为了数据完整性?”。
答案是两者兼而有之,既要确保远程镜像文件的更高安全级别,并且在传输的镜像发生损坏时提供更快的反馈。
通常,校验和由 ironic-python-agent 或负责整体部署操作的部署接口进行验证。也就是说,并非每个部署接口都依赖于具有校验和的磁盘镜像,而这些部署接口是 Ironic 用户利用的特定用例,超出了 direct 部署接口提供的“常规”用例能力范围。
注意
不建议使用节点 instance_info/image_checksum 字段,因为匹配的 Glance Image Service 字段的使用也已被弃用。尽管如此,Ironic 仍保留此功能以满足用户需求,同时也能够保留简化的操作员交互。Glance 支持的新字段也由 Ironic 作为 instance_info/image_os_hash_value 校验和值和 instance_info/image_os_hash_algo 字段用于校验和算法而特别支持。
警告
将校验和值设置为 URL 是受支持的,但是这样做是在安全方面做“权衡”,因为远程校验和可能会更改。可以使用 conductor.disable_support_for_checksum_files 设置禁用 Conductor 对此功能的支持。
REST API:用户角色和策略设置¶
默认情况下,用户通过 Web API 的操作安全模型以及与 keystone 的交互,对 Ironic 进行身份验证和授权详细信息提供。
从 Wallaby 开发周期开始,默认 REST API 用户角色和策略设置已经演变,成为 OpenStack 社区经常提到的模型,即 Secure RBAC。该模型旨在平衡可用性,同时倾向于默认安全的态势。您可以在 Secure RBAC 中找到更多信息。
操作员可以选择通过利用覆盖策略来覆盖默认的、代码中的基于角色的访问控制策略,您可以在 Policies 中了解有关此信息。
Conductor 操作¶
Ironic 依赖 REST API 来验证、身份验证和授权用户请求和交互。虽然 Conductor 服务可以在单个进程中与 REST API 一起运行,但其正常运行模式是作为通过消息总线连接或使用经过身份验证的 JSON-RPC 端点连接的独立服务。
多租户¶
在评估 Bare Metal 服务的部署时,需要考虑多租户的两个方面:网络上的租户之间的交互,以及一个租户可以对机器采取的会影响下一个租户的操作。
网络交互¶
同时在单独的服务器上运行的租户的工作负载之间的交互包括但不限于:IP 欺骗、数据包嗅探和网络中间人攻击。
默认情况下,Bare Metal 服务将所有节点置备到“扁平”网络上,并且不采取任何预防措施来避免或防止租户之间的交互。可以通过与 OpenStack Identity、Compute 和 Networking 服务集成来解决此问题,从而提供租户网络隔离。有关 网络多租户 的更多文档可用。
残留效应¶
按顺序放置在同一服务器上的租户之间的交互包括但不限于:BIOS 设置的更改、固件的修改或留在磁盘或外围存储设备上的文件(如果这些设备未在每次使用后擦除)。
默认情况下,Bare Metal 服务将在删除实例后,在“清理”阶段擦除(清除)本地磁盘驱动器。它不会重置 BIOS 或刷新固件或外围设备。可以通过自定义在“清理”阶段使用的实用程序 ramdisk 来解决此问题。请参阅 固件安全 部分中的详细信息。
固件安全¶
当 Bare Metal 服务将操作系统镜像部署到服务器时,该镜像会在服务器上原生运行,而无需虚拟化。具有已部署实例的管理员访问权限的任何用户都具有对底层硬件的管理员访问权限。
大多数服务器的默认设置不允许具有特权本地用户直接访问硬件设备。这样的用户可以在删除其实例并允许将服务器分配给另一个用户之前,修改设备或固件设置,并可能将新固件刷新到设备上。
如果启用了 [conductor]/automated_clean 配置选项(并且 [deploy]/erase_devices_priority 配置选项不为零),Bare Metal 服务将在实例删除期间安全擦除机器内的所有本地磁盘设备。但是,该服务不附带任何验证或修改系统或设备固件或固件设置的代码。
鼓励操作员为 ironic-python-agent ramdisk 编写自己的硬件管理器插件。这应包括自定义 clean steps,这些步骤将在 节点清理 过程中作为节点停用的一部分运行。 clean steps 将执行在该环境中确保每个服务器固件完整性所需的特定操作。
理想情况下,操作员应与他们的硬件供应商合作,以确保在提前实施适当的固件安全措施。这可能包括
安装 BIOS 和外围设备的签名固件
使用 TPM(可信平台模块)在启动时验证签名
以 UEFI 安全启动模式 而不是 BIOS 模式启动机器,以验证内核签名
禁用来自主机操作系统的本地(带内)访问管理控制器(BMC)
禁用来自主机操作系统对启动设置的修改
其他参考资料
UEFI 安全启动模式¶
安全启动是一个有趣的话题,因为它存在于硬件、安全、供应商以及您愿意为流程、控制或进一步机制付出以启用流程和能力的位置的交叉点。
从高层来看,安全启动是指 UEFI 固件读取诸如操作系统内核或 Preboot eXecution Environment (PXE) 二进制文件之类的工件,如果该工件使用受信任的密钥签名,则执行它。一旦加载并执行了一段代码,它可能会读取更多的字节码并验证使用不同的密钥签名的其他签名工件。
这基本上就是大多数 Linux 操作系统今天启动的方式。 shim 加载程序由一家权威机构(微软)签名,通常受硬件供应商的信任。shim 加载程序然后加载一个引导加载程序,例如 Grub,然后加载一个操作系统。
潜在挑战¶
安全启动的一个主要挑战是 Preboot eXecution Environment 二进制文件的状态。操作系统分发供应商倾向于不请求拥有通用签名密钥的权威机构来签名这些二进制工件。因此,几乎不可能通过网络启动已启用安全启动的机器。
开源社区有报告称微软愿意签名 iPXE 二进制文件,但是要求有点苛刻,并且在很大程度上意味着供应商需要承担签名 iPXE 二进制文件成为普遍存在的负担。 iPXE 开发人员在其网站上提供了进一步的 详细信息,但它提供了巩固了我们不太可能看到签名 iPXE 加载程序的原因的细节。
也就是说,除非您自己签名 iPXE。
您可以这样做,但您需要建立自己的密钥管理基础设施,并教导硬件信任您的签名,这本身并不是一件容易的事。
注意
Linux 上本地机器的密钥管理工具是 mokutil,但是它被建模为手动调用。也许可以通过基板管理控制器管理密钥,并且 Ironic 可能会在某个时候添加这些功能。
有可能使用 shim 和 Grub2 来启动裸机节点,但是 Grub2 在引导机器方面的能力与 iPXE 相比非常有限。值得注意的是,Ironic 的许多示例配置都使用 iPXE,包括整个活动,例如使用 ironic-inspector 进行非托管硬件内省。
为了更深入的了解,非托管内省是指您要求 ironic-inspector 检查机器而不是要求 ironic。换句话说,使用 openstack baremetal introspection start <node> 而不是 baremetal node inspect <node> 命令。这需要将 inspector.require_managed_boot 设置为 true。
驱动程序对安全启动部署的支持¶
某些硬件类型支持在部署实例时动态启用 UEFI 安全启动。目前这些是 iLO 驱动程序、iRMC 驱动程序 和 Redfish 驱动程序。
其他驱动程序,例如 IPMI 驱动程序,可以在主机上手动配置,但是由于 IPMI 协议中缺乏安全启动支持的标准化,您可能会遇到意外行为。
通过在 properties 字段的 capabilities 参数中添加 secure_boot 功能来声明对 UEFI 安全启动的支持。 secure_boot 是一个布尔参数,取值为 true 或 false。
要在节点上启用 secure_boot,请将其添加到 capabilities
baremetal node set <node> --property capabilities='secure_boot:true'
或者,使用 硬件内省 自动填充安全启动功能。
警告
UEFI 安全启动仅适用于 UEFI 启动模式,请参阅 启动模式支持,了解如何启用和禁用它。
兼容镜像¶
大多数主流和供应商支持的基于 Linux 的公共云镜像已经与使用安全启动兼容。
使用 Shim 和 Grub2 进行安全启动¶
要使用 Shim 和 Grub 启动裸机节点,需要 Ironic 部署的管理员和 Ironic API 的用户采取操作。
对于 Ironic 管理员¶
要启用 grub 以网络启动裸机节点以进行活动,例如托管内省、节点清理和部署,需要在 ironic.conf 中进行一些配置。
[DEFAULT]
enabled_boot_interfaces = pxe
[pxe]
uefi_pxe_config_template = $pybasedir/drivers/modules/pxe_grub_config.template
tftp_root = /tftpboot
loader_file_paths = bootx64.efi:/usr/lib/shimx64.efi.signed,grubx64.efi:/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed
注意
您可能希望利用 pxe.loader_file_paths 功能,该功能会自动将引导加载程序复制到 tftp_root 文件夹中,但是如果手动将命名的文件复制到 Preboot eXecution Environment 文件夹中,则不需要此功能,默认情况下是 [pxe]tftp_root 和 [deploy]http_root 文件夹。
警告
Shim/Grub 工件路径因发行版而异。上面的示例取自 Ironic 的持续集成测试作业,在该作业中执行此功能。
对于 Ironic 用户¶
要将节点设置为使用 pxe boot_interface,请执行 baremetal 命令
baremetal node set --boot-interface pxe <node>
或者,如果您的硬件支持 HttpBoot 并且您的 Ironic 至少是 2023.2,您可以改为设置 http boot_interface
baremetal node set --boot-interface http <node>
与 OpenStack Compute 启用¶
具有将 secure_boot 设置为 true 的节点可以通过将 extra_spec 添加到 nova flavor 来请求。
openstack flavor set <flavor> --property capabilities:secure_boot="true"
openstack server create --flavor <flavor> --image <image> instance-1
如果 capabilities 在 extra_spec 中使用,则 nova 调度程序 (ComputeCapabilitiesFilter) 将仅匹配在 properties/capabilities 中具有适当设置的 secure_boot 的 ironic 节点。它将过滤掉其余的节点。
在 nova 中用于匹配的上述设施可以在异构环境中用于混合支持和不支持 UEFI 安全启动的机器,并且操作员希望为用户提供关于安全启动的选择。如果 flavor 不包含 secure_boot,那么 nova 调度器将不会将安全启动模式视为放置标准,因此用户可能会获得与用户指定 flavor 匹配的具有安全启动能力的机器,但部署将不会使用其安全启动能力。只有通过 flavor 显式指定,才会发生安全启动部署。
启用独立模式¶
要在独立模式(没有 OpenStack Compute)下为实例请求安全启动,您必须显式告知 Ironic
baremetal node set secure boot on <node>
也可以通过执行命令的否定形式来禁用
baremetal node set secure boot off <node>
其他注意事项¶
内部网络¶
应禁止从外部访问 Bare Metal 服务使用的内部网络。这些网络用于管理(与节点的 BMC 控制器)、配置、清理(如果使用)和救援(如果使用)。
可以通过物理或逻辑网络隔离、流量过滤等方式来实现。
虽然 Ironic 项目已经努力使 API 能够被最终用户直接使用,但我们仍然鼓励操作员尽可能谨慎,以确保到位适当的安全控制,以限制对服务的访问。
管理接口技术¶
一些节点支持多种管理接口技术(例如,供应商和 IPMI)。如果您只使用一种现代技术进行带外节点访问,建议禁用 IPMI,因为 IPMI 协议不安全。如果启用了 IPMI,在大多数情况下,本地操作系统管理员能够在不指定任何凭据的情况下通过 IPMI 设置进行带内操作,因为这是 DCMI 规范的要求。
租户网络隔离¶
如果您使用租户网络隔离,处理节点启动文件的服务(TFTP 或 HTTP)应仅从用于正在部署和清理的节点的内部网络提供请求。
TFTP 协议根本不支持每个用户的访问控制。
对于 HTTP,没有通用的安全方法可以将凭据传输到节点。
此外,租户网络隔离默认情况下不适用于网络启动节点,一旦节点已被配置。
用于 RAM 磁盘使用的 API 端点¶
Bare Metal API 中有 三个(未授权的)端点,这些端点旨在由 ironic-python-agent RAM 磁盘使用。它们不打算公开使用。
即使这些端点周围的逻辑旨在具有防御性,这些端点也可能导致安全问题。应禁止从外部或不受信任的网络访问这些端点。一种简单的方法是
设置两组 API 服务:一组用于外部请求,第二组用于部署 RAM 磁盘的请求。
为了禁用对(第一组)服务外部请求的 API 服务中这些端点的未经授权的访问,应将以下行添加到 policy.yaml 文件
# Send heartbeats from IPA ramdisk "baremetal:node:ipa_heartbeat": "!" # Access IPA ramdisk functions "baremetal:driver:ipa_lookup": "!" # Continue introspection IPA ramdisk endpoint "baremetal:driver:ipa_continue_inspection": "!"
速率限制¶
Ironic 具有“并发操作限制”的概念,该概念允许操作员限制并发的、长时间运行的、破坏性操作。
实施此功能的总体用例是帮助为可能应用于环境的失控进程和操作提供后备,例如节点的批量删除。这些设置的适当设置是 conductor.max_concurrent_deploy,默认值为 250,以及 conductor.max_concurrent_clean,默认值为 50。这些设置对于中到大型部署来说是合理的默认值,但根据负载和使用模式,可以安全地调整以符合操作员的舒适度。
内存限制¶
由于 Ironic API 的用户可以请求可能消耗大量内存的活动,例如,作为部署操作的一部分的磁盘镜像格式转换。Ironic conductor 服务具有最小可用内存检查,该检查在启动这些操作之前执行。它默认为 1024 兆字节,可以使用 DEFAULT.minimum_required_memory 设置进行调整。
具有更高并发水平的操作员可能希望增加默认值。
磁盘镜像¶
Ironic 依赖于 qemu-img 工具将镜像从提供的磁盘镜像格式转换为 raw 格式,以便将磁盘镜像的内容写入远程设备。
默认情况下,仅支持 qcow2 格式进行此操作,但是有报告称其他格式在使用 [conductor]permitted_image_formats 配置选项启用后也能工作。
Ironic 默认情况下执行几个步骤。
Ironic 检查并将提供的元数据与远程权威来源进行比较,例如,如果可用,则为 Glance Image Service。
Ironic 尝试基于可用的元数据和文件结构“指纹”文件类型。未被镜像格式检查代码识别的文件格式可能被评估为“raw”,这意味着该镜像将不会通过
qemu-img。如有疑问,请使用raw镜像,您可以验证其处于所需和预期状态。然后,镜像执行一组安全和健全性检查,这些检查查找基本格式中可能允许攻击者利用
qemu-img中不应使用的功能的未知或不安全的功能使用情况。默认情况下,此检查仅通过遍历 conductor 的镜像发生。Ironic 然后检查指纹值和元数据值是否匹配。如果它们不匹配,则请求的镜像将被拒绝,并且操作将失败。
然后将镜像提供给
ironic-python-agent。
作为 URL 提供的镜像(即由 API 用户提供的镜像),或通过可用的服务配置转换为临时 URL 的镜像,作为 URL 提供给 ironic-python-agent。
Ironic 可以配置为拦截此交互,并让 conductor 下载和检查这些项目,然后再由 ironic-python-agent 执行,但是这会增加 Conductor 的临时磁盘利用率以及促进传输的网络流量。默认情况下禁用此检查,但可以使用 [conductor]conductor_always_validates_images 配置选项启用。
一个选项强制所有文件都从 conductor 提供,从而强制在涉及 ironic-python-agent 之前进行镜像检查,是使用 [agent]image_download_source 配置参数设置为 local,它通过 conductor 代理所有磁盘镜像。此设置也可用在节点的 driver_info 和 instance_info 字段中。
磁盘镜像的缓解因素¶
在完全集成的 OpenStack 环境中,Ironic 要求将镜像设置为 Image Service 中的“public”。
具有足够提升访问权限的直接 API 用户可以提交 URL 到 baremetal 节点的 instance_info 字典字段,并设置 image_source 键值到 URL。要这样做,明确需要具有 System 范围成员的提升(受信任)访问权限,或者 Project 范围的 Owner-Member,或者通过 baremetal:node:update_instance_info 策略权限规则的 Project 范围的 Lessee-Admin。在 OpenStack 的 Wallaby 版本之前,这仅限于 admin 和 baremetal_admin 角色,并且在较新的“Secure RBAC”模型中仍然类似地受到限制。