Menu Close

安全和强化指南

Red Hat OpenStack Platform 16.2

良好的实践、合规性和安全强化

摘要

本指南提供有关强化 Red Hat OpenStack Platform 环境安全性的良好实践建议和概念信息。

前言

使开源包含更多

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。详情请查看 CTO Chris Wright 的信息

对红帽文档提供反馈

我们感谢您对文档提供反馈信息。与我们分享您的成功秘诀。

使用直接文档反馈(DDF)功能

使用 添加反馈 DDF 功能,用于特定句子、段落或代码块上的直接注释。

  1. Multi-page HTML 格式查看文档。
  2. 请确定您看到文档右上角的 反馈 按钮。
  3. 用鼠标指针高亮显示您想评论的文本部分。
  4. 添加反馈
  5. 使用您的评论 完成 Add feedback 字段。
  6. 可选:添加您的电子邮件地址,以便文档团队可以联系您的问题。
  7. Submit

第 1 章 安全简介

使用 Red Hat Openstack Platform(RHOSP)提供的工具,优先选择计划和操作中的安全性,以满足用户隐私性和数据安全性的期望。未能实施安全标准可能导致停机或数据泄露。您的用例可能会受到需要传递审计和合规性流程的法律。

注意

按照本指南中的说明强化您的环境安全性。但是,这些建议不能保证安全性或合规性。您必须根据环境的独特要求评估安全性。

有关强化 Ceph 的信息,请参阅 数据安全性和强化指南

1.1. Red Hat OpenStack Platform 安全性

默认情况下,Red Hat OpenStack Platform(RHOSP)director 使用以下工具和访问控制来创建 overcloud:

SElinux
SELinux 通过提供访问控制,要求每个进程对每个操作具有显式权限,从而为 RHOSP 提供安全性增强。
Podman
Podman 作为容器工具是 RHOSP 的安全选项,因为它不使用需要具有 root 访问权限功能的进程的客户端/服务器模型。
系统访问限制
您只能使用 director 在 overcloud 部署期间为 heat-admin 创建的 SSH 密钥或 overcloud 中创建的 SSH 密钥来登录 overcloud 节点。您不能使用 SSH 并通过密码登录 overcloud 节点,或者使用 root 登录 overcloud 节点。

您可以根据机构的需要和信任级别配置 director,使其带有以下额外安全功能:

  • 公共 TLS 和 TLS-everywhere
  • 硬件安全模块与 OpenStack Key Manager(barbican)集成。
  • 签名的镜像和加密卷
  • 使用工作流执行的密码和 fernet 密钥轮转

1.2. 识别 Red Hat OpenStack Platform 中的安全区

安全区是指共享常见安全问题的资源、应用程序、网络和服务器。设计安全区域,以便具有常见的身份验证和授权要求和用户。您可以根据云的架构、在您的环境中可接受的信任级别以及您机构的标准化要求,自行定义安全区,使其根据需要进行精细。区及其信任要求可能会因云实例是公共、私有还是混合而异。

例如,您可以将 Red Hat OpenStack Platform 的默认安装分成以下区:

表 1.1. 安全区

zone网络详情

公开

external

public 区域为实例外部连接托管外部网络、公共 API 和浮动 IP 地址。此区域允许从管理控制外的网络进行访问,并且是云基础架构的不受信任的区域。

guest

tenant

guest 区域托管项目网络。对于公共和私有云供应商,允许不受限制地访问实例的公共云和私有云供应商是不被信任。

存储访问

storage, storage_mgmt

存储访问区域用于存储管理、监控和集群,以及存储流量。

控制

ctlplane, internal_api, ipmi

control 区域还包括 undercloud、主机操作系统、服务器硬件、物理网络和 Red Hat OpenStack Platform director control plane。

1.3. 在 Red Hat OpenStack Platform 中查找安全区

运行以下命令收集有关 Red Hat OpenStack Platform 部署的物理配置的信息:

流程

  1. 登录到 undercloud,源 stackrc

    $ source /home/stack/stackrc
  2. 运行 openstack subnet list,将分配的 ip 网络与其关联的区匹配:

    openstack subnet list -c Name -c Subnet
    +---------------------+------------------+
    | Name                | Subnet           |
    +---------------------+------------------+
    | ctlplane-subnet     | 192.168.101.0/24 |
    | storage_mgmt_subnet | 172.16.105.0/24  |
    | tenant_subnet       | 172.16.102.0/24  |
    | external_subnet     | 10.94.81.0/24    |
    | internal_api_subnet | 172.16.103.0/24  |
    | storage_subnet      | 172.16.104.0/24  |
    +---------------------+------------------+
  3. 运行 openstack server list 以列出您基础架构中的物理服务器:

    openstack server list -c Name -c Networks
    +-------------------------+-------------------------+
    | Name                    | Networks                |
    +-------------------------+-------------------------+
    | overcloud-controller-0  | ctlplane=192.168.101.15 |
    | overcloud-controller-1  | ctlplane=192.168.101.19 |
    | overcloud-controller-2  | ctlplane=192.168.101.14 |
    | overcloud-novacompute-0 | ctlplane=192.168.101.18 |
    | overcloud-novacompute-2 | ctlplane=192.168.101.17 |
    | overcloud-novacompute-1 | ctlplane=192.168.101.11 |
    +-------------------------+-------------------------+
  4. 使用 openstack server list 命令中的 ctlplane 地址查询物理节点的配置:

    ssh heat-admin@192.168.101.15 ip addr

1.4. 连接安全区

您必须根据不同的信任级别或身份验证要求,仔细配置跨越多个安全区的组件。这些连接通常是网络架构中弱点。确保将这些连接配置为满足所连接任何区域的最大信任级别的安全要求。在很多情况下,连接的区的安全控制是由于攻击的可能性造成的主要关注点。区发现了一个额外的潜在攻击点,并给攻击者添加将其攻击迁移到更为敏感部分部署的机会。

在某些情况下,OpenStack 操作员可能希望考虑比它所驻留的任何区域更高的标准保护集成点。根据以上 API 端点示例,广告可能会针对来自公共区的公共 API 端点为目标,如果这些区域未完全隔离,则可利用此页来损害或获取对管理区域中内部或管理 API 的访问权限。

OpenStack 的设计非常困难。由于核心服务通常至少跨越两个区域,因此在将安全控制应用到它们时,必须考虑特殊考虑。

1.5. 威胁缓解措施

大多数类型的云部署、公共、私有或混合都暴露于某种形式的安全威胁。以下实践有助于缓解安全威胁:

  • 应用最小特权的原则。
  • 在内部和外部接口上使用加密。
  • 使用集中身份管理。
  • 使 Red Hat OpenStack Platform 不断更新。

计算服务可以为 DDoS 和 brute 强制攻击提供恶意工具。预防措施包括出口安全组、流量检查、入侵检测系统和客户教育和认知。对于公共网络访问或可访问公共网络(如互联网)的部署,请确保进程和基础架构已原位来检测和处理出站滥用。

第 2 章 记录 RHOSP 环境

在识别安全问题、攻击向量以及可能的安全区桥接点时,记录系统组件、网络、服务和软件非常重要。Red Hat OpenStack Platform(RHOSP)部署的文档应该包括以下信息:

  • RHOSP 生产、开发和测试环境中系统组件、网络、服务和软件的描述。
  • 任何临时资源(如虚拟机或虚拟磁盘卷)的清单。

2.1. 记录系统角色

Red Hat OpenStack Platform(RHOSP)部署中的每个节点都提供特定角色,可以是为云的基础架构提供,或提供云资源。

对基础架构进行贡献的节点运行云相关的服务,如消息排队服务、存储管理、监控、联网以及支持云操作和调配所需的其他服务。基础架构角色示例包括:

  • Controller
  • Networker
  • 数据库
  • Telemetry

提供云资源的节点为云中运行的实例提供计算或存储容量。资源角色示例包括:

  • CephStorage
  • Compute
  • ComputeOvsDpdk
  • ObjectStorage

记录您环境中使用的系统角色。这些角色可以在用于部署 RHOSP 的模板内标识。例如,环境中为每个角色都有一个 NIC 配置文件。

流程

  1. 检查部署的现有模板,以查找指定当前正在使用的角色的文件。环境中每个角色都有一个 NIC 配置文件。在以下示例中,RHOSP 环境包含 ComputeHCI 角色、Compute 角色和 Controller 角色:

    $ cd ~/templates
    $ tree
    .
    ├── environments
    │   └── network-environment.yaml
    ├── hci.yaml
    ├── network
    │   └── config
    │       └── multiple-nics
    │           ├── computehci.yaml
    │           ├── compute.yaml
    │           └── controller.yaml
    ├── network_data.yaml
    ├── plan-environment.yaml
    └── roles_data_hci.yaml
  2. RHOSP 环境的每个角色都执行许多交互相关的服务。您可以通过检查角色文件来记录各个角色使用的服务。

    1. 如果为模板生成了 角色 文件,您可以在 ~/templates 目录中找到它:

      $ cd ~/templates
      $ find . -name *role*
      > ./templates/roles_data_hci.yaml
    2. 如果没有为您的临时请求生成 角色 文件,您可以生成一个角色用于检查文档目的:

      $ openstack overcloud roles generate \
      > --roles-path /usr/share/openstack-tripleo-heat-templates/roles \
      > -o roles_data.yaml Controller Compute

2.2. 创建硬件清单

您可以通过查看内省期间收集的数据来获取 Red Hat OpenStack Platform 部署的硬件信息。内省从节点收集有关 CPU、内存和磁盘等的硬件信息。

流程

  1. 从 undercloud 中,提供 stackrc 文件:

    $ source ~/stackrc
  2. 列出环境中的节点:

    $ openstack baremetal node list -c Name
    +--------------+
    | Name         |
    +--------------+
    | controller-0 |
    | controller-1 |
    | controller-2 |
    | compute-0    |
    | compute-1    |
    | compute-2    |
    +--------------+
  3. 对于收集信息的每个裸机节点,并运行以下命令来检索内省数据:

    $ openstack baremetal introspection data save <node> | jq

    <node > 替换为在第 1 步中检索的列表中的节点名称。

  4. 可选: 要将输出限制为特定类型的硬件,您可以检索清单密钥列表并查看特定密钥的内省数据:

    1. 运行以下命令从内省数据中获取顶级密钥列表:

      $ openstack baremetal introspection data save controller-0 | jq '.inventory | keys'
      
      [
        "bmc_address",
        "bmc_v6address",
        "boot",
        "cpu",
        "disks",
        "hostname",
        "interfaces",
        "memory",
        "system_vendor"
      ]
    2. 选择一个密钥,如磁盘,并运行以下命令以获取更多信息:

      $ openstack baremetal introspection data save controller-1 | jq '.inventory.disks'
      [
        {
          "name": "/dev/sda",
          "model": "QEMU HARDDISK",
          "size": 85899345920,
          "rotational": true,
          "wwn": null,
          "serial": "QM00001",
          "vendor": "ATA",
          "wwn_with_extension": null,
          "wwn_vendor_extension": null,
          "hctl": "0:0:0:0",
          "by_path": "/dev/disk/by-path/pci-0000:00:01.1-ata-1"
        }
      ]

2.3. 创建软件清单

记录在 Red Hat OpenStack Platform(RHOSP)基础架构中部署的节点中使用的软件组件。系统数据库、RHOSP 软件服务和支持组件(如负载均衡器、DNS 或 DHCP 服务)在评估库、应用程序或软件类影响时至关重要。

流程

  1. 确定您知道可受恶意活动影响的系统和服务的入口点。在 undercloud 上运行以下命令:

    $ cat /etc/hosts
    $ source stackrc ; openstack endpoint list
    $ source overcloudrc ; openstack endpoint list
  2. RHOSP 部署在容器化服务中,因此您可以通过检查该节点上运行的容器来查看 overcloud 节点上的软件组件。使用 ssh 连接到 overcloud 节点并列出正在运行的容器。例如,要查看 compute-0 上的 overcloud 服务,请运行类似如下的命令:

    $ ssh heat-admin@compute-0 podman ps

第 3 章 加密和密钥管理

设备内通信是一个严重的安全顾虑。如 Heartbleed 等大量漏洞(如 Heartbleed )或更高级攻击(如 BEAST 和 CRIME)相比,网络间的通信安全方法也变得更加重要。但是,加密只是一个更大的安全策略的一部分。端点危害意味着攻击者不再需要破坏所使用的加密,但可以在系统处理时查看和操作信息。

本章将回顾有关配置传输层安全(TLS)以保护内部和外部资源的功能,并会调用需要特别关注的特定系统类别。

OpenStack 组件使用各种协议相互通信,其通信可能涉及敏感或机密数据。攻击者可能会尝试转站在频道上,以便可以访问敏感信息。因此,所有组件都必须使用安全通讯协议相互通信。

3.1. TLS 和 SSL 简介

在某些情况下,需要确保 OpenStack 部署中网络流量的机密性或完整性。您通常会使用加密措施来配置此功能,如 TLS 协议。在典型的部署中,通过公共网络传输的所有流量都应经过安全加固,但安全性的良好做法要求还必须对内部流量进行保护。为了保护,它不依赖于安全区分离。如果攻击者获得对虚拟机监控程序或主机资源的访问、破坏 API 端点或任何其他服务,则他们必须能够轻松地注入或捕获消息、命令或影响云的管理功能。

您应该使用 TLS 强化所有区域,包括管理区服务和内部服务通信。TLS 提供了相应的机制,用于确保身份验证、非推荐、用户通信的保密性和 OpenStack 服务以及 OpenStack 服务本身之间的完整性。

由于安全套接字层(SSL)协议中公布的漏洞,请考虑使用 TLS 1.2 或更高版本(首选使用 SSL),并且所有情况下 SSL 都是禁用的,除非需要与过时的浏览器或库兼容。

3.2. 公钥基础架构

公钥基础架构(PKI)是一种框架,用于提供加密算法、密码模式和用于保护数据和身份验证的协议。它由一组系统和流程组成,确保在验证各方身份时可以发送流量。此处描述的 PKI 配置集是 PKIX 工作组开发的互联网工程任务组(IETF)公共密钥基础架构(PKIX)配置集。PKI 的核心组件是:

  • 数字证书 - 签名的公钥证书是具有可验证实体的数据、其公钥以及其他属性的数据结构。这些证书由证书颁发机构(CA)发布。因为证书由 CA 签名,在验证后,与实体关联的公钥可以保证与这个实体关联。用于定义这些证书的最常见标准是 X.509 标准。RFC5280 中详细介绍了 X.509 v3,它是由 RFC6818 更新的详细信息。证书由 CA 发布为证明在线实体身份的机制。CA 通过从证书创建消息摘要并使用其私钥加密摘要,为证书进行数字签名。
  • 终端实体 - 受证书主体的用户、进程或系统。最终实体将其证书请求发送到注册授权中心(RA)进行批准。如果批准,RA 会将请求转发到认证认证机构(CA)。认证认证机构验证请求以及信息是否正确,生成并签名证书。然后,此签名证书会发送到证书存储库。
  • 依赖方 - 接收数字签名的证书的端点,这些证书可以通过引用证书中列出的公钥。依赖方应位于验证链链的位置,确保其在 CRL 中不存在,还必须能够验证证书上的到期日期。
  • 证书颁发机构(CA)- CA 是一个可信实体,由由方方和依赖于认证策略、管理处理和证书的第三方均依赖。
  • 注册机构(RA)- CA 委托某些管理功能的可选系统,其中包括在由 CA 签发签发前的最终实体验证功能。
  • 证书撤销列表(CRL)- 证书撤销列表(CRL)是已撤销的证书序列号列表。呈现这些证书的最终实体不应在 PKI 模型中被信任。可能会因为以下多种原因而发生撤销,例如:密钥威胁,CA 遭到破坏。
  • CRL 签发者 - CA 将发布证书撤销列表的可选系统。
  • 证书存储库 - 存储终止实体证书和证书撤销列表的位置,有时也称为证书捆绑包。

3.3. 认证授权机构

很多机构有自己的认证认证机构(CA)、证书策略和管理建立了公共密钥基础架构,这些基础架构应使用它来为内部 OpenStack 用户或服务发布证书。面向公共安全区的组织还需要由广泛认可的公共 CA 签名的证书。对于管理网络上的加密通信,建议不要使用公共 CA。相反,建议大多数部署都会部署自己的内部 CA。

注意

有效使用 TLS 依赖于在 DNS 中给定域或子域(可由通配符)或一系列特定证书问题(通过公共或内部 CA 使用)的部署。为确保 TLS 证书可以有效地验证,需要通过这些 DNS 记录访问平台服务。

建议 OpenStack 云架构师将单独的 PKI 部署用于内部系统和面向客户的服务。这使得云部署器能够控制其 PKI 基础架构,并使内部系统请求、签名和部署证书变得更加容易。高级配置可能会将单独的 PKI 部署用于不同的安全区。这使得 OpenStack 操作员能够维护环境的加密分离,确保签发的证书不能被另一个识别。

用于在互联网上支持 TLS 的证书(或客户期望安装任何与标准操作系统提供的证书捆绑包以外)上的 TLS 的证书应使用操作系统证书捆绑包中安装的证书授权机构进行置备。

注意

存在与创建和签名证书相关的管理、策略和技术挑战。云架构师或操作员可能希望获得行业领导和供应商的建议,除了这里所推荐的指南之外。

3.4. 使用 director 配置加密

默认情况下,overcloud 在其服务中使用未加密的端点。这意味着 overcloud 配置需要额外的环境文件来为其公共 API 端点启用 SSL/TLS。有关如何配置 SSL/TLS 证书的更多信息,并将其包含在 overcloud 创建过程中,请参阅在 overcloud 公共端点 上启用 SSL/TLS

3.5. 更改默认证书密钥大小

您可以使用 Red Hat OpenStack Platform director 使用大于默认 2048 字节的私钥创建证书。您必须使用以下 heat 参数,以便 director 接受这些证书:

parameter_defaults:
    CertificateKeySize: '4096'

CertificateKeySize 参数是一个适用于所有服务的全局参数。您可以使用服务特定密钥大小参数覆盖 CertificateKeySize 参数:

parameter_defaults:
    CertificateKeySize: '4096'
    RedisCertificateKeySize: '2048'

3.6. TLS 库

OpenStack 生态系统中的某些组件、服务和应用程序可以配置为使用 TLS 库。OpenStack 中的 TLS 和 HTTP 服务通常使用 OpenSSL 实施,它具有一个经 FIPS 140-2 验证的模块。但是,考虑每个应用程序或服务都可以在如何使用 OpenSSL 库时引入弱点。

3.7. TLS 1.0 弃用

重要

您必须至少对 NIST-approval 使用 TLS 1.2。如需更多信息,请参阅 https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf

对于 Red Hat OpenStack Platform 13 及更新版本的部署,HAProxy 不接受 TLS 1.0 连接,该连接处理 TLS 启用 API 的 TLS 连接。这通过 no-tlsv10 选项实现。对于启用 InternalTLS 的 HA 部署,控制器平面上的跨节点流量也会加密。这包括 RabbitMQ、MariaDB 和 Redis 等。MariaDB 和 Redis 已被弃用了 TLS1.0,RabbitMQ 期望从上游向后移植。

3.7.1. 检查 TLS 1.0 是否使用

您可以使用 ciphercan 来确定您的部署是否显示 TLS 1.0。Cipherscan 可以从 https://github.com/mozilla/cipherscan 克隆。此示例输出显示从 horizon 接收的结果:

注意

从非生产环境系统运行 密码,因为它可能会在首次运行时安装其他依赖项。

$ ./cipherscan https://openstack.lab.local
..............................
Target: openstack.lab.local:443

prio  ciphersuite                  protocols  pfs                 curves
1     ECDHE-RSA-AES128-GCM-SHA256  TLSv1.2    ECDH,P-256,256bits  prime256v1
2     ECDHE-RSA-AES256-GCM-SHA384  TLSv1.2    ECDH,P-256,256bits  prime256v1
3     DHE-RSA-AES128-GCM-SHA256    TLSv1.2    DH,1024bits         None
4     DHE-RSA-AES256-GCM-SHA384    TLSv1.2    DH,1024bits         None
5     ECDHE-RSA-AES128-SHA256      TLSv1.2    ECDH,P-256,256bits  prime256v1
6     ECDHE-RSA-AES256-SHA384      TLSv1.2    ECDH,P-256,256bits  prime256v1
7     ECDHE-RSA-AES128-SHA         TLSv1.2    ECDH,P-256,256bits  prime256v1
8     ECDHE-RSA-AES256-SHA         TLSv1.2    ECDH,P-256,256bits  prime256v1
9     DHE-RSA-AES128-SHA256        TLSv1.2    DH,1024bits         None
10    DHE-RSA-AES128-SHA           TLSv1.2    DH,1024bits         None
11    DHE-RSA-AES256-SHA256        TLSv1.2    DH,1024bits         None
12    DHE-RSA-AES256-SHA           TLSv1.2    DH,1024bits         None
13    ECDHE-RSA-DES-CBC3-SHA       TLSv1.2    ECDH,P-256,256bits  prime256v1
14    EDH-RSA-DES-CBC3-SHA         TLSv1.2    DH,1024bits         None
15    AES128-GCM-SHA256            TLSv1.2    None                None
16    AES256-GCM-SHA384            TLSv1.2    None                None
17    AES128-SHA256                TLSv1.2    None                None
18    AES256-SHA256                TLSv1.2    None                None
19    AES128-SHA                   TLSv1.2    None                None
20    AES256-SHA                   TLSv1.2    None                None
21    DES-CBC3-SHA                 TLSv1.2    None                None

Certificate: trusted, 2048 bits, sha256WithRSAEncryption signature
TLS ticket lifetime hint: None
NPN protocols: None
OCSP stapling: not supported
Cipher ordering: server
Curves ordering: server - fallback: no
Server supports secure renegotiation
Server supported compression methods: NONE
TLS Tolerance: yes

Intolerance to:
 SSL 3.254           : absent
 TLS 1.0             : PRESENT
 TLS 1.1             : PRESENT
 TLS 1.2             : absent
 TLS 1.3             : absent
 TLS 1.4             : absent

在扫描服务器时,Cipherscan 会公告对特定 TLS 版本的支持,这是用于协商的最高 TLS 版本。如果目标服务器正确遵循 TLS 协议,它将以相互支持的最高版本响应,这可能低于最初公告的 Cipherscan。如果服务器将继续使用该特定版本与客户端建立连接,则不会考虑该协议版本。如果没有建立连接(带有指定版本或任何较低版本),则考虑使用那个版本的协议进入容限。例如:

Intolerance to:
 SSL 3.254           : absent
 TLS 1.0             : PRESENT
 TLS 1.1             : PRESENT
 TLS 1.2             : absent
 TLS 1.3             : absent
 TLS 1.4             : absent

在这个输出中,TLS 1.0TLS 1.1 的容限被报告为 PRESENT,这意味着无法建立连接,并且 Cipherscan 无法连接这些 TLS 版本。因此,最好在扫描服务器上启用这些(以及任何较低的)协议版本。

3.8. 加密算法、密码模式和协议

您应该只考虑使用 TLS 1.2。其他版本(如 TLS 1.0 和 1.1)容易受到多个攻击的影响,并可以被很多政府机构和监管的行业表示禁止。在您的环境中应禁用 TLS 1.0。TLS 1.1 可能用于广泛的客户端兼容性,但在启用此协议时要谨慎。只有存在强制兼容性要求并且您了解以下相关的风险时,才启用 TLS 版本 1.1。由于多个公共漏洞,不得使用 SSL 的所有版本(与 TLS 的前身)。

当您使用 TLS 1.2 并同时控制客户端和服务器时,密码套件应限制为 ECDHE-ECDSA-AES256-GCM-SHA384。在您不控制端点的情况下,使用 TLS 1.1 或 1.2 更一般的 HIGH:!aNULL:!eNULL:!DES:!3DES:!SSLv3:!TLSv1:!CAMELLIA 是一个合理的密码选择。

注意

本指南不用作加密(加密)的参考,并不指定您在 OpenStack 服务中启用或禁用哪些特定算法或密码模式。

3.9. TLS 代理和 HTTP 服务

OpenStack 端点是为公共网络上的最终用户以及管理网络上的其他 OpenStack 服务提供 API 的 HTTP 服务。目前,您可以使用 TLS 加密外部请求。要在 Red Hat OpenStack Platform 中配置此功能,您可以在 HAproxy 后面部署 API 服务,从而建立和终止 TLS 会话。

如果软件终止提供的性能不足,则可能会对硬件加速器作为替代选项进行探索。此方法需要在平台上进行额外的配置,而不是所有硬件负载均衡器可以与 Red Hat OpenStack Platform 兼容。务必要注意将由任何所选 TLS 代理处理的请求的大小。

3.10. 完美转发公司

配置 TLS 服务器以进行完全转发保密,需要仔细规划关键大小、会话 ID 和会话票据。此外,对于多服务器部署,共享状态也是一个重要的考虑因素。现实部署可能会考虑启用此功能以提高性能。这可以以安全加固的方式完成,但需要对关键管理进行特殊考虑。这种配置超出了本指南的范围。

3.11. 使用 Barbican 管理 secret

OpenStack Key Manager(barbican)是 Red Hat OpenStack Platform 的 secret manager。您可以使用 barbican API 和命令行来集中管理 OpenStack 服务使用的证书、密钥和密码。Barbican 目前支持以下用例:

  • 对称加密密钥 - 用于块存储(cinder)卷加密和 Object Storage(swift)对象加密。
  • 非对称密钥和证书 - glance 镜像签名和验证,Octavia TLS 负载均衡。

OpenStack Key 服务(barbican)与 cinder、swift、Octavia 和 Compute(nova)组件集成。例如,您可以将 barbican 用于以下用例:

  • 支持加密卷 - 您可以使用 barbican 管理 Cinder 加密密钥。此配置使用 LUKS 加密连接到您的实例的磁盘,包括引导磁盘。其关键管理方面对用户透明执行。
  • Glance 镜像签名 - 您可以配置镜像服务(glance),以验证上传的镜像没有被篡改。该镜像首先使用存储在 barbican 中的密钥进行签名,并在每次使用前进行验证。

如需更多信息,请参阅 Barbican 指南: https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/16.2/html-single/manage_secrets_with_openstack_key_manager/

第 4 章 身份和访问管理

Identity 服务(keystone)为云用户提供身份验证和授权,是安全考虑中的一个重要组件。

身份服务可以直接提供最终用户身份验证,或者可以配置为使用外部身份验证方法符合组织的安全策略和要求。

4.1. 身份验证

身份验证是任何现实世界 OpenStack 部署不可或缺的一部分。请小心考虑系统设计。本主题的完整处理超出了本指南的范围,但以下部分介绍了一些重要主题。

在最基本的环境中,身份验证是确认身份的过程 - 用户实际上是他们声明的身份。熟悉的示例是在登录系统时提供用户名和密码。

OpenStack Identity 服务(keystone)支持多种身份验证方法,包括用户名、密码、LDAP 和其他外部身份验证方法。身份验证成功后,身份服务为用户提供了用于后续服务请求的身份验证令牌。

传输层安全性(TLS)使用 X.509 证书在服务和人员之间提供身份验证。虽然 TLS 的默认模式只是服务器端身份验证,但您应该考虑使用证书进行客户端身份验证,因为它是在美国政府标准中规定的。

4.2. 无效的登录尝试

Identity Service(keystone)可以在重复登录尝试后限制对帐户的访问。重复失败登录尝试的模式通常代表进行强制攻击。这种类型的攻击在公共云部署中更为宝贵。您还可以使用在配置了失败登录尝试次数后阻断帐户的外部身份验证系统来缓解这个问题。然后,该帐户只能通过进一步的管理干预解锁。

检测技术也可用于缓解损坏。检测涉及频繁查看访问控制日志,以识别未经授权尝试访问帐户。可能的补救包括查看用户密码的强度,或者阻止通过防火墙规则进行攻击的网络源。您可以在 keystone 服务器上添加限制连接数的防火墙规则;这有助于降低攻击的有效性。

此外,检查帐户活动中不寻常的登录次数和可疑动作很有用,并采取纠正措施,比如禁用帐户。

4.3. 授权

身份服务支持组和角色的概念。在组拥有角色列表时,用户属于组。OpenStack 服务引用试图访问该服务的用户的角色。OpenStack 策略 enforcer 中间件考虑与每个资源关联的策略规则,然后用户的组/角色及关联来确定是否允许访问所请求的资源。

4.4. 建立 Formal Access Control Policies

在配置角色、组和用户之前,您应该记录您的 OpenStack 安装所需的访问控制策略。该政策应与该组织的任何法规或法律要求保持一致。对访问控制配置的将来的修改应该一致地根据正式策略进行。这些策略应包括用于创建、删除、禁用和启用帐户以及为帐户分配特权的条件和进程。定期检查策略,并确保配置符合批准的策略。

4.5. 服务授权

云管理员必须为每个服务定义具有 admin 角色的用户。此服务帐户为该服务提供验证用户的授权。

Compute 和 Object Storage 服务可以配置为使用身份服务来存储身份验证信息。身份服务支持 TLS 的客户端身份验证,这些身份验证可能会启用。TLS 客户端身份验证除了用户名和密码之外,还提供了额外的身份验证因素,从而让用户身份提供更高的可靠性。它降低了当用户名和密码被破坏时未经授权访问的风险。但是,每次部署中可能会存在额外的管理开销和成本来为用户发布证书。

云管理员应该防止敏感配置文件不受未授权的修改。这可以使用 SELinux 等强制访问控制框架进行配置,包括 /var/lib/config-data/puppet-generated/keystone/etc/keystone/keystone.conf 文件和 X.509 证书。

使用 TLS 进行客户端身份验证需要向服务发布证书。这些证书可以由外部或内部证书颁发机构签名。默认情况下,OpenStack 服务检查针对可信 CA 的证书签名的有效性,如果签名无效或者 CA 没有被信任,则连接将失败。云部署器可能会使用自签名证书 ; 在这种情况下,必须禁用有效期检查,或者证书应标记为可信状态。要禁用自签名证书的验证,请在 /etc/nova/api.paste.ini 文件的 [filter:authtoken] 部分中设置 insecure=False。此设置还禁用其他组件的证书。请注意,对容器化服务的确切文件路径可能会有所不同。

4.6. 令牌

一旦用户通过身份验证,将生成令牌以进行授权和对 OpenStack 环境的访问权限。令牌可以有一个变量生命周期范围,但到期的默认值是一小时。推荐的到期值应设置为较低值,使内部服务有足够的时间完成任务。如果令牌在任务完成前过期,云可能会变得无响应,或者停止提供服务。使用期间延长的时间示例是计算服务将磁盘映像传输到虚拟机监控程序以进行本地缓存所需的时间。

令牌通常在一个更大的身份服务响应上下文中传递。这些响应也提供各种 OpenStack 服务的目录。每个服务都列出其名称、内部访问端点、管理员和公共访问权限。身份服务支持令牌撤销。此清单作为撤销令牌的 API,用于列出撤销令牌以及缓存令牌以查询已撤销令牌的令牌,并将它们从其缓存中删除它们,并将其与缓存的撤销令牌列表相同。Fernet 令牌是 Red Hat OpenStack Platform 16.2 中唯一支持的令牌。

4.6.1. Fernet 令牌

Fernet 令牌现在是默认的令牌提供程序。Fernet 是明确设计为在 API 令牌中使用的安全消息格式。Fernet 令牌不是永久的(不需要保留到数据库)、轻量级(长度为 180 到 240 字节),并减少运行云所需的操作开销。身份验证和授权元数据捆绑到消息包的有效负载中,该载荷在 中作为 Fernet 令牌进行加密并签名(使用 180 到 240 字节)。

与 UUID、PKI 和 PKIZ 令牌不同,Nexa 和 PKIZ 令牌不需要持久性。keystone 令牌数据库不再受身份验证的副作用。在使用 Fernet 令牌时,不再需要从令牌数据库修剪已到期的令牌。由于 Fernet 令牌不是永久的,因此不必复制它们。只要每个 keystone 节点共享同一存储库,您就可以即时创建并验证 Fernet 令牌。

与 PKI 和 PKIZ 令牌相比,Hora 和 PKIZ 令牌的大小比较小;通常保持在 250 个字节限值下。对于 PKI 和 PKIZ 令牌,较大的服务目录将导致令牌长度较长。此模式不存在 Fernet 令牌,因为加密有效负载的内容保持在最低限度。

有关 Fernet 令牌和轮转 Fernet 密钥的信息,请参阅 https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/16.2/html-single/deploy_fernet_on_the_overcloud/

4.7. Keystone 域

Keystone 域是高级别安全边界,逻辑上对项目、用户和组进行分组。因此,它们可用于集中管理所有基于 keystone 的身份组件。使用帐户域、服务器和其他资源可逻辑地分组到多个项目中,它们本身可以被分到更高级别的容器中。另外,可以在帐户域中管理多个用户,并为每个项目分配不同的角色。

身份 V3 API 支持多个域。不同域的用户可能在不同身份验证后端中表示。它们也可能有不同的属性,它们必须映射到一组角色和特权,这些属性在策略定义中用于访问各种服务资源。

如果规则可能仅指定对项目的管理员用户和属于项目的用户的访问,其映射可能是微不足道的。在其他情况下,云管理员可能需要批准每个项目的映射例程。

特定于域的身份验证驱动程序允许使用特定于域的配置文件为多个域配置身份服务。启用驱动程序并设置特定于域的配置文件位置,位于 /var/lib/config-data/puppet-generated/keystone/etc/keystone/keystone.conf 文件的 [identity] 部分中。例如:

[identity]
domain_specific_drivers_enabled = True
domain_config_dir = /var/lib/config-data/puppet-generated/keystone/etc/keystone/domains/

任何没有特定域的配置文件的域将使用主 /var/lib/config-data/puppet-generated/keystone/etc/keystone/keystone.conf 文件中的选项。

4.8. 与 LDAP 进行身份验证

您可以使用外部身份提供程序(IdP)向 OpenStack 服务供应商(SP)进行身份验证。在本例中,Service Providers 是 OpenStack 云提供的服务。

对于身份验证和授权服务,OpenStack 身份模型将外部身份验证数据库视为单独的 Keystone 域。每个外部身份验证机制都与 keystone 域关联,支持多个共存域。您可以使用角色为外部域中的用户授予云中资源的访问权限;这种方法也可用于跨域多项目部署。这种方法对每组件策略也具有影响,因为并非所有 OpenStack 角色都可以映射到外部身份验证的用户。例如,如果外部身份验证数据库中的用户需要管理访问权限,则通常还需要额外的配置,并且需要与 admin 域中的 admin 用户类似。

外部身份验证提供了一种方式,使用现有凭证访问多个授权云中提供的云资源,如服务器、卷和数据库,使用一组凭据,而无需多次置备额外的身份或登录。凭据由用户的身份提供程序维护。

身份服务可以将用户凭据存储在 SQL 数据库中,或者可能会使用与 LDAP 兼容的目录服务器。身份数据库可能与其他 OpenStack 服务使用的数据库分离,以减少存储的凭证遭到破坏的风险。

当您使用用户名和密码进行身份验证时,身份不会在密码强、过期或身份验证尝试中强制实施策略。希望执行更强大的密码策略的组织应考虑使用身份扩展或外部身份验证服务。

LDAP 简化了将身份身份验证整合到组织的现有目录服务和用户帐户管理流程中。OpenStack 中的身份验证和授权策略可能会委派给其他服务。典型的用例是寻求部署私有云的组织,已在 LDAP 系统中拥有员工和用户数据库。将此用作身份验证授权机构时,对身份服务的请求将委派给 LDAP 系统,然后根据策略授权或拒绝服务。身份验证成功后,身份服务接着生成用于访问授权服务的令牌。

请注意,如果 LDAP 系统为用户(如 admin、err 和 HR 等)定义了属性,则必须将它们映射到身份内的角色和组中,以供各种 OpenStack 服务使用。/var/lib/config-data/puppet-generated/keystone/etc/keystone/keystone.conf 文件将 LDAP 属性映射到身份属性。

4.9. 与基于 LDAP 的服务集成

Identity Service(keystone)可以验证存储在基于 LDAP 的服务中的用户帐户,如 Microsoft Active Directory Domain Services(AD DS)和 Red Hat Identity Management(IdM)。在这种情况下,keystone 对 LDAP 用户数据库身份验证具有只读访问权限,并且保留对分配给身份验证的帐户的 authZ 特权的管理。keystone 仍然执行 authZ 功能(权限、角色、项目),其中使用 keystone 管理工具为 LDAP 帐户分配权限和角色。

4.9.1. LDAP 集成如何工作

在下图中,keystone 使用加密的 LDAPS 连接连接到 Active Directory 域控制器。当用户登录到 horizon 时,keystone 会收到提供的用户凭证,并将其传递给 authZ 的 Active Directory。

ad 集成 keystone v3

有关将 OpenStack 与 AD DS 和 IdM 集成的信息,请参阅将 OpenStack 身份与外部用户管理服务集成

第 5 章 策略(policy)

每个 OpenStack 服务都包含由访问策略管理的资源。例如,资源可能包含以下功能:

  • 创建和启动实例的权限
  • 将卷附加到实例的功能

如果您是 Red Hat OpenStack Platform(RHOSP)管理员,您可以创建一个自定义策略来引入具有不同访问权限级别的新角色,或更改现有角色的默认行为。

重要

红帽不支持自定义角色和策略。语法错误可能会导致停机,而应用不当授权可能会对安全性或可用性造成负面影响。如果您在生产环境中需要自定义策略,请联络红帽支持以获取例外的支持。

5.1. 查看现有策略

传统上服务的策略文件存在于 /etc/$service 目录中。例如,compute(nova)的 policy.json 文件的完整路径为 /etc/nova/policy.json

有两个重要的架构更改会影响您查找现有策略的方式:

  • Red Hat OpenStack Platform 现在容器化。

    • 如果您从服务容器内查看它们,则策略文件位于传统路径中:

      /etc/$service/policy.json

    • 如果您从服务容器外查看它们,则策略文件(如果存在)位于以下路径中:

      /var/lib/config-data/puppet-generated/$service/etc/$service/policy.json

  • 每个服务都有在代码中提供的默认策略,使用您手动创建的文件,或者当使用 oslopolicy 工具生成时可用文件。要生成策略文件,请使用容器内的 oslopolicy-policy-generator,如下例所示:

    podman exec -it keystone oslopolicy-policy-generator --namespace keystone

默认情况下,生成的策略通过 osly.policy CLI 工具推送到 stdout。

5.2. 了解服务策略

服务策略文件声明是别名定义或规则。别名定义位于文件的顶部。以下列表包含从计算(nova)生成的 policy.json 文件中的别名定义说明:

  • "context_is_admin": "role:admin"

    当目标后出现 rule:context_is_admin 时,策略会在用户允许该操作前使用管理上下文操作。

  • "admin_or_owner": "is_admin:True or project_id:%(project_id)s"

    当在目标后出现 admin_or_owner 时,策略会检查用户是 admin,或者其项目 ID 在允许该操作前与目标对象拥有的项目 ID 匹配。

  • "admin_api": "is_admin:True

    当目标后出现 admin_api 时,策略会在用户允许该操作前检查该用户是 admin。

5.3. 策略语法

policy.json 文件支持某些运算符,以便您可以控制这些设置的目标范围。例如,以下 keystone 设置包含只有 admin 用户可以创建用户的规则:

"identity:create_user": "rule:admin_required"

字符左侧的 部分描述了特权,右侧定义谁能够使用特权。 您还可以使用右侧的 operator 来进一步控制范围:

  • ! - 没有用户(包括 admin)可以执行此操作。
  • @"" - 任何用户可以执行此操作。
  • 不是 - Standard operator 功能可用。

例如,以下设置意味着没有用户有创建新用户的权限:

"identity:create_user": "!"

5.4. 使用策略文件访问控制

要覆盖默认规则,请编辑适当的 OpenStack 服务的 policy.json 文件。例如,计算服务在 nova 目录中有一个 policy.json,当您从容器中查看容器化服务时,这是容器化服务的正确位置。

注意
  • 您必须对暂存环境中的策略文件进行全面的测试更改,然后再在生产环境中实施它们。
  • 您必须检查对访问控制策略的任何更改都不会意外破坏任何资源的安全。另外,对 policy.json 文件的任何更改都会立即生效,且不需要重启服务。

5.5. 示例:创建高级用户角色

要自定义 keystone 角色的权限,请更新服务的 policy.json 文件。这意味着您可以更精细地定义分配给某一类用户的权限。本例为您的部署创建一个 power 用户角色,并具有以下权限:

  • 启动实例。
  • 停止实例。
  • 管理附加到实例的卷。

此角色的目的是为某些用户授予额外权限,而无需授予 admin 访问权限。要使用这些权限,您必须为自定义角色授予以下权限:

  • 启动实例:" os_compute_api:servers:start": "role:PowerUsers"
  • 停止实例:" os_compute_api:servers:stop": "role:PowerUsers"
  • 将实例配置为使用特定的卷:" os_compute_api:servers:create:attach_volume": "role:PowerUsers"
  • 列出附加到实例的卷:" os_compute_api:os-volumes-attachments:index": "role:PowerUsers"
  • 附加卷:" os_compute_api:os-volumes-attachments:create": "role:PowerUsers"
  • 查看附加的卷详情:" os_compute_api:os-volumes-attachments:show": "role:PowerUsers"
  • 更改附加到实例的卷:" os_compute_api:os-volumes-attachments:update": "role:PowerUsers"
  • 删除附加到实例的卷:" os_compute_api:os-volumes-attachments:delete": "role:PowerUsers"
注意

当修改 policy.json 文件时,您要覆盖默认策略。因此,PowerUsers 的成员是可以执行这些操作的唯一用户。要允许 管理员用户 保留这些权限,可以为 admin_or_power_user 创建规则。您还可以使用一些基本条件逻辑来定义 role:PowerUsers 或 role:Admin

  1. 创建自定义 keystone 角色:

    $ openstack role create PowerUsers
    +-----------+----------------------------------+
    | Field     | Value                            |
    +-----------+----------------------------------+
    | domain_id | None                             |
    | id        | 7061a395af43455e9057ab631ad49449 |
    | name      | PowerUsers                      |
    +-----------+----------------------------------+
  2. 将现有用户添加到角色,并将角色分配给项目:

    $ openstack role add --project [PROJECT_NAME] --user [USER_ID] [PowerUsers-ROLE_ID]
    注意

    角色分配仅与一个项目相配。这意味着,当您为用户分配角色时,您也会同时定义 target 项目。如果您希望用户收到相同的角色,但对于其他项目,则必须为它们分配角色,但以不同的项目为目标。

  3. 查看默认 nova 策略设置:

    $ oslopolicy-policy-generator --namespace nova
  4. 通过将以下条目添加到 /var/lib/config-data/puppet-generated/nova/etc/nova/policy.json 来为新的 PowerUsers 角色创建自定义权限:

    注意

    在部署前测试您的策略更改,以验证它们是否按预期工作。

    {
    "os_compute_api:servers:start": "role:PowerUsers",
    "os_compute_api:servers:stop": "role:PowerUsers",
    "os_compute_api:servers:create:attach_volume": "role:PowerUsers",
    "os_compute_api:os-volumes-attachments:index": "role:PowerUsers",
    "os_compute_api:os-volumes-attachments:create": "role:PowerUsers",
    "os_compute_api:os-volumes-attachments:show": "role:PowerUsers",
    "os_compute_api:os-volumes-attachments:update": "role:PowerUsers",
    "os_compute_api:os-volumes-attachments:delete": "role:PowerUsers"
    }

    在保存此文件并重启 nova 容器时会实施更改。添加到 PowerUsers keystone 角色的用户可以接收这些权限。

5.6. 示例:根据属性限制访问权限

您可以创建策略,以根据发出 API 调用的用户属性来限制对 API 调用的访问。例如,以下默认规则指出,如果在管理上下文上运行,则允许密钥对删除,或者令牌的用户 ID 与与目标关联的用户 ID 匹配。

"os_compute_api:os-keypairs:delete": "rule:admin_api or user_id:%(user_id)s"

注:* 在每个发行版本中都无法保证新功能在每项服务中都得到保证。因此,使用 target 服务现有策略的惯例编写规则非常重要。有关查看这些策略的详情,请参阅 检查现有策略。* 所有策略都应该在非生产环境中严格测试,用于部署它们的每个版本,因为策略无法保证跨版本的兼容性。

根据上例,您可以设计 API 规则来根据他们自己的资源来扩展或限制用户的访问权限。另外,属性也可以与其他限制合并,如以下示例所示:

"admin_or_owner": "is_admin:True or project_id:%(project_id)s"

考虑上面的示例,您可以创建一个只限制管理员和用户的唯一规则,然后使用该规则来进一步限制操作:

"admin_or_user": "is_admin:True or user_id:%(user_id)s"
"os_compute_api:os-instance-actions": "rule:admin_or_user"

有关可用的 policy.json 语法选项的更多信息,请参阅 策略语法

5.7. 使用 heat 修改策略

您可以使用 heat 为 overcloud 中的某些服务配置访问策略。使用以下参数来设置相应服务的策略:

表 5.1. 策略参数

参数描述

KeystonePolicies

为 OpenStack Identity(keystone)配置的策略哈希。

IronicApiPolicies

为 OpenStack Bare Metal(ironic)API 配置的策略哈希。

BarbicanPolicies

为 OpenStack Key Manager(barbican)配置的策略哈希。

NeutronApiPolicies

为 OpenStack Networking(neutron)API 配置的策略哈希。

SaharaApiPolicies

为 OpenStack 集群(sahara)API 配置的策略哈希。

NovaApiPolicies

为 OpenStack Compute(nova)API 配置的策略哈希。

CinderApiPolicies

为 OpenStack Block Storage(cinder)API 配置的策略哈希。

GlanceApiPolicies

为 OpenStack Image Storage(glance)API 配置的策略哈希。

HeatApiPolicies

为 OpenStack Orchestration(heat)API 配置的策略哈希。

要为服务配置策略,请为策略参数提供一个 hash 值,其中包含服务的策略,例如:

  • OpenStack Identity(keystone)使用 Keystone 轮询 参数。在环境文件的 parameter_defaults 部分中设置此参数:

    parameter_defaults:
      KeystonePolicies: { keystone-context_is_admin: { key: context_is_admin, value: 'role:admin' } }
  • OpenStack Compute(nova)使用 NovaApiPolicies 参数。在环境文件的 parameter_defaults 部分中设置此参数:

    parameter_defaults:
      NovaApiPolicies: { nova-context_is_admin: { key: 'compute:get_all', value: '@' } }

5.8. 审计您的用户和团队

您可以使用 Red Hat OpenStack Platform 中提供的工具为每个用户和相关权限构建角色分配报告。

  1. 运行 openstack role list 命令以查看您环境中当前的角色:

    openstack role list -c Name -f value
    
    swiftoperator
    ResellerAdmin
    admin
    _member_
    heat_stack_user
  2. 运行 openstack role assignment list 命令,列出属于特定角色的所有用户。例如,要查看具有 admin 角色的所有用户,请运行以下命令:

    $ openstack role assignment list --names --role admin
    +-------+------------------------------------+-------+-----------------+------------+--------+-----------+
    | Role  | User                               | Group | Project         | Domain     | System | Inherited |
    +-------+------------------------------------+-------+-----------------+------------+--------+-----------+
    | admin | heat-cfn@Default                   |       | service@Default |            |        | False     |
    | admin | placement@Default                  |       | service@Default |            |        | False     |
    | admin | neutron@Default                    |       | service@Default |            |        | False     |
    | admin | zaqar@Default                      |       | service@Default |            |        | False     |
    | admin | swift@Default                      |       | service@Default |            |        | False     |
    | admin | admin@Default                      |       | admin@Default   |            |        | False     |
    | admin | zaqar-websocket@Default            |       | service@Default |            |        | False     |
    | admin | heat@Default                       |       | service@Default |            |        | False     |
    | admin | ironic-inspector@Default           |       | service@Default |            |        | False     |
    | admin | nova@Default                       |       | service@Default |            |        | False     |
    | admin | ironic@Default                     |       | service@Default |            |        | False     |
    | admin | glance@Default                     |       | service@Default |            |        | False     |
    | admin | mistral@Default                    |       | service@Default |            |        | False     |
    | admin | heat_stack_domain_admin@heat_stack |       |                 | heat_stack |        | False     |
    | admin | admin@Default                      |       |                 |            | all    | False     |
    +-------+------------------------------------+-------+-----------------+------------+--------+-----------+
    注意

    您可以使用 -f {csv,json,table,value,yaml} 参数导出这些结果。

5.9. 审计 API 访问

您可以审核给定角色可以访问的 API 调用。为每个角色重复此过程会导致每个角色对可访问 API 的综合报告。对于以下步骤,您需要:

  • 作为目标角色中的用户提供的身份验证文件。
  • JSON 格式的访问令牌。
  • 您要审计的每个服务的 API 的一个策略文件。

流程

  1. 首先在所需角色中提供用户的身份验证文件。
  2. 捕获 Keystone 生成的令牌,并将它保存到文件中。您可以运行任何 openstack-cli 命令并使用 --debug 选项实现这一点,它会将提供的令牌输出到 stdout。您可以复制此令牌并将其保存到访问文件中。使用以下命令作为单一步骤进行此操作:

    openstack token issue --debug 2>&1 | egrep ^'{\"token\":' > access.file.json
  3. 创建策略文件。这可以在托管兴趣的容器化服务的 overcloud 节点上完成。以下示例为 cinder 服务创建一个策略文件:

    ssh heat-admin@CONTROLLER-1 sudo podman exec cinder_api \
    oslopolicy-policy-generator \
    --config-file /etc/cinder/cinder.conf \
    --namespace cinder > cinderpolicy.json
  4. 使用这些文件,您现在可以审计对 cinder API 访问相关的角色:

    oslopolicy-checker --policy cinderpolicy.json --access access.file.json

第 6 章 轮转服务帐户密码

您可以定期轮转服务帐户密码,以提高安全状态。

6.1. overcloud 密码管理概述

在 overcloud 上运行的 OpenStack 服务通过其身份服务(keystone)凭据进行身份验证。这些密码在初始部署过程中生成,并定义为 heat 参数。例如:

            'MistralPassword',
            'BarbicanPassword',
            'AdminPassword',
            'CeilometerMeteringSecret',
            'ZaqarPassword',
            'NovaPassword',
            'MysqlRootPassword'

您可以使用工作流服务(mistral)工作流轮转服务帐户使用的密码。但是,如果在 DO_NOT_ROTATE 中列出密码,则不会轮转密码,如密钥加密密钥(KEK)和 Fernet 密钥:

DO_NOT_ROTATE_LIST = (
    'BarbicanSimpleCryptoKek',
    'SnmpdReadonlyUserPassword',
    'KeystoneCredential0',
    'KeystoneCredential1',
    'KeystoneFernetKey0',
    'KeystoneFernetKey1',
    'KeystoneFernetKeys',
)

这些密码位于 DO_NOT_ROTATE 列表中,理由如下:

  • BarbicanSimpleCryptoKek - 更改此密码需要您重新加密所有 secret。
  • KeystoneFernetKeyKeystoneCredential - 已存在独立的工作流来轮换这些工作流。有关更多信息,请参阅 使用工作流服务 轮转 Fernet 密钥

6.2. 轮转密码

使用以下步骤轮转符合条件的密码。下一次运行 openstack overcloud deploy 命令时,会应用您的轮转的密码更改。环境文件中指定的密码优先于使用此方法的密码更改。有关中断要求和服务影响的详情,请参考age 要求。

重要

不要使用这个流程来轮转 swift 密码,因为目前不支持它。

  1. 以 stack 用户身份,运行密码轮转工作流。这会轮转所有密码,除了 DO_NOT_ROTATE 列表中以外的密码:

    $ openstack workflow execution create tripleo.plan_management.v1.rotate_passwords '{"container": "overcloud"}'

    如果只想轮转特定的密码,可以使用 password_list。您还可以使用此方法轮转 DO_NOT_ROTATE 列表中的密码。例如:

    $ openstack workflow execution create tripleo.plan_management.v1.rotate_passwords '{"container": "overcloud", "password_list": ["SaharaPassword", "ManilaPassword"]}'
    The Workflow service Mistral workflow generates new passwords for the service accounts.
  2. 运行堆栈更新以应用新密码。
  3. 您可以通过创建工作流来检索和查看新密码,然后查看输出:

    1. 创建新工作流以检索密码。记录工作流的 ID:

      $ openstack workflow execution create tripleo.plan_management.v1.get_passwords '{"container": "overcloud"}'
       +--------------------+---------------------------------------------+
       | Field              | Value                                       |
       +--------------------+---------------------------------------------+
       | ID                 | edcf9103-e1a8-42f9-85c1-e505c055e0ed        |
       | Workflow ID        | 8aa2ac9b-22ee-4e7d-8240-877237ef0d0a        |
       | Workflow name      | tripleo.plan_management.v1.rotate_passwords |
       | Workflow namespace |                                             |
       | Description        |                                             |
       | Task Execution ID  | <none>                                      |
       | Root Execution ID  | <none>                                      |
       | State              | RUNNING                                     |
       | State info         | None                                        |
       | Created at         | 2020-01-22 15:47:57                         |
       | Updated at         | 2020-01-22 15:47:57                         |
       +--------------------+---------------------------------------------+
    2. 使用工作流 ID 检查工作流状态。您必须等到工作流的状态为 SUCCESS,然后才能继续:

      $ openstack workflow execution show edcf9103-e1a8-42f9-85c1-e505c055e0ed
            +--------------------+---------------------------------------------+
            | Field              | Value                                       |
            +--------------------+---------------------------------------------+
            | ID                 | edcf9103-e1a8-42f9-85c1-e505c055e0ed        |
            | Workflow ID        | 8aa2ac9b-22ee-4e7d-8240-877237ef0d0a        |
            | Workflow name      | tripleo.plan_management.v1.rotate_passwords |
            | Workflow namespace |                                             |
            | Description        |                                             |
            | Task Execution ID  | <none>                                      |
            | Root Execution ID  | <none>                                      |
            | State              | SUCCESS                                     |
            | State info         | None                                        |
            | Created at         | 2020-01-22 15:47:57                         |
            | Updated at         | 2020-01-22 15:48:39                         |
            +--------------------+---------------------------------------------+
    3. 当工作流完成后,使用以下命令检索密码:

      openstack workflow execution output show edcf9103-e1a8-42f9-85c1-e505c055e0ed
           {
                "status": "SUCCESS",
                "message": {
                    "AdminPassword": "FSn0sS1aAHp8YK2fU5niM3rxu",
                    "AdminToken": "dTP0Wdy7DtblG80M54r4a2yoC",
                    "AodhPassword": "fB5NQdRe37BaBVEWDHVuj4etk",
                    "BarbicanPassword": "rn7yk7KPafKw2PWN71MvXpnBt",
                    "BarbicanSimpleCryptoKek": "lrC3sGlV7-D7-V_PI4vbDfF1Ujm5OjnAVFcnihOpbCg=",
                    "CeilometerMeteringSecret": "DQ69HdlJobhnGWoBC0jM3drPF",
                    "CeilometerPassword": "qI6xOpofuiXZnG95iUe8Oxv5d",
                    "CephAdminKey": "AQDGVPpdAAAAABAAZMP56/VY+zCVcDT81+TOjg==",
                    "CephClientKey": "AQDGVPpdAAAAABAAanYtA0ggpcoCbS1nLeDN7w==",
                    "CephClusterFSID": "141a5ede-21b4-11ea-8132-52540031f76b",
                    "CephDashboardAdminPassword": "AQDGVPpdAAAAABAAKhsx630YKDhQrocS4o4KzA==",
                    "CephGrafanaAdminPassword": "AQDGVPpdAAAAABAAKBojG+CO72B0TdBRR0paEg==",
                    "CephManilaClientKey": "AQDGVPpdAAAAABAAA1TVHrTVCC8xQ4skG4+d5A=="
                }
            }

6.3. 中断要求

当您更改 overcloud 服务帐户的密码时,中断要求和服务可能会影响。

在堆栈更新过程中轮转密码后,旧密码就将变为无效。因此,服务会在服务配置设置中添加新密码的持续时间内不可用,并显示 HTTP 401 错误。

另外,您还可在更改支持服务的密码(包括 MySQL、RabbitMQ 和 High Availability)时遇到简短中断。

第 7 章 强化基础架构和虚拟化

定期检查硬件和软件供应商,获取有关新漏洞和安全更新的可用信息。红帽产品安全团队维护以下站点以告知您安全更新:

定期更新 Red Hat OpenStack Platform 部署时请注意以下几点。

  • 请确保包括所有安全更新。
  • 内核更新需要重新启动。
  • 更新托管的镜像服务(glance)镜像,以确保新创建的实例具有最新的更新。

7.1. 虚拟机监控程序

当您评估虚拟机监控程序平台时,请考虑管理程序将运行的硬件的支持性。另外,请考虑硬件中的附加功能以及您选择的功能作为 OpenStack 部署的一部分。为此,管理程序各自具有自己的硬件兼容性列表(HCL)。在选择兼容硬件时,从安全角度了解基于硬件的虚拟化技术非常重要。

7.1.1. 虚拟机监控程序与裸机

与使用 KVM 等管理程序相比,务必要识别使用 Linux 容器或裸机系统之间的差别。具体来说,此安全指南的重点在于拥有管理程序和虚拟化平台。但是,如果您的实施需要使用裸机或容器化环境,您必须注意与部署该环境相关的特定区别。

对于裸机,请确保节点已在重新置备和停用之前正确清理数据。此外,在重新使用节点前,您必须保证硬件未被篡改或受到破坏。更多信息请参阅 https://docs.openstack.org/ironic/queens/admin/cleaning.html

7.1.2. 管理程序内存优化

某些虚拟机监控程序使用过量内存的内存优化技术。这是一个有用的功能,可用于部署非常高密度的计算集群。这个技术的一种方法是通过重复数据删除或共享内存页面:当两个虚拟机在内存中有相同的数据时,可以将它们引用同一内存的优点。这通常通过写时复制(COW)机制来执行,如内核相同的页面合并(KSM)。这些机制容易受到攻击:

  • 内存重复数据删除系统容易受到侧频道攻击的影响。在学术研究中,攻击者能够识别在邻居虚拟机上运行的软件包和版本,以及通过分析攻击者虚拟机上的内存访问时间来下载软件下载和其他敏感信息。因此,一个虚拟机可能会推断另一个项目的状态,这可能不适用于受信任或共享相同级别的信任环境。
  • 更重要的是,根据 KSM 对可执行内存进行跨虚拟机修改,对 行-hammer 类型攻击 也进行了演示。这意味着,恶意实例可以获取对同一 Compute 主机上其他实例的代码执行访问权限。

如果部署器需要强大的项目分离(与公共云和某些私有云一样),则应该禁用 KSM:

7.2. PCI Passthrough

PCI 透传允许实例直接访问节点上某一部分硬件。例如,这可用于允许实例访问提供计算统一设备架构(CUDA)的视频卡或 GPU,以实现高性能计算。这个功能包括了两种类型的安全风险:直接进行内存访问和硬件存在。

直接内存访问(DMA)是允许某些硬件设备访问主机计算机中的任意物理内存地址的功能。通常视频卡具有此功能。但是,不应为实例赋予任意物理内存访问权限,因为这会完全查看主机系统及其他在同一节点上运行的实例。硬件供应商使用输入/输出内存管理单元(IOMMU)在这些情况下管理 DMA 访问。您应该确认将虚拟机监控程序配置为使用此硬件功能。

当实例对固件或其它某个设备的一部分进行恶意修改时,会发生硬件问题。由于此设备被其他实例或主机操作系统使用,因此恶意代码可以分布到这些系统中。最终结果是一个实例可以在其安全区外运行代码。这是大量漏洞,因为与虚拟硬件相比,物理硬件的状态更难重置,并可能导致其他暴露(如访问管理网络)。

由于与 PCI 透传相关的风险和复杂性,应该默认禁用它。如果为特定需求启用,则需要相应的进程来帮助确保硬件在重复使用前被清理。

7.3. selinux

强制访问控制通过将 QEMU 进程的权限限制为仅需要什么,从而限制尝试攻击的影响。在 Red Hat OpenStack Platform 上,SELinux 配置为在一个单独的安全上下文下运行每个 QEMU 进程。SELinux 策略已预先配置为 Red Hat OpenStack Platform 服务。

OpenStack 的 SELinux 策略旨在帮助保护虚拟机监控程序主机和虚拟机,使其免受两个主要威胁向量的威胁:

  • 管理程序威胁 - 虚拟机内部运行的已被破坏的应用程序可攻击管理程序访问底层资源。例如,当虚拟机可以访问虚拟机监控程序操作系统、物理设备或其他应用程序时。这种威胁向向量表示,因为虚拟机监控程序上的妥协的风险可能会破坏物理硬件,同时公开其他虚拟机和网络段。
  • 虚拟机(多项目)威胁 - 虚拟机内运行的应用受到攻击,从而访问或控制另一台虚拟机及其资源。这是对虚拟化特有的威胁,它表示存在大量虚拟机文件镜像的风险,因为单个应用程序中存在漏洞,可能会破坏多种虚拟机文件镜像。这种虚拟网络攻击主要关注的是,因为用于保护实际网络的管理技术不直接应用于虚拟环境。每个基于 KVM 的虚拟机都是一个由 SELinux 标记的进程,可有效地在每个虚拟机上建立安全边界。这个安全边界由 Linux 内核监控和强制,限制虚拟机对边界外的资源的访问,如主机数据文件或其他虚拟机。

无论虚拟机内运行的客户机操作系统,都提供了基于 SELinux 的隔离功能。可以使用 Linux 或 Windows 虚拟机。

7.3.1. labels 和 Categories

基于 KVM 的虚拟机实例使用自己的 SELinux 数据类型标记,称为 svirt_image_t。内核级别的保护可防止未经授权的系统进程(如 malware)操作磁盘上的虚拟机镜像文件。虚拟机关闭后,镜像将存储为 svirt_image_t,如下所示:

system_u:object_r:svirt_image_t:SystemLow image1
system_u:object_r:svirt_image_t:SystemLow image2
system_u:object_r:svirt_image_t:SystemLow image3
system_u:object_r:svirt_image_t:SystemLow image4

svirt_image_t 标签 唯一标识磁盘上的镜像文件,允许 SELinux 策略限制访问。当基于 KVM 的计算镜像开机时,SELinux 会将随机数字标识符附加到镜像中。SELinux 能够为每个虚拟机监控程序节点分配最多 524,288 个虚拟机的数值标识符,但大多数 OpenStack 部署不太可能遇到这个限制。此示例显示 SELinux 类别标识符:

system_u:object_r:svirt_image_t:s0:c87,c520 image1
system_u:object_r:svirt_image_t:s0:419,c172 image2

7.3.2. SELinux 用户和角色

SELinux 管理用户角色。它们可以通过 -Z 标志查看,也可以使用 semanage 命令查看。在虚拟机监控程序上,应该只有管理员才能访问系统,并且应该对管理用户和系统上的其他用户有适当的上下文。

7.4. 容器化服务

许多 Red Hat OpenStack Platform 服务(如计算服务(nova)、镜像服务(glance)和身份服务(keystone))在容器内运行。通过容器化,您可以更轻松地将更新应用到服务。另外,可能的漏洞是被隔离的,这可以减少对相邻服务的受攻击面。

注意

挂载到容器的主机上的路径可以作为挂载点来传输容器和主机之间的数据(如果它们配置为 ro/rw )。

如果要测试环境中的配置选项,请考虑以下选项:

  • 您可以更新容器中运行的配置文件。容器内的环境具有临时性,因此在重启容器时会丢失更改。
  • 您可以在托管容器的系统中更新绑定挂载配置。下一次运行 openstack overcloud deploy 命令时,如果这些配置更改不在 heat 中,则配置更改将会丢失。

不要更新 /etc 中的服务配置文件,例如 /etc/cinder/cinder.conf。这是因为容器化服务不引用此文件。

注意

要进行永久配置更改,您必须修改 Red Hat OpenStack Platform director 上的 heat 模板,并重新运行 openstack overcloud deploy 命令,使用与最初使用的参数相同的环境文件。包括包含配置更改的任何其他环境文件。

bind-mounted 服务配置文件位于 /var/lib/config-data/puppet-generated 目录中。例如:

  • Identity service: /var/lib/config-data/puppet-generated/keystone/etc/keystone/keystone.conf
  • Block Storage 服务: /var/lib/config-data/puppet-generated/cinder/etc/cinder/cinder.conf
  • 计算服务: /var/lib/config-data/puppet-generated/nova_libvirt/etc/nova/nova.conf

这些配置文件在初始部署期间由 puppet 生成,其中包含了决定 Red Hat OpenStack 云环境行为的敏感配置信息。在重启容器时会实施更改。

7.5. 强化计算部署

任何 OpenStack 部署都存在一些主要安全问题,即安全并控制相关的文件,如 /var/lib/config-data/puppet-generated/nova_libvirt/etc/nova/nova.conf 文件。此配置文件包含多个敏感选项,包括配置详情和服务密码。所有敏感文件都应授予严格的文件级别权限,并通过 AIDE 等文件完整性监控(FIM)工具来监控其更改。这些实用程序会使用已知良好状态的目标文件的哈希值,然后定期获取文件的新哈希并将其与已知良好的哈希进行比较。如果发现一个警报已被意外修改,则可以创建一个警报。

可以通过移动到文件中包含的目录并运行 ls -lh 命令来检查文件的权限。这将显示有权访问该文件的权限、所有者和组,以及该文件上次修改以及该文件创建的时间等信息。

/var/lib/nova 目录保存有关给定 Compute 节点上的实例的信息。该目录应该被视为敏感,并且严格强制实施文件权限。另外,它应该定期备份,因为它包含与该主机关联的实例的信息和元数据。

如果您的部署不需要完整的虚拟机备份,请考虑不包括 /var/lib/nova/instances 目录,因为它会像该节点上运行的每个实例的组合空间一样大。如果您的部署需要完全虚拟机的备份,则需要确保成功备份该目录。

注意

存储在存储子系统(例如 Ceph)卷中的数据也应被视为敏感,因为当网络或逻辑访问允许时,可以从 storage 子系统检索完整的虚拟机镜像(如网络或逻辑访问权限),这可能会绕过 OpenStack 控制。

7.6. 固件更新

物理服务器使用复杂的固件启用和操作服务器硬件和轻量管理卡,该卡可能具有自己的安全漏洞,有可能允许系统访问和中断。为解决这些问题,硬件供应商会发布固件更新,这些更新与操作系统更新分开。您将需要一个可按照常规时间表检索、测试并实施这些更新的操作安全性,请注意,固件更新通常需要重新启动物理主机才能生效。

7.7. 块存储

OpenStack Block Storage(cinder)是一个提供软件(服务和库)的服务,为自助服务管理持久块级存储设备。这会创建按需访问块存储资源,以用于计算(nova)实例。这可以通过将块存储池虚拟化到各种后端存储设备(可以是软件实施或传统硬件存储产品)来创建软件定义存储。这样做的主要功能是管理块设备的创建、附加和分离。消费者不需要了解后端存储设备的类型,或者它所在的位置。

计算实例使用行业标准存储协议(如 iSCSI、ATA over Ethernet 或 Fibre-Channel)检索块存储。这些资源通过 OpenStack 原生标准的 HTTP RESTful API 管理和配置。

7.7.1. 卷 Wiping

可以通过多种方式擦除块存储设备。传统的方法是将 lvm_type 设为 thin,然后使用 volume_clear 参数。另外,如果卷加密功能是我们的,那么删除卷加密密钥时不需要卷。

注意

在以前的版本中,lvm_type=default 用于识别一个擦除。虽然此方法仍可正常工作,但不推荐设置安全删除,但不推荐使用 lvm_type=default

volume_clear 参数可以接受 或以参数 取用。零将零 写入单个零给设备。shred 操作将写入预先确定的位模式。

7.7.2. 使用 keystone 进行身份验证

/var/lib/config-data/puppet-generated/cinder/cinder/cinder.conf 中,检查 [DEFAULT] 部分下的 auth_strategy 的值是否已设置为 keystone,而不是 auth

7.7.3. 启用 TLS 进行身份验证

/var/lib/config-data/puppet-generated/cinder/cinder.conf 中,检查 [keystone_authtoken] 项中的 auth_uri 的值是否被设置为一个以 https:// ' 开始的 Identity API 端点,并且 [keystone_authtoken] 下也设置为 False

7.7.4. 确保块存储使用 TLS 与 Compute 通信

cinder.conf 中,检查 [DEFAULT] 部分下的 glance_api_servers 的值设置为以 https:// 开头的值,并且参数 glance_api_insecure 的值设置为 False

7.7.5. 为请求正文设置最大大小

如果没有定义每个请求的最大正文大小,攻击者可以制作一个大大小的 OSAPI 请求,从而导致服务崩溃,最后导致服务攻击。分配 t he maximum value 可确保任何恶意请求被恶意的请求被阻止,确保服务的持续可用性。

检查 cinder.conf 中的 [oslo_middleware] 部分下的 max_request_body_size 是否设置为 114688

7.7.6. 启用卷加密

未加密的卷数据使卷托管平台对于攻击者而言尤其高价值目标,因为它允许攻击者读取多个不同虚拟机的数据。此外,物理存储介质是 stu ld,重新挂载,并从不同的计算机访问。加密卷数据和卷备份可帮助缓解这些风险,并深入了解卷托管平台。块存储(c inder)能够在将卷数据写入磁盘前加密卷数据,因此请考虑启用卷加密,并将 Barbican 用于私钥存储。

7.8. 网络

OpenStack Networking 服务(neutron)允许 end-user 或项目定义和使用网络资源。OpenStack 网络提供了一个面向项目的 API,用于定义云中实例的网络连接和 IP 寻址,除了编排网络配置之外。随着过渡到以 API 为中心的网络服务,云架构师和管理员应考虑一个良好的实践,以保护物理和虚拟网络基础架构和服务。

OpenStack 网络设计了一个插件架构,它通过开源社区或第三方服务提供 API 的可扩展性。当您评估您的架构设计要求时,务必要确定 OpenStack 网络核心服务中的哪些功能、第三方产品提供的其他服务,以及在物理基础架构中实施哪些补充服务。

本节概述了实施 OpenStack 网络时应考虑哪些流程和良好实践。

7.8.1. 网络架构

OpenStack 网络是一个独立服务,可在多个节点上部署多个进程。这些进程会相互交互,以及其他 OpenStack 服务。OpenStack 网络服务的主要进程是 neutron-server,它是一个 Python 守护进程,它公开 OpenStack 网络 API,并将项目请求传递给一组插件以进行额外处理。

OpenStack 网络组件有:

  • Neutron 服务器(neutron-serverneutron-*-plugin - neutron-server 服务在 Controller 节点上运行,以服务网络 API 及其扩展(或插件)。它还强制实施每个端口的网络模型和 IP 地址。neutron-server 需要直接访问持久数据库。代理可以通过 neutron-server 间接访问数据库,它们使用 AMQP(高级消息队列协议)进行通信。
  • Neutron 数据库 - 数据库是 neutron 信息的集中式源,API 记录数据库中的所有事务。这允许多个 Neutron 服务器共享同一数据库集群,它们全部保持同步,并允许使网络配置拓扑的持久性。
  • 插件代理(neutron-*-agent) - 在每个计算节点和网络节点(与 L3 和 DHCP 代理)上运行,以管理本地虚拟交换机(vswitch)配置。启用插件决定启用哪些代理。这些服务需要消息队列访问权限,并且根据所使用的插件,访问外部网络控制器或 SDN 实施。有些插件(如 OpenDaylight(ODL)和 Open Virtual Network(OVN))不需要计算节点上任何 python 代理,只需要启用 Neutron 插件才能集成。
  • DHCP 代理(neutron-dhcp-agent) - 为项目网络提供 DHCP 服务。这个代理在所有插件中是相同的,它负责维护 DHCP 配置。neutron-dhcp-agent 需要消息队列访问权限。可选,具体取决于插件。
  • 元数据代理(neutron-metadata-agentneutron-ns-metadata-proxy - 提供用于应用实例操作系统配置和用户提供的初始脚本(userdata')的元数据服务。实施需要在 L3 或 DHCP 代理命名空间中运行的 neutron-ns-metadata-proxy 截获 cloud-init 发送的元数据 API 请求,以代理到元数据代理。
  • L3 代理(neutron-l3-agent) - 为项目网络上的虚拟机的外部网络访问提供 L3/NAT 转发。需要消息队列访问权限。可选,具体取决于插件。
  • 网络提供程序服务(SDN 服务器/服务) - 为项目网络提供额外的联网服务。这些 SDN 服务可能会通过 REST API 等通信频道与 neutron-server、neutron-plugin 和 plugin-agents 交互。

下图显示了 OpenStack 网络组件的架构和网络流图:

网络连接

请注意,在使用分布式虚拟路由(DVR)和第 3 层高可用性(L3HA)时,这种方法会有很大变化。这些模式改变了 neutron 的安全环境,因为 L3HA 在路由器之间实现 VRRP。部署需要正确大小并强化,以帮助缓解对路由器的 DoS 攻击,而且路由器之间的本地网络流量必须被视为敏感,以帮助解决 VRRP 伪造的威胁。DVR 将网络组件(如路由)移到计算节点,同时仍然需要网络节点。因此,计算节点需要访问公共网络,增加其暴露并要求客户进行额外的安全考虑,因为它们需要确保防火墙规则和安全模型支持这个方法。

7.8.2. Neutron 服务在物理服务器上放置

本节介绍了标准架构,其中包括控制器节点、网络节点,以及一组用于运行实例的计算节点。要为物理服务器建立网络连接,典型的 neutron 部署具有最多四个不同的物理数据中心网络:

网络拓扑图
  • 管理网络 - 用于 OpenStack 组件之间的内部通信。此网络上的 IP 地址应只在数据中心中访问,并被视为管理安全区。默认情况下,管理网络角色由 内部 API 网络执行。
  • 客户机网络 - 用于云部署内虚拟机数据通信。此网络的 IP 寻址要求取决于所使用的 OpenStack 网络插件以及项目发出的虚拟网络的网络配置选择。这个网络被视为 Guest Security 区域。
  • 外部网络 - 在某些部署场景中,用来提供带有互联网访问的虚拟机。该网络上的 IP 地址应该可以被互联网上的任何人访问。此网络被视为在公共安全区域中。此网络由 neutron 外部网络 提供。这些 neutron VLAN 托管在外部网桥上。它们不是由 Red Hat OpenStack Platform director 创建,而是在部署后由 neutron 创建。
  • 公共 API 网络 - 将所有 OpenStack API(包括 OpenStack 网络 API)公开给项目。该网络上的 IP 地址应该可以被互联网上的任何人访问。这可能是与外部网络相同的网络,因为有可能为外部网络创建子网,该网络使用 IP 分配范围小于 IP 块中的完整 IP 地址范围。此网络被视为在公共安全区域中。

建议您将此流量分成不同的区。如需更多信息,请参阅下一节。

7.8.3. 安全区

建议您使用安全区的概念使关键系统相互独立。在实际意义上,这意味着使用 VLAN 和防火墙规则隔离网络流量。这有精细的细节来完成,结果应该只有需要连接到 neutron 的服务才能这样做。

在下图中,您可以看到创建了区来分离某些组件:

  • 仪表板:可以访问公共网络和管理网络。
  • Keystone:可访问管理网络。
  • Compute 节点:可以管理网络和计算实例。
  • 网络节点:根据使用中的 neutron-plugin,可以访问管理网络、计算实例以及可能公共网络。
  • SDN 服务节点:管理服务、计算实例,以及可能根据所使用的产品和配置进行公共公共。
网络区

.

7.8.4. 网络服务

在设计 OpenStack 网络基础架构的初始架构阶段,务必要确保适当的专业知识有助于设计在线网络基础架构的设计,以识别正确的安全控制和审计机制。

OpenStack 网络添加了一个虚拟化网络服务层,为项目提供架构自己的虚拟网络的能力。目前,这些虚拟服务不像其传统网络对应项一样成熟。在使用这些虚拟化服务之前,请考虑这些虚拟化服务的当前状态,因为它规定了在虚拟化和传统网络边界上实施哪些控制。

7.8.5. 使用 VLAN 和隧道进行 L2 隔离

OpenStack 网络可以采用两种不同的机制来隔离各个项目/网络组合:VLAN(IEEE 802.1Q 标记)或 L2 隧道(使用 VXLAN 或 GRE 封装)。OpenStack 部署的范围和缩放决定了您应该用于流量隔离或隔离的方法。

7.8.6. VLAN

VLAN 在带有特定 VLAN ID(VID)字段值的特定物理网络上实现为数据包。共享同一物理 netw 或k 的 VLAN 网络相互隔离,甚至可以有重叠的 IP 地址空间。每个支持 VLAN 网络的每一个不同的物理网络被视为单独的 VLAN 中继 k,不同的空间为 VID 值。有效 VID 值为 1 到 4094。

VLAN 配置的复杂性取决于您的 OpenStack 设计要求。要允许 OpenStack 网络更有效地使用 VLAN,您必须分配一个 VLAN 范围(每个项目一个),并将每个 Compute 节点物理交换机端口转换成 VLAN 中继端口。

7.8.7. L2 隧道

网络隧道将各个项目/网络组合与一个唯一的 隧道 相结合,用于标识属于该组合的网络流量。项目的 L2 网络连接独立于物理局域网或底层网络设计。通过将流量封装在 IP 数据包中,该流量可以跨第 3 层边界实现流量,从而消除对预先配置的 VLAN 和 VLAN 中继的需求。隧道为网络流量添加了一个模糊处理层,从而减少了各个项目流量的可见性。

OpenStack 网络目前支持 GRE 和 VXLAN 封装。提供 L2 隔离的技术选择取决于部署中要创建的项目网络的范围和大小。

7.8.8. 访问控制列表

计算通过使用 OpenStack 网络服务支持项目网络流量访问控制。安全组允许管理员和项目指定流量类型,以及允许传递虚拟接口端口的方向(入口/出口)。安全组规则是有状态 L2-L4 流量过滤器。

7.8.9. L3 路由和 NAT

OpenStack 网络路由器可以连接多个 L2 网络,还可提供一个网关,用于将一个或多个私有 L2 网络连接到共享外部网络,如用于访问互联网的公共网络。

L3 路由器在网关端口上提供基本的网络地址转换(SNAT 和 DNAT)功能,可将路由器链接到外部网络。此路由器 SNAT(源 NAT)默认所有出口流量,并支持浮动 IP,这会从外部网络上的公共 IP 到附加到路由器的其他子网中的一个私有 IP 创建一个静态一对一双向映射。浮动 IP(通过 DNAT)提供实例的外部入站连接,并可从一个实例移到另一个实例。

考虑使用 per-project L3 路由和浮动 IP 来更精细地连接项目实例。应考虑特殊考虑给实例连接到公共网络或使用浮动 IP。建议仔细考虑使用安全组,只过滤对需要在外部公开的服务的访问。

7.8.10. 服务质量(QoS)

默认情况下,服务质量(QoS)策略和规则由云管理员管理,这会导致项目无法创建特定的 QoS 规则,或者将 pecific 策略附加到端口。在一些用例中,比如一些电信应用程序,管理员可能会信任项目,因此允许他们创建自己的策略并将其附加到端口。这可以通过修改 policy.json 文件来实现。

从 Red Hat OpenStack Platform 12,neutron 支持入口和出口流量的带宽限制 QoS 规则。这个 QoS 规则名为 QosBandwidthLimitRule,它接受每秒以 kilobits 测量的两个非负整数:

  • max-kbps :带宽
  • max-burst-kbps: burst buffer

QoSBandwidthLimitRule 在 neutron Open vSwitch、Linux 网桥和 SR-IOV 驱动程序中实施。但是,对于 SR-IOV 驱动程序,不使用 max-burst-kbps 值,并在设置时忽略。

QoS 规则 QosDscpMarkingRule 设置 IPv4(RFC 2474)和 IPv6 上所有流量的 IPv6 上服务标头类型中的 differentiated Service Code Point(DSCP)值,其中应用该规则。这是一个带有 21 个有效值的 6 位标头,它表示数据包的丢弃优先级,因为通过网络达到拥塞时。防火墙也可以使用它与其访问控制列表匹配有效或无效流量。

7.8.11. 负载平衡

OpenStack 负载均衡服务(octavia)为 Red Hat OpenStack Platform director 安装提供负载均衡即服务(LBaaS)实施。要实现负载均衡,octavia 支持启用多个供应商驱动程序。参考供应商驱动程序(Amphora 提供者驱动程序)是一个开源、可扩展和高可用性的负载。它通过管理虚拟机组来实现负载平衡服务的交付 - 也称为按需启动的情况。

有关负载均衡服务的详情,请参考 使用 Octavia 进行负载均衡即服务指南

7.8.12. 强化网络服务

本节讨论 OpenStack 网络配置良好做法,因为它们适用于 OpenStack 部署中的项目网络安全性。

7.8.13. 限制 API 服务器的绑定地址:neutron-server

要限制 OpenStack Networking API 服务绑定传入客户端连接的接口或 IP 地址,在 /var/lib/config-data/puppet-generated/neutron/etc/neutron/neutron.conf 文件中指定 bind_hostbind_por t

# Address to bind the API server
bind_host = IP ADDRESS OF SERVER

# Port the bind the API server to
bind_port = 9696

7.8.14. 项目网络服务工作流

OpenStack 网络为用户提供网络资源的自助服务配置。云架构师和操作员务必要通过评估其设计用例,以为用户提供创建、更新和销毁可用的网络资源。

7.8.15. 网络资源策略引擎

在 OpenStack 网络中,策略引擎及其配置文件(policy.json)提供了在项目联网方法和对象上为用户提供精细的授权方法。OpenStack N etworking 策略定义会影响网络可用性、网络安全性和整体 OpenStack 安全性。云架构师和操作员应仔细评估其对用户和项目来管理网络资源的策略。

注意

务必要检查默认的网络资源策略,因为该策略可以被修改以适合您的安全措施。

如果您的 OpenStack 部署提供多个外部访问点到不同的安全区,请务必将项目附加多个 vNIC 的能力限制为多个外部访问 po intsies,这会桥接这些安全区,并可能导致不预见的安全破坏。您可以使用计算提供的主机聚合功能,或将th e 项目实例拆分为具有不同虚拟网络配置的多个项目,从而帮助缓解这一风险。如需有关主机聚合的更多信息,请参阅创建和管理主机聚合

7.8.16. 安全组

安全组是安全组规则的集合。通过安全组及其规则,管理员和项目可以指定流量类型和方向(入口/出口)类型,它们被允许通过虚拟接口端口传递。在 OpenStack 网络中创建虚拟接口端口时,它将与安全组关联。可将规则添加到默认安全组中,以便根据部署更改行为。

当使用 Compute API 修改安全组时,更新的安全组将应用到实例上的所有虚拟接口端口。这是因为,计算安全组 API 是基于实例而非基于端口的,如 neutron 中找到的。

7.8.17. 缓解 ARP 欺骗

OpenStack 网络具有内置功能,可帮助缓解对实例的 ARP 欺骗。除非考虑到结果风险,否则不应禁用此设置。

7.8.18. 使用安全协议进行身份验证

/var/lib/config-data/puppet-generated/neutron/etc/neutron/neutron.conf 检查 [keystone_authtoken] 项中的 auth_uri 的值被设置为一个以 'https 开始的 Identity API 端点:

第 8 章 网络时间协议

您需要确保 Red Hat OpenStack Platform 集群中的系统在系统间有准确且一致的时间戳。

Red Hat Enterprise Linux 8 上的 Red Hat OpenStack Platform 支持 Chrony 进行时间管理。如需更多信息,请参阅使用 Chrony 套件配置 NTP

8.1. 为什么一致性时间非常重要

在整个机构中保持一致的时间对于操作和安全需求都很重要:

识别安全事件
一致计时有助于关联受影响系统上的事件的时间戳,以便您了解事件的顺序。
身份验证和安全系统

安全系统对时间偏差可能敏感,例如:

  • 基于 kerberos 的身份验证系统可能会拒绝验证受时钟偏移影响的客户端。
  • 传输层安全性(TLS)证书取决于有效时间源。如果客户端和服务器系统之间的差别超过 Valid From date 范围,则服务器 TLS 连接的客户端会失败。
Red Hat OpenStack Platform 服务
一些核心 OpenStack 服务特别取决于准确计时,包括高可用性(HA)和 Ceph。

8.2. NTP 设计

网络时间协议(NTP)以分级设计的形式进行组织。每个层都被称为 stratum。层次结构的顶部是 stratum 0 设备,如 atomic 时钟。在 NTP 层次结构中,stratum 0 设备为公开可用的 stratum 1 和 stratum 2 NTP 时间服务器提供参考。

请勿将数据中心客户端直接连接到公开可用的 NTP stratum 1 或 2 服务器。直接连接数量会对公共 NTP 资源造成不必要的压力。相反,在您的数据中心中分配专用时间服务器,并将客户端连接到该专用服务器。

将实例配置为从您的专用时间服务器接收时间,而不是从它们所在的主机接收时间。

注意

在 Red Hat OpenStack Platform 环境中运行的服务容器仍然会从其所在的主机接收时间。

第 9 章 使用 director 配置安全强化

在部署过程中,使用 Red Hat OpenStack Platform director 应用安全强化值。OpenStack 配置文件由 director 管理,如果直接编辑,则可覆盖。

在运行 openstack overcloud deploy 时,请记住,除了您要进行的任何更改外,您始终需要包括部署 overcloud 所需的所有环境文件。

9.1. 使用 SSH 横幅文本

您可以设置一个横幅,向通过 SSH 连接的所有用户显示控制台消息。您可以使用环境文件中的以下参数在 /etc/issue 中添加横幅文本。考虑自定义此示例文本以满足您的要求。

resource_registry:
  OS::TripleO::Services::Sshd:
    /usr/share/openstack-tripleo-heat-templates/deployment/sshd/sshd-baremetal-puppet.yaml

parameter_defaults:
  BannerText: |
   ******************************************************************
   * This system is for the use of authorized users only. Usage of  *
   * this system may be monitored and recorded by system personnel. *
   * Anyone using this system expressly consents to such monitoring *
   * and is advised that if such monitoring reveals possible        *
   * evidence of criminal activity, system personnel may provide    *
   * the evidence from such monitoring to law enforcement officials.*
   ******************************************************************

要将这一更改应用到您的部署,请将设置保存为名为 ssh_banner.yaml 的文件,然后按照如下所示 将其传递给 overcloud 部署命令。& lt;full environment > 表示您仍必须包含所有原始部署参数。例如:

    openstack overcloud deploy --templates \
      -e <full environment> -e  ssh_banner.yaml

9.2. 系统事件的审计

维护所有审计事件的记录可帮助您建立系统基线、执行故障排除或分析导致特定结果的事件序列。审计系统能够记录许多类型的事件,如系统时间的变化、强制/探索访问控制的变化,以及创建/分离用户或组。

可以使用环境文件创建规则,然后将其由 director 注入到 /etc/audit/audit.rules。例如:

    resource_registry:
      OS::TripleO::Services::AuditD: /usr/share/openstack-tripleo-heat-templates/deployment/auditd/auditd-baremetal-puppet.yaml
    parameter_defaults:
      AuditdRules:
        'Record Events that Modify User/Group Information':
          content: '-w /etc/group -p wa -k audit_rules_usergroup_modification'
          order  : 1
        'Collects System Administrator Actions':
          content: '-w /etc/sudoers -p wa -k actions'
          order  : 2
        'Record Events that Modify the Systems Mandatory Access Controls':
          content: '-w /etc/selinux/ -p wa -k MAC-policy'
          order  : 3

9.3. 管理防火墙规则

防火墙规则会在部署过程中自动应用于 overcloud 节点,并且设计为仅公开让 OpenStack 正常工作所需的端口。您可以根据需要指定额外的防火墙规则。例如,要为 Zabbix 监控系统添加规则:

    parameter_defaults:
      ControllerExtraConfig:
        tripleo::firewall::firewall_rules:
          '301 allow zabbix':
            dport: 10050
            proto: tcp
            source: 10.0.0.8
            action: accept

您还可以添加限制访问的规则。规则定义中使用的数字将决定规则的优先级。例如,RabbitMQ 的规则编号默认为 109。如果要限制它,请将其切换为使用较低值:

    parameter_defaults:
      ControllerExtraConfig:
        tripleo::firewall::firewall_rules:
          '098 allow rabbit from internalapi network':
            dport: [4369,5672,25672]
            proto: tcp
            source: 10.0.0.0/24
            action: accept
          '099 drop other rabbit access':
            dport: [4369,5672,25672]
            proto: tcp
            action: drop

在这个示例中,098099 是任意选择的数字,小于 RabbitMQ 的规则号 109。要确定规则的数量,您可以检查相应节点上的 iptables 规则;对于 RabbitMQ,您要检查控制器:

iptables-save
[...]
-A INPUT -p tcp -m multiport --dports 4369,5672,25672 -m comment --comment "109 rabbitmq" -m state --state NEW -j ACCEPT

或者,也可以从 puppet 定义中提取端口要求。例如,RabbitMQ 的规则存储在 puppet/services/rabbitmq.yaml 中:

    tripleo.rabbitmq.firewall_rules:
      '109 rabbitmq':
        dport:
          - 4369
          - 5672
          - 25672

可以为规则设置以下参数:

  • 端口 :与该规则关联的端口。由 puppetlabs-firewall 弃用。
  • dport :与该规则关联的目的地端口。
  • SPORT :与该规则关联的源端口。
  • proto :与该规则关联的协议。默认为 tcp
  • 操作 :与该规则关联的操作策略。默认为 accept
  • 跳过 :要跳至的链。
  • State:与该规则关联的状态阵列。默认为 [NEW]
  • Source :与该规则关联的源 IP 地址。
  • 在iface 中 :与该规则关联的网络接口。
  • :与该规则关联的链。默认为 INPUT
  • destination :与该规则关联的目的地 cidr。
  • Extraspuppetlabs-firewall 模块支持的任何额外参数的哈希。

9.4. 使用 AIDE 进行入侵检测

AIDE(高级入侵检测环境)是一个文件和目录完整性检查程序。它用于检测未授权文件篡改或更改的事件。例如,如果更改了系统密码文件,AIDE 可以提醒您。

AIDE 通过分析系统文件并编译文件哈希的完整性数据库来实现。然后,数据库作为验证文件和目录的完整性并检测更改的比较点。

director 包括 AIDE 服务,允许您在 AIDE 配置中添加条目,然后供 AIDE 服务用于创建完整性数据库。例如:

  resource_registry:
    OS::TripleO::Services::Aide:
      /usr/share/openstack-tripleo-heat-templates/deployment/aide/aide-baremetal-ansible.yaml

  parameter_defaults:
    AideRules:
      'TripleORules':
        content: 'TripleORules = p+sha256'
        order: 1
      'etc':
        content: '/etc/ TripleORules'
        order: 2
      'boot':
        content: '/boot/ TripleORules'
        order: 3
      'sbin':
        content: '/sbin/ TripleORules'
        order: 4
      'var':
        content: '/var/ TripleORules'
        order: 5
      'not var/log':
        content: '!/var/log.*'
        order: 6
      'not var/spool':
        content: '!/var/spool.*'
        order: 7
      'not nova instances':
        content: '!/var/lib/nova/instances.*'
        order: 8
注意

上面的示例没有主动维护或基准,因此您应选择符合您要求的 AIDE 值。

  1. 声明了一个名为 TripleORules 的别名,以避免每次重复出现相同的属性。
  2. 别名接收 p+sha256 的属性。在 AIDE 术语中,它将以下指令读取:监控所有文件权限 p,其完整性校验和为 sha256

有关 AIDE 配置文件可用属性的完整列表,请参阅 AIDE MAN 页面 https://aide.github.io/

完成以下步骤以将更改应用到您的部署:

  1. 将设置保存为 /home/stack/templates/ 目录中的名为 aide.yaml 的文件。
  2. 编辑 aide.yaml 环境文件,使其包含适用于您的环境的参数和值。
  3. openstack overcloud deploy 命令中包含 /home/stack/templates/templates.yaml 环境文件,以及特定于您的环境的所有其他 heat 模板和环境文件:

    openstack overcloud deploy --templates
    ...
    -e /home/stack/templates/aide.yaml

9.4.1. 使用复杂 AIDE 规则

可使用前面描述的格式创建复杂的规则。例如:

    MyAlias = p+i+n+u+g+s+b+m+c+sha512

上面的操作将作为以下指令转换:监控权限、内节点、链接数、用户、组、大小、块大小、mtime、ctime、ctime(使用 sha256 生成)。

请注意,别名应始终具有 1 的顺序位置,即它将位于 AIDE 规则的顶部,并且递归应用到下面的所有值。

别名后面的是要监控的目录。请注意,可以使用正则表达式。例如,我们为 var 目录设置了监控,但使用 '!/var/log.*''!/var/spool.*' 覆盖了 not 子句。

9.4.2. 其他 AIDE 值

以下 AIDE 值也可用:

AideConfPath: 到 aide 配置文件的完整 POSIX 路径,默认为 /etc/aide.conf。如果没有要求更改文件位置,则建议继续使用默认路径。

AideDBPath :到 AIDE 完整性数据库的完整 POSIX 路径。此值可以配置,使操作员能够声明自己的完整路径,因为 AIDE 数据库文件可能会存储在只读文件挂载中。

AideDBTempPath: 到 AIDE 完整性临时数据库的完整 POSIX 路径。当 AIDE 初始化新数据库时,会创建此临时文件。

AideHour :此值是将 hour 属性设置为 AIDE cron 配置的一部分。

AideMinute :此值是将 minute 属性设置为 AIDE cron 配置的一部分。

AideCronUser :此值是将 linux 用户设置为 AIDE cron 配置的一部分。

AideEmail :此值设置每次发出 cron 运行时接收 AIDE 的电子邮件地址。

AideMuaPath :此值设置用于将 AIDE 报告发送到在 AideEmail 中设置的电子邮件地址的路径。

9.4.3. AIDE 的 cron 配置

AIDE director 服务允许您配置 Cron Job。默认情况下,它将向 /var/log/audit/ 发送报告;如果要使用电子邮件警报,请启用 AideEmail 参数,以将警报发送到配置的电子邮件地址。请注意,依赖关键警报的电子邮件可能会容易受到系统中断和无意消息过滤的影响。

9.4.4. 考虑系统升级的影响

执行升级时,AIDE 服务将自动重新生成新的完整性数据库,以确保正确重新计算所有升级的文件,使其包含更新的 checksum。

如果 openstack overcloud deploy 作为后续到初始部署而被调用,并且更改了 AIDE 配置规则,则 director AIDE 服务将重建数据库,以确保新配置属性被封装在完整性数据库中。

9.5. 查看 SecureTTY

securetty 允许您禁用任意控制台设备(tty)的 root 访问权限。此行为由 /etc/securetty 文件中的条目管理。例如:

  resource_registry:
    OS::TripleO::Services::Securetty: ../puppet/services/securetty.yaml

  parameter_defaults:
    TtyValues:
      - console
      - tty1
      - tty2
      - tty3
      - tty4
      - tty5
      - tty6

9.6. Identity Service 的 CADF 审计

彻底的审计流程可帮助您检查 OpenStack 部署的持续安全状况。这对于 keystone 来说尤其重要,因为它在安全模式中发挥其角色。

Red Hat OpenStack Platform 采用了 Cloud Auditing Data Federation(CADF)作为审计事件的数据格式,使用 keystone 服务为身份和令牌操作生成 CADF 事件。您可以使用 KeystoneNotificationFormat 为 keystone 启用 CADF 审计:

  parameter_defaults:
    KeystoneNotificationFormat: cadf

9.7. 查看 login.defs 值

要强制新系统用户(非keystone)的密码要求,director 可以根据这些示例参数将条目添加到 /etc/login.defs 中:

  resource_registry:
    OS::TripleO::Services::LoginDefs: ../puppet/services/login-defs.yaml

  parameter_defaults:
    PasswordMaxDays: 60
    PasswordMinDays: 1
    PasswordMinLen: 5
    PasswordWarnAge: 7
    FailDelay: 4

第 10 章 强化仪表板服务

控制面板为用户提供了一个自助门户网站,从而在管理员设定的限制内置备自己的资源。控制面板的处理应当与 OpenStack API 相同的敏感度。

10.1. 选择一个域名

建议您将仪表板部署到第二个级别域,如 https://example.com,而不是在共享子域(任何级别上部署仪表板),如 https://openstack.example.orghttps://horizon.openstack.example.org。还建议您避免将仪表板部署到裸机内部域,如 https://horizon/。这些建议基于浏览器 同一origin-policy 的限制。

这种方法可帮助您将 Cookie 和安全令牌与其他域隔离,其中可能没有完全控制内容。在子域上部署时,仪表板的安全性等同于同一第二级域中部署的最小安全应用程序。

您可以通过避免由 Cookie 支持的会话存储并配置 HTTP Strict Transport Security(HSTS)(在本指南中分离)来进一步缓解这一风险。

10.2. 配置 ALLOWED_HOSTS

Web 服务可能会受到与虚拟 HTTP 主机标头相关的威胁。为了帮助缓解这种情况,请考虑将 ALLOWED_HOSTS 设置配置为使用 OpenStack 仪表板提供的 FQDN。

配置后,如果传入 HTTP 请求的 Host: 标头中与这个列表中的任何值不匹配,则会引发错误,请求者将无法继续。

Horizon 基于 python Django Web 框架,需要设置 ALLOWED_HOSTS 来防止 HTTP Host: 标头的恶意操作。将此值设置为 FQDN,控制面板应可从以下位置进行访问。对于 director,此设置由 HorizonAllowedHosts 管理。

10.3. 跨站点脚本(XSS)

OpenStack 仪表板可以自定义,并允许大多数字段中设置整个 Unicode 字符;这种可扩展性允许引入跨站点脚本(XSS)漏洞。Horizon 包括可帮助开发人员避免意外创建 XSS 漏洞的工具,但只有在开发人员正确使用时它们才起作用。建议您审计任何自定义仪表板,并特别注意以下功能:

  • mark_safe 功能。
  • is_safe - 与自定义模板标签一起使用。
  • 安全 模板标签。
  • 任何自动转义都被关闭,任何 JavaScript 都可能评估不正确的转义数据。

10.4. 跨站点请求 Forgery(CSRF)

OpenStack 仪表板旨在鼓励开发人员通过自定义仪表板引入跨站点脚本漏洞,因为可能会引入威胁。使用多个 JavaScript 实例的仪表板应对漏洞进行审核,如 @csrf_exempt decorator 的使用不当使用。在 CORS(跨 Origin 资源共享)限制之前,应仔细评估未遵循这些建议安全设置的仪表板。

您应该将 Web 服务器配置为使用每个响应发送限制性 CORS 标头,仅允许仪表板域和协议。例如:Access-Control-Allow-Origin: https://example.com/。您不应该允许通配符来源。

10.5. 跨外脚本(XFS)

disallow_iframe_embed 设置不允许将 Dashboard 嵌入到 iframe 中。旧浏览器仍容易受到 Cross-Frame Scripting(XFS)漏洞的影响,因此这个选项为不需要进行 RAM 的部署增加了额外的安全强化功能。

您可以使用以下参数允许 iframe 嵌入:

    parameter_defaults:
      ControllerExtraConfig:
        horizon::disallow_iframe_embed: false

10.6. 使用 HTTPS 加密进行仪表板流量

建议您使用 HTTPS 加密 Dashboard 流量。您可以通过将其配置为使用来自可识别的证书颁发机构(CA)的有效可信证书来完成此操作。只有在所有用户浏览器中预安装的信任根时,私有机构签发的证书才合适。

将 HTTP 请求配置为控制面板域,以重定向到完全限定的 HTTPS URL。

有关基于 director 的部署,请参阅 https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/16.2/html/advanced_overcloud_customization/sect-enabling_ssltls_on_the_overcloud

10.7. HTTP 严格传输安全性(HSTS)

HTTP 严格传输安全性(HSTS)可防止浏览器在最初进行安全连接后进行后续的不安全连接。如果您在公共或不可信区上部署了 HTTP 服务,则 HSTS 非常重要。

对于基于 director 的部署,此设置在 /usr/share/openstack-tripleo-heat-templates/deployment/horizon/horizon-container-puppet.yaml 文件中默认启用:

horizon::enable_secure_proxy_ssl_header: true

验证

部署 overcloud 后,检查 Red Hat OpenStack Dashboard(horizon)进行验证的 local_settings 文件。

  1. 使用 ssh 连接到控制器:

    $ ssh heat-admin@controller-0
  2. 检查 SECURE_PROXY_SSL_HEADER 参数的值是否为 ('HTTP_X_FORWARDED_PROTO', 'https'):

    sudo egrep ^SECURE_PROXY_SSL_HEADER /var/lib/config-data/puppet-generated/horizon/etc/openstack-dashboard/local_settings
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

10.8. 前端缓存

不建议将前端缓存工具和仪表板,因为它呈现直接从 OpenStack API 请求生成的动态内容。因此,varnish 等前端缓存层可能会阻止显示正确的内容。控制面板使用 Django,它直接从 Web 服务提供静态介质,并从 web 主机缓存中受益。

10.9. 会话后端

对于基于 director 的部署,horizon 的默认会话后端是 django.contrib.sessions.backends.cache,后者与 memcached 相结合。由于性能的原因,这种方法首选本地内存缓存,对于高可用性和负载平衡安装,而且能够在多个服务器上共享缓存,同时仍然将其视为单一缓存。

您可以在 director 的 horizon.yaml 文件中查看这些设置:

          horizon::cache_backend: django.core.cache.backends.memcached.MemcachedCache
          horizon::django_session_engine: 'django.contrib.sessions.backends.cache'

10.10. 查看 secret 密钥

控制面板依赖于一个共享的 SECRET_KEY 设置,用于某些安全功能。secret 密钥应该是随机生成的字符串,长度至少为 64 个字符,它必须在所有活跃的仪表板实例间共享。破坏此密钥可能允许远程攻击者执行任意代码。轮转此密钥会导致现有用户会话和缓存无效。不要将此密钥提交到公共存储库。

对于 director 部署,此设置作为 HorizonSecret 值进行管理。

10.11. 配置会话 Cookie

仪表板会话 Cookie 可以通过浏览器技术(如 JavaScript)进行交互。对于各处使用 TLS 的 director 部署,您可以使用 HorizonSecureCookies 设置强化此行为。

注意

切勿将 CSRF 或会话 Cookie 配置为使用带有前导点的通配符域。

10.12. 静态介质

仪表板的静态介质应当部署到仪表板域的子域,并由 Web 服务器提供。另外还可使用外部内容交付网络(CDN)。此子域不应设置 cookies,或者提供用户提供的内容。介质还应通过 HTTPS 提供。

控制面板的默认配置使用 django_ everywhere 来压缩和减号 CSS 和 JavaScript 内容,然后再提供它。此过程应在部署仪表板之前静态完成,而不是使用默认的 in-request 动态压缩,以及与部署的代码或 CDN 服务器复制生成的文件。在非生产环境构建环境中进行压缩。如果这不实际,请考虑完全禁用资源压缩。生产机器上不应安装在线压缩依赖关系(无 Node.js)。

10.13. 验证密码复杂性

OpenStack Dashboard(horizon)可以使用密码验证检查来强制实施密码复杂性。

您可以为密码验证指定正则表达式,以及为失败的测试显示帮助文本。以下示例要求用户在长度为 8 到 18 个字符之间创建密码:

    parameter_defaults:
      HorizonPasswordValidator: '^.{8,18}$'
      HorizonPasswordValidatorHelp: 'Password must be between 8 and 18 characters.'

要将这一更改应用到您的部署,请将设置保存为名为 horizon_password.yaml 的文件,然后按照如下所示将其传递给 overcloud deploy 命令。& lt;full environment > 表示您仍必须包含所有原始部署参数。例如:

    openstack overcloud deploy --templates \
      -e <full environment> -e  horizon_password.yaml

10.14. 强制管理员密码检查

默认情况下,以下设置设为 True,但在需要时可使用环境文件来禁用它。

注意

只有在潜在的安全影响被完全理解后,这些设置才应设置为 False

Dashboard 的 local_settings.py 文件中的 ENFORCE_PASSWORD_CHECK 设置显示 Change Password 表单上的 Admin Password 字段,这有助于验证管理员是否启动密码更改。

您可以使用环境文件禁用 ENFORCE_PASSWORD_CHECK

    parameter_defaults:
      ControllerExtraConfig:
        horizon::enforce_password_check: false

10.15. disallow iframe embedding

注意

只有在潜在的安全影响被完全理解后,这些设置才应设置为 False

DISALLOW_IFRAME_EMBED 设置不允许将 Dashboard 嵌入到 iframe 中。旧浏览器仍容易受到 Cross-Frame Scripting(XFS)漏洞的影响,因此这个选项为不需要进行 RAM 的部署增加了额外的安全强化功能。默认情况下,设置为 True,但可以根据需要使用环境文件来禁用此设置。例如,您可以使用以下参数允许 iframe 嵌入:

    parameter_defaults:
      ControllerExtraConfig:
        horizon::disallow_iframe_embed: false

10.16. 禁用密码发现

默认情况下,以下设置设为 True,但在需要时可使用环境文件来禁用它。

注意

只有在潜在的安全影响被完全理解后,这些设置才应设置为 False

password reveal 按钮可让 Dashboard 用户查看它们要输入的密码。这个选项可以使用 DISABLE_PASSWORD_REVEAL 参数切换:

    parameter_defaults:
      ControllerExtraConfig:
        horizon::disable_password_reveal: false

10.17. 显示仪表板的登录标题

许多监管的行业,如 HIPAA、PCI-DSS 和 U.S。政府要求您显示用户登录标题。控制面板服务在容器内运行,因此您需要自定义 Dashboard 容器镜像以应用横幅。有关自定义 Dashboard 容器的更多信息,请参阅 https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/16.2/html-single/introduction_to_the_openstack_dashboard/index#dashboard-customization

10.18. 自定义主题

在自定义 Dashboard 容器中,您可以通过手动编辑 /usr/share/openstack-dashboard/openstack_dashboard/openstack_dashboard/themes/rcue/templates/auth/login.html 文件来创建登录标题:

  1. {% include 'auth/_login.html' %} 部分前输入所需的 logon banner。请注意,可以使用 HTML 标签。例如:

    <snip>
    <div class="container">
      <div class="row-fluid">
        <div class="span12">
          <div id="brand">
            <img src="../../static/themes/rcue/images/RHOSP-Login-Logo.svg">
          </div><!--/#brand-->
        </div><!--/.span*-->
    
        <!-- Start of Logon Banner -->
        <p>Authentication to this information system reflects acceptance of user monitoring agreement.</p>
        <!-- End of Logon Banner -->
    
        {% include 'auth/_login.html' %}
      </div><!--/.row-fluid→
    </div><!--/.container-->
    
    {% block js %}
      {% include "horizon/_scripts.html" %}
    {% endblock %}
    
      </body>
    </html>

更新的仪表板类似如下:

logonbanner

10.19. 限制文件上传的大小

您可以选择配置仪表板来限制文件上传的大小;此设置可能是各种安全强化策略的要求。

LimitRequestBody - 此值(以字节为单位)限制您可以使用控制面板传输的文件的最大大小,如镜像和其他大文件。

重要

红帽还没有对此设置进行正式测试。建议您在将此设置部署到生产环境前全面测试此设置的效果。

注意

如果值太小,则文件上传将失败。

例如,此设置限制每个文件上传的最大大小为 10 GB(10737418240)。您需要调整这个值以适应部署。

  • /var/lib/config-data/puppet-generated/horizon/etc/httpd/conf/httpd.conf

    <Directory />
      LimitRequestBody 10737418240
    </Directory>
  • /var/lib/config-data/puppet-generated/horizon/etc/httpd/conf.d/10-horizon_vhost.conf

    <Directory "/var/www">
      LimitRequestBody 10737418240
    </Directory>
  • /var/lib/config-data/puppet-generated/horizon/etc/httpd/conf.d/15-horizon_ssl_vhost.conf

    <Directory "/var/www">
      LimitRequestBody 10737418240
    </Directory>
注意

这些配置文件由 Puppet 管理,因此每当运行 openstack overcloud 部署过程时,任何未管理的更改都会被覆盖。

10.20. 调试 Dashboard 服务

建议您在生产环境中将 DEBUG 设置设置为 False。如果设置为 True,则 Django 可能会输出堆栈追踪来浏览器包含敏感 Web 服务器状态信息的用户。另外,DEBUG 模式还对禁用 ALLOWED_HOSTS 的影响,这可能是一个不可取的结果,具体取决于您的要求。

第 11 章 强化共享文件系统服务(Manila)

共享文件系统服务(manila)提供了一组服务,用于在多项目云环境中管理共享文件系统。使用 manila,您可以创建一个共享文件系统并管理其属性,如可见性、可访问性和配额。

有关 manila 的更多信息,请参阅存储指南 :https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/16.2/html-single/storage_guide/

11.1. manila 的安全注意事项

Manila 由 keystone 注册,允许您使用 manila endpoint 命令找到 API。例如:

 $ manila endpoints
 +-------------+-----------------------------------------+
 | manila      | Value                                   |
 +-------------+-----------------------------------------+
 | adminURL    | http://172.18.198.55:8786/v1/20787a7b...|
 | region      | RegionOne                               |
 | publicURL   | http://172.18.198.55:8786/v1/20787a7b...|
 | internalURL | http://172.18.198.55:8786/v1/20787a7b...|
 | id          | 82cc5535aa444632b64585f138cb9b61        |
 +-------------+-----------------------------------------+

 +-------------+-----------------------------------------+
 | manilav2    | Value                                   |
 +-------------+-----------------------------------------+
 | adminURL    | http://172.18.198.55:8786/v2/20787a7b...|
 | region      | RegionOne                               |
 | publicURL   | http://172.18.198.55:8786/v2/20787a7b...|
 | internalURL | http://172.18.198.55:8786/v2/20787a7b...|
 | id          | 2e8591bfcac4405fa7e5dc3fd61a2b85        |
 +-------------+-----------------------------------------+

默认情况下,manila API 服务仅侦听带有 tcp6 的端口 8786,它支持 IPv4 和 IPv6。

Manila 使用多个配置文件,这些文件存储在 /var/lib/config-data/puppet-generated/manila/ 中:

 api-paste.ini
 manila.conf
 policy.json
 rootwrap.conf
 rootwrap.d

 ./rootwrap.d:
 share.filters

建议您将 manila 配置为在非 root 服务帐户下运行,并更改文件权限,以便只有系统管理员才能修改它们。Manila 要求只有管理员对配置文件写入,服务只能通过 manila 组中的组成员资格来读取它们。其他用户不能读取这些文件,因为它们包含服务帐户密码。

注意

只有 root 用户应该可以自行写入 rootwrap.conf 中的 manila-rootwrapmanila-rootwrap 命令过滤器,用于在 rootwrap.d/share.filters 中共享节点。

11.2. manila 的网络和安全模型

manila 中的共享驱动程序是 Python 类,可以为后端设置来管理共享操作,其中一些特定于厂商。后端是 manila-share 服务的实例。Manila 为许多不同的存储系统共享驱动程序,支持商业供应商和开源解决方案。每个共享驱动程序都支持一个或多个后端模式: 共享服务器无共享服务器。管理员通过使用 driver_handles_share_serversmanila.conf 中指定模式来选择模式。

共享服务器是一个逻辑网络连接存储(NAS)服务器,可导出共享文件系统。当今的后端存储系统很复杂,可以隔离不同 OpenStack 项目之间的数据路径和网络路径。

由 manila 共享驱动程序置备的共享服务器将在属于创建项目用户的隔离网络上创建。共享 服务器模式可以配置扁平网络或网段网络,具体取决于网络提供程序。

对于不同的模式,可以采用单独的驱动程序来使用相同的硬件。根据所选模式,您可能需要通过配置文件提供更多配置详情。

11.3. 共享后端模式

每个共享驱动程序支持至少一个可用驱动程序模式:

  • 共享服务器 - driver_handles_share_servers = True - 共享驱动程序创建共享服务器并管理共享服务器生命周期。
  • 没有共享服务器 - driver_handles_share_servers = False - 管理员(而不是共享驱动程序)使用网络接口管理裸机存储,而不是依赖于共享服务器。

没有共享服务器模式 - 在这个模式中,驱动程序不会设置共享服务器,因此不需要设置任何新的网络接口。假设驱动程序管理的存储控制器具有它所需的所有网络接口。驱动程序在没有创建共享服务器的情况下直接创建共享。要使用在这个模式下运行的驱动程序创建共享,manila 不需要用户创建任何私有共享网络。

注意

在没有共享服务器模式 中,manila 将假定所有项目都可通过其中导出任何共享的网络接口。

共享服务器 模式中,共享驱动程序不处理共享服务器生命周期。管理员应该处理存储、网络和其他主机配置,这些配置可能需要提供项目隔离。在这个模式中,管理员可以将存储设置为导出共享的主机。OpenStack 云内的所有项目共享一个共同的网络管道。缺少隔离可能会影响安全性和服务质量。当使用不处理共享服务器的共享驱动程序时,云用户无法确保无法通过不受信任的用户访问其共享,从而接管其文件系统的顶级目录。公共云中,可能为所有网络带宽供一个客户端使用,因此管理员应该注意的是不会发生此情况。网络平衡可通过任何方式完成,而不仅仅使用 OpenStack 工具。

共享服务器模式 - 在这个模式中,驱动程序可以创建共享服务器并将其插入现有的 OpenStack 网络。Manila 决定需要新的共享服务器,并提供共享驱动程序创建必要共享服务器所需的所有网络信息。

当在处理共享服务器的驱动程序模式中创建共享时,用户必须提供一个共享网络,他们期望共享在共享之后导出。Manila 使用这个网络为这个网络中的共享服务器创建网络端口。

用户可以在 共享 服务器中配置安全服务,也不能 共享服务器 后端模式。但是,如果没有共享服务器 后端模式,管理员必须在主机上手动设置所需的身份验证服务。在 共享服务器 模式中,manila 可以在它生成的共享服务器上配置由用户标识的安全服务。

11.4. manila 的网络要求

Manila 可以和不同的网络类型集成: 扁平GREVLANVXLAN

注意

Manila 只将网络信息存储在数据库中,以及由网络供应商提供的实际网络。Manila 支持使用 OpenStack Networking 服务(neutron),以及"standalone"预先配置的网络。

共享服务器 后端模式中,共享驱动程序为每个共享网络创建和管理共享服务器。这个模式可以分为两种变体:

  • 共享服务器 后端模式中的扁平网络
  • 共享服务器 后端模式进行分段网络

用户可以使用 OpenStack Networking(neutron)服务的网络和子网来创建共享网络。如果管理员决定使用 StandAloneNetworkPlugin,用户不需要提供任何网络信息,因为管理员在配置文件中预配置此功能。

注意

由一些共享驱动程序生成的共享服务器是利用计算服务创建的 Compute 服务器。其中一些驱动程序不支持网络插件。

创建共享网络后,manila 会检索由网络供应商决定的网络信息:网络类型、分段标识符(如果网络使用分段)和 CIDR 标记中的 IP 块(用于分配网络)。

用户可以创建安全服务,用于指定 AD 或 LDAP 域或 Kerberos 域等安全要求。Manila 假设安全服务中任何主机都可以从创建共享服务器的子网访问,这限制了可以使用此模式的情况。

注意

有些共享驱动程序可能不支持所有类型的分段,以了解更多详细信息您使用的驱动程序规格。

11.5. 使用 manila 的安全服务

Manila 可以通过与网络身份验证协议集成来限制对文件共享的访问。每个项目可以拥有自己的身份验证域,其功能与云的 keystone 身份验证域分开。此项目域可用于向 OpenStack 云中运行的应用程序(包括 manila)提供授权(AuthZ)服务。可用的身份验证协议包括 LDAP、Kerberos 和 Microsoft Active Directory 身份验证服务。

11.6. 安全服务简介

创建共享并获取其导出位置后,用户没有挂载它的权限,并使用文件进行操作。用户需要明确授予新共享的访问权限。

客户端身份验证和授权(authN/authZ)可与安全服务一起执行。如果由共享驱动程序和后端支持,Manila 会使用 LDAP、Kerberos 或 Microsoft Active 目录。

注意

在某些情况下,需要明确指定一种安全服务,例如,NetApp、EMC 和 Windows 驱动程序需要 Active Directory 来使用 CIFS 协议创建共享。

11.7. 安全服务管理

安全服务 是一个 manila 实体,它抽象一组选项,为特定共享文件系统协议定义安全区,如 Active Directory 域或 Kerberos 域。安全服务包含 manila 创建加入给定域的服务器所需的所有信息。

通过使用 API,用户可以创建、更新、查看和删除安全服务。安全服务采用以下假设:

  • 项目提供安全服务的详细信息。
  • 管理员关心安全服务:它们配置此类安全服务的服务器端。
  • 在 manila API 中,一个 security_serviceshare_networks 关联。
  • 共享驱动程序使用安全服务中的数据配置新创建的共享服务器。

在创建安全服务时,您可以选择其中一个身份验证服务:

  • LDAP - 轻量级目录访问协议。用于通过 IP 网络访问和维护分布式目录信息服务的应用程序协议。
  • Kerberos - 网络验证协议,以票据为基础,允许非安全网络通信的节点以安全的方式证明其身份。
  • Active Directory - Microsoft 为 Windows 域网络开发的目录服务。使用 LDAP、Microsoft 的版本 Kerberos 和 DNS。

Manila 允许您使用以下选项配置安全服务:

  • 在项目网络中使用的 DNS IP 地址。
  • 安全服务的 IP 地址或主机名。
  • 安全服务的域。
  • 项目使用的用户或组名称。
  • 如果您指定用户名,则输入密码。

现有安全服务实体可以与共享网络实体关联,该实体告知 manila 关于一组共享的安全性和网络配置。您还可以查看指定共享网络的所有安全服务列表,并将它们与共享网络解除。

管理员和用户作为共享所有者可通过 IP 地址、用户、组或 TLS 证书创建具有身份验证的访问规则来管理对共享的访问。身份验证方法取决于您的配置和使用的共享驱动程序和安全服务。然后,您可以将后端配置为使用特定的身份验证服务,该服务可在不使用 manila 和 keystone 的情况下与客户端操作。

注意

不同共享驱动程序支持不同的身份验证服务。有关支持不同驱动程序功能的详情,请参考 https://docs.openstack.org/manila/latest/admin/share_back_ends_feature_support_mapping.html

通过驱动程序支持特定身份验证服务,并不意味着可以使用任何共享文件系统协议配置它。支持的共享文件系统协议是 NFS、CEPHFS、CIFS、GlusterFS 和 HDFS。有关特定驱动程序及其安全服务配置的详情,请查看驱动程序厂商的文档。

有些驱动程序支持安全服务和其他驱动程序不支持上述任何安全服务。例如:带有 NFS 或 CIFS 共享文件系统协议的通用驱动程序只支持通过 IP 地址验证方法。

注意

在大多数情况下,支持 CIFS 共享文件系统协议的驱动程序可以配置为使用 Active Directory 并通过用户身份验证管理访问权限。

  • 支持 GlusterFS 协议的驱动程序可使用 TLS 证书进行身份验证。
  • 使用支持使用 IP 地址进行 NFS 协议验证的驱动程序是唯一支持的选项。
  • 由于 HDFS 共享文件系统服务协议使用 NFS 访问,因此也可以将其配置为使用 IP 地址进行身份验证。

production manila 部署的建议配置是创建与 CIFS 共享协议的共享,并将其添加到 Microsoft Active Directory 目录服务中。通过此配置,您将获得集成 Kerberos 和 LDAP 方法的集中数据库和服务。

11.8. 共享访问控制

用户可以指定哪些特定客户端有权访问他们所创建的共享。由于 keystone 服务,由各个用户创建的共享仅对同一项目中的其他用户可见。Manila 允许用户创建"公开"可见的共享。如果所有者授予他们访问权限,则这些共享在仪表板中可见,他们甚至可以在网络上挂载这些共享。

在创建共享期间,使用密钥 --public 使您的共享公钥在共享列表中查看它并查看其详细信息。

根据 policy.json 文件,管理员和作为共享所有者的用户可以通过创建访问规则来管理对共享的访问。使用 manila access-allowmanila access-denymanila access-list 命令,您可以相应地授予、拒绝和列出指定共享的访问权限。

注意

Manila 不提供存储系统的端到端管理。您仍然需要单独保护后端系统,使其免受未经授权的访问。因此,如果有人破坏后端存储设备,manila API 提供的保护仍然可以被忽略。

当刚刚创建共享时,没有关联有默认访问规则以及挂载它的权限。这会在挂载配置供使用中的导出协议中看到。例如:存储中有一个 NFS 命令 exportfs/etc/exports 文件,该文件控制每个远程共享并定义可以访问它的主机。如果 nobody 可以挂载共享,则为空。对于远程 CIFS 服务器,有 net conf list 命令,该命令会显示配置。hosts deny 参数应由共享驱动程序设置为 0.0.0.0/0,这意味着任何主机都被拒绝挂载共享。

使用 manila,您可以通过指定其中一个受支持的共享访问级别来授予或拒绝对共享的访问:

  • rw - 读和写(RW)访问权限。这是默认值。
  • ro- 只读(RO)访问。
注意

当管理员为特定编辑器或贡献者授予读和写(RW)访问权限,并且为其他用户(viewers)授予只读(RO)访问权限时,对公共共享而言非常有用。

您还必须指定这些支持的验证方法之一:

  • ip - 使用 IP 地址来验证实例。可以通过以 CIDR 表示法表示的 IPv4 或 IPv6 地址或子网为客户端提供 IP 访问。
  • 证书 - 使用 TLS 证书验证实例。将 TLS 身份指定为 IDENTKEY。有效值是证书的通用名称(CN)中最多 64 个字符的任意字符串。
  • User - 由指定用户或组名称进行授权。有效的值是字母数字字符串,可以包含一些特殊字符,从 4 到 32 个字符。
注意

支持的验证方法取决于您所使用的共享驱动程序、安全服务和共享文件系统协议。支持的共享文件系统协议是 MapRFS、CEPHFS、NFS、CIFS、GlusterFS 和 HDFS。支持的安全服务包括 LDAP、Kerberos 协议或 Microsoft Active Directory 服务。

要验证某个共享是否正确配置了访问规则(ACL),您可以列出其权限。

注意

为共享选择安全服务时,您需要考虑共享驱动程序是否能够使用可用身份验证方法创建访问规则。支持的安全服务包括 LDAP、Kerberos 和 Microsoft Active Directory。

11.9. 共享类型访问控制

共享类型是由项目可见描述 组成的管理员定义的服务类型,以及名为"无项目"的键值对列表。manila-scheduler 使用额外的规格来做出调度决策,驱动程序则控制共享创建。

管理员可以创建和删除共享类型,也可以管理授予 manila 内的含义的额外规格。项目可以列出共享类型,并可使用它们创建新共享。共享类型可以作为 公共和私有 创建。这是定义其他项目是否可以在共享类型列表中查看的共享类型的可见性级别,并使用它来创建新的共享。

默认情况下,共享类型创建为公共类型。在创建共享类型时,请使用 --is_public 参数设置为 False,使共享类型私有,这将阻止其他项目在共享类型列表中看到,并与它创建新的共享。另一方面,公共 共享类型可供云中的每个项目使用。

Manila 允许管理员为项目授予或拒绝对 私有 共享类型的访问。您还可以获取有关指定私有共享类型访问权限的信息。

注意

由于共享类型因其额外规格帮助在用户创建共享之前过滤或选择后端,因此请使用对共享类型的访问权限,在选择特定后端时限制客户端。

例如,admin 项目中的管理员用户可以创建一个名为 my_type 的专用共享类型,并在列表中查看它。在下面的控制台示例中,省略了登录和注销,并提供环境变量来显示当前登录的用户。

 $ env | grep OS_
 ...
 OS_USERNAME=admin
 OS_TENANT_NAME=admin
 ...
 $ manila type-list --all
 +----+--------+-----------+-----------+-----------------------------------+-----------------------+
 | ID | Name   | Visibility| is_default| required_extra_specs              | optional_extra_specs  |
 +----+--------+-----------+-----------+-----------------------------------+-----------------------+
 | 4..| my_type| private   | -         | driver_handles_share_servers:False| snapshot_support:True |
 | 5..| default| public    | YES       | driver_handles_share_servers:True | snapshot_support:True |
 +----+--------+-----------+-----------+-----------------------------------+-----------------------+

演示项目中的 demo 用户可以列出类型为 my_type,并且他不可见名为 my_type 的私有共享类型。

 $ env | grep OS_
 ...
 OS_USERNAME=demo
 OS_TENANT_NAME=demo
 ...
 $ manila type-list --all
 +----+--------+-----------+-----------+----------------------------------+----------------------+
 | ID | Name   | Visibility| is_default| required_extra_specs             | optional_extra_specs |
 +----+--------+-----------+-----------+----------------------------------+----------------------+
 | 5..| default| public    | YES       | driver_handles_share_servers:True| snapshot_support:True|
 +----+--------+-----------+-----------+----------------------------------+----------------------+

管理员可以为 demo 项目授予私有共享类型的访问权限,其项目 ID 等于 df29a37db5ae48d19b349fe947fada46:

 $ env | grep OS_
 ...
 OS_USERNAME=admin
 OS_TENANT_NAME=admin
 ...
 $ openstack project list
 +----------------------------------+--------------------+
 | ID                               | Name               |
 +----------------------------------+--------------------+
 | ...                              | ...                |
 | df29a37db5ae48d19b349fe947fada46 | demo               |
 +----------------------------------+--------------------+
 $ manila type-access-add my_type df29a37db5ae48d19b349fe947fada46

因此,演示项目 中的用户可以看到私有共享类型并在共享创建中使用:

 $ env | grep OS_
 ...
 OS_USERNAME=demo
 OS_TENANT_NAME=demo
 ...
 $ manila type-list --all
 +----+--------+-----------+-----------+-----------------------------------+-----------------------+
 | ID | Name   | Visibility| is_default| required_extra_specs              | optional_extra_specs  |
 +----+--------+-----------+-----------+-----------------------------------+-----------------------+
 | 4..| my_type| private   | -         | driver_handles_share_servers:False| snapshot_support:True |
 | 5..| default| public    | YES       | driver_handles_share_servers:True | snapshot_support:True |
 +----+--------+-----------+-----------+-----------------------------------+-----------------------+

要拒绝对指定项目的访问,可使用 manila type-access-remove <share_type> <project_id>

注意

例如,说明共享类型的目的,请考虑您有两个后端:LVM 作为公共存储,而 Ceph 作为私有存储。在这种情况下,您可以授予特定项目的访问权限,并使用 用户/组验证方法 控制访问权限。

11.10. 策略(policy)

共享文件系统服务 API 提供了基于角色的访问控制策略。这些策略决定了哪些用户可以访问某些 API,并在服务的 policy.json 文件中定义。

注意

配置文件 policy.json 可以在任何位置放置。默认预期 /var/lib/config-data/puppet-generated/manila/etc/manila/policy.json 路径。

每当向 manila 发出 API 调用时,策略引擎会使用适当的策略定义来确定可以接受调用。策略规则决定在哪些情况下允许 API 调用。当规则是空字符串: "" 时,/var/lib/config-data/puppet-generated/manila/etc/manila/policy.json 文件带有始终允许的操作的规则:"" ; 规则基于用户角色或规则;具有布尔值表达式的规则。以下是 manila 的 policy.json 文件的片段。预计会在 OpenStack 版本间进行变化。

   {
       "context_is_admin": "role:admin",
       "admin_or_owner": "is_admin:True or project_id:%(project_id)s",
       "default": "rule:admin_or_owner",
       "share_extension:quotas:show": "",
       "share_extension:quotas:update": "rule:admin_api",
       "share_extension:quotas:delete": "rule:admin_api",
       "share_extension:quota_classes": "",
   }

用户必须分配给您在策略中引用的组和角色。使用用户管理命令时,服务会自动完成。

注意

/var/lib/config-data/puppet-generated/manila/etc/manila/policy.json 的任何更改都会立即生效,这允许在 manila 运行时实施新策略。手动修改策略可能会具有意外的副作用,我们不建议这样做。Manila 不提供默认策略文件,所有默认策略都位于代码库中。您可以通过执行 manila 代码生成默认策略: oslopolicy-sample-generator --config-file=var/lib/config-data/puppet-generated/manila/manila/manila-policy-generator.conf

第 12 章 对象存储

Object Storage(swift)服务存储并通过 HTTP 检索数据。对象(数据的限制)存储在组织层次结构中,可以将其配置为提供匿名只读访问、ACL 定义的访问权限,甚至是临时访问。Swift 支持通过中间件实施的多个基于令牌的身份验证机制。

应用程序使用行业标准 HTTP RESTful API 在对象存储中存储和检索数据。后端 swift 组件遵循相同的 RESTful 模型,但一些 API(比如管理持久性)被集群保持私有。

swift 的组件属于以下主要组:

  • 代理服务
  • 身份验证服务
  • 存储服务

    • 帐户服务
    • 容器服务
    • 对象服务
Swift 网络图 1
注意

Object Storage 安装不必是面向互联网的,也可以是带有公共交换机组织内部网络部分的私有云。

12.1. 网络安全

swift 的安全强化始于网络组件安全。如需更多信息,请参阅网络章节。

为获得高可用性,rsync 协议用于在存储服务节点之间复制数据。另外,代理服务在转发客户端端点和云环境中的数据时,与存储服务通信。

注意

Swift 不使用加密或与节点间通信进行身份验证。这是因为 swift 使用原生 rsync 协议来提高性能,且不会对 rsync 通信使用 SSH。这就是您在架构图中看到私有交换机或专用网络([V]LAN)的原因。此数据区域也应与其他 OpenStack 数据网络分开。

注意

在 data 区域中,为您的存储节点使用私有(V)LAN 网络段。

这要求代理节点具有双接口(物理或虚拟):

  • 一个接口作为供消费者访问的公共接口。
  • 另一个接口作为专用接口,可访问存储节点。

下图演示了一个可能的网络架构,它通过管理节点(OSAM)使用 Object Storage 网络架构:

Swift 网络图 2

12.2. 以非 root 用户身份运行服务

建议您将 swift 配置为在非 root(UID 0)服务帐户下运行。建议是用户名 swift,其主要组 swift 是由 director 部署的主组 swift。对象存储服务包括 proxy-servercontainer-serveraccount-server

12.3. 文件权限

/var/lib/config-data/puppet-generated/swift/etc/swift/ 目录包含有关环拓扑和环境配置的信息。建议使用以下权限:

chown -R root:swift /var/lib/config-data/puppet-generated/swift/etc/swift/*
find /var/lib/config-data/puppet-generated/swift/etc/swift/ -type f -exec chmod 640 {} \;
find /var/lib/config-data/puppet-generated/swift/etc/swift/ -type d -exec chmod 750 {} \;

这个限制仅允许 root 修改配置文件,同时仍然允许服务读取它们,而 由于其在 swift 组中成员资格。

12.4. 保护存储服务

以下是各种存储服务的默认监听端口:

  • 帐户服务 - TCP/6002
  • 容器化服务 - TCP/6001
  • Object Service - TCP/6000
  • Rsync - TCP/873
注意

如果使用 ssync 而不是 rsync,则对象服务端口用于维护持久性。

注意

存储节点上不会发生身份验证。如果您可以在其中一个端口上连接到存储节点,您可以在无需身份验证的情况下访问或修改数据。为了帮助缓解这个问题,您应该遵循之前使用私有存储网络给出的建议。

12.5. Object Storage 帐户术语

swift 帐户不是用户帐户或凭证。存在以下区别:

  • Swift 帐户 - 容器(非用户帐户或身份验证)的集合。您使用的验证系统决定了哪个用户与帐户相关联,以及它们如何访问它。
  • Swift 容器 - 对象的集合。容器的元数据可用于 ACL。ACL 的使用取决于所使用的身份验证系统。
  • Swift 对象 - 实际的数据对象。对象级别的 ACL 也通过元数据提供,它们取决于所使用的身份验证系统。

在每个级别上,您都有控制用户访问的 ACL;ACL 根据使用的验证系统解释。最常见的身份验证提供程序类型是 Identity Service(keystone);自定义身份验证提供程序也可用。

12.6. 保护代理服务

代理节点应该至少有一个接口(物理或虚拟):一个公共节点和一个私有。您可以使用防火墙或服务绑定来帮助保护公共接口。面向公众的服务是处理端点客户端请求的 HTTP Web 服务器,对它们进行身份验证,并执行适当的操作。专用接口不需要任何监听服务,而是用来建立到私有存储网络上的存储节点的传出连接。

12.7. HTTP 侦听端口

director 将 Web 服务配置为在非 root 用户(无 UID 0)用户下运行。使用大于 1024 的端口号有助于避免以 root 身份运行任何部分 web 容器。通常,使用 HTTP REST API(和执行自动身份验证)的客户端将从身份验证响应中检索所需的完整 REST API URL。OpenStack REST API 允许客户端对一个 URL 进行身份验证,然后重定向到将完全不同的 URL 用于实际服务。例如,客户端可以向 https://identity.cloud.example.org:55443/v1/auth 验证,并通过其身份验证密钥和存储 URL(代理节点的 URL 或负载均衡器)得到响应 https://swift.cloud.example.org:44443/v1/AUTH_8980

12.8. 负载均衡器

如果无法使用 Apache 的 选项,或者希望卸载 TLS 工作的性能,则可能使用专用的网络设备负载均衡器。这是使用多个代理节点时提供冗余和负载均衡的通用方法。

如果选择卸载 TLS,请确保负载均衡器和代理节点之间的网络链接位于私有(V)LAN 片段中,因此网络中的其他节点(可能被破坏)无法有线tap(侦听)加密流量。如果发生此类漏洞,攻击者可以获得对端点客户端或云管理员凭证的访问并访问云数据。

您使用的身份验证服务将决定如何将响应中的不同 URL 配置为端点客户端,从而允许它们使用负载均衡器而不是单独的代理节点。

12.9. 对象存储身份验证

Object Storage(swift)使用 WSGI 模型提供中间件功能,它不仅提供一般可扩展性,还用于对端点客户端进行身份验证。身份验证提供程序定义存在哪些角色和用户类型。有些人使用传统用户名和密码凭证,另一些可能会利用 API 密钥令牌,甚至利用客户端 X.509 证书。自定义提供程序可以使用自定义中间件集成。

对象存储默认附带两个身份验证中间件模块,其中任一个模块可用作开发自定义身份验证中间件的示例代码。

12.10. 加密 at-rest swift 对象

Swift 可以和 Barbican 集成,以透明地加密和解密您的存储(at-rest)对象。at-rest 加密与传输加密不同,并引用在磁盘上加密的对象。

Swift 以透明方式执行这些加密任务,对象在上传到 swift 时自动加密,然后在提供给用户时自动解密。此加密和解密使用相同(symmetric)密钥进行,该密钥存储在 Barbican 中。

如需更多信息,请参阅 Barbican 集成指南: https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/16.2/html-single/manage_secrets_with_openstack_key_manager/

12.11. 其他项目

在每个节点中的 /var/lib/config-data/puppet-generated/swift/etc/swift/swift.conf 中,都有一个 swift_hash_path_prefix 设置和 swift_hash_path_suffix 设置。提供的是减少存储对象的哈希冲突的机会,并会验证一个用户覆盖另一个用户的数据的几率。

这个值最初应该使用加密随机数字生成器设置,并在所有节点上保持一致性。确保通过正确的 ACL 保护,并且您有备份副本以避免数据丢失。

第 13 章 监控和日志记录

日志管理是监控 OpenStack 部署安全状态的重要组件。日志除组成 OpenStack 部署的组件活动外,还对 BAU 对管理员、项目和实例的操作提供深入了解。

日志不仅有助于主动的安全和持续合规活动,而且也是调查和事件响应的宝贵信息来源。例如,分析 keystone 访问日志可能会提醒您失败的登录、它们频率、原始 IP 以及事件是否限制为选择帐户,等等。

director 包括使用 AIDE 的入侵检测功能,以及 keystone 的 CADF 审计。如需更多信息,请参阅 director 强化章节。

13.1. 强化监控基础架构

集中式日志记录系统是入侵者的高价值目标,因为成功入侵可能会允许它们清除或修改事件记录。建议您使用以下命令强化监控平台。此外,请考虑为这些系统进行定期备份,并在出现停机或 DoS 时进行故障转移规划。

13.2. 要监控的事件示例

事件监控是一种更加主动的方法来保护环境,提供实时检测和响应。存在多个可以协助监控的工具。对于 OpenStack 部署,您需要监控硬件、OpenStack 服务和云资源的使用情况。

本节论述了您可能需要了解的一些示例事件。

重要

此列表不详细。您需要考虑额外的用例,这些用例可能适用于您的特定网络,并且您可能会考虑行为。

  • 检测没有日志生成情况是高值。这种差距可能表示服务故障,甚至是临时关闭日志记录或修改日志级别以隐藏其跟踪的入侵者。
  • 应用程序事件(如启动或停止事件)可能具有可能的安全影响。
  • OpenStack 节点上的操作系统事件,如用户登录或重启。这为区分正确和不正确的系统使用提供了宝贵的见解。
  • 网络桥接关闭。这可能是因为服务中断风险而导致的一个可操作事件。
  • iptables 刷新 Compute 节点上的事件,并最终无法访问实例。

为了减少来自用户、项目或域删除的用户、项目或域删除的安全风险,讨论要在系统中生成通知,并让 OpenStack 组件根据需要响应这些事件,如终止实例、断开已连接的卷、回收 CPU 和存储资源等。

安全监控可控制入侵检测软件、防病毒软件以及复制软件检测和删除实用程序可生成显示何时以及如何进行攻击或入侵所经过的日志。这些工具可在 OpenStack 节点上部署时提供一层保护。项目用户可能还想在其实例上运行此类工具。

第 14 章 项目的数据隐私

OpenStack 旨在支持具有不同数据要求的项目之间的多租户。云操作员需要考虑其适用的数据隐私问题和法规。本章解决了对于 OpenStack 部署的数据驻留和处理的问题。

14.1. 数据所在

数据隐私和隔离始终被认为是过去几年间采用云的主要障碍。对于拥有云端数据以及云操作员是否最终可以信任此数据的人员担心,过去一直都存在大量问题。

某些 OpenStack 服务可以访问属于项目或引用项目信息的数据和元数据。例如,存储在 OpenStack 云中的项目数据可能包括以下项目:

  • 对象存储对象。
  • 计算实例临时文件系统存储.
  • 计算实例内存.
  • 块存储卷数据。
  • 用于计算访问的公钥。
  • 镜像服务中的虚拟机镜像。
  • 实例快照.
  • 传递给计算配置驱动器扩展的数据。

由 OpenStack 云存储的元数据包括以下项目(此列表不是行为):

  • 组织名称。
  • 用户的"重命名"。
  • 正在运行的实例、存储桶、对象、卷和其他配额相关项目的数量或大小。
  • 运行实例或存储数据的小时数。
  • 用户的 IP 地址。
  • 用于计算镜像捆绑的内部生成私钥。

14.2. 数据处理

良好的实践建议,Operator 必须清理云系统介质(数字和非位),然后再发布机构控制前,或发布才可以重复使用。清理方法应该根据具体的安全域和敏感程度实施适当的强度和完整性。

注意

NIST Special Publication 800-53 Revision 4 在此主题上使用一个特定视图:

The sanitization process removes information from the media such that the information cannot be retrieved or reconstructed. Sanitization techniques, including clearing, purging, cryptographic erase, and destruction, prevent the disclosure of information to unauthorized individuals when such media is reused or released for disposal.

当开发常规数据处理和清理指南时,云操作员应考虑以下几点(根据 NIST 建议的安全控制所示):

  • 跟踪、文档和验证媒体清理和处理操作。
  • 测试完整性设备和程序以验证正确性能。
  • 在将这些设备连接到云基础架构之前,清除可移植、可移动存储设备。
  • 销毁无法清理的云系统介质。

因此,OpenStack 部署需要解决以下做法(其它操作):

  • 安全数据评分
  • 实例内存清理
  • 块存储卷数据
  • 计算实例临时存储
  • 裸机服务器清理

14.2.1. 未安全地清除数据

在 OpenStack 中,可能会删除一些数据,但无法在上述 NIST 标准上下文中安全地清除。这通常适用于存储在数据库中的最大或全部定义元数据和信息。这可通过数据库和/或系统配置自动清空和定期免费空间修复。

14.2.2. 实例内存清理

特定于各种虚拟机监控程序是实例内存的处理。此行为在 Compute 中不定义,但一般情况下,管理程序通常是在实例创建时、创建或两者时清理内存的最佳努力。

14.3. 加密 Cinder 卷数据

强烈建议使用 OpenStack 卷加密功能。这在卷加密下的数据加密部分中对此进行讨论。使用此功能时,通过安全地删除加密密钥来完成数据破坏性。最终用户可以在创建卷时选择此功能,但请注意,管理员必须首先执行一组卷加密功能。

如果没有使用 OpenStack 卷加密功能,那么通常更难以启用其他方法。如果使用了后端插件,则可能存在独立加密的方法或非标准覆盖解决方案。OpenStack Block Storage 的插件以各种方式存储数据。许多插件特定于某个厂商或技术,另一些则更围绕文件系统(比如 LVM 或 ZFS)有关。安全销毁数据的方法因插件、供应商和文件系统而异。

有些后端(如 ZFS)支持写时复制以防止数据暴露。在这些情况下,从未写入的块读取总是返回零。其他后端(如 LVM)可能无法原生支持,因此 cinder 插件会接管在将之前写入的块传递给用户前覆盖之前写入的块。务必要检查您选择的卷后端提供的保障,并查看哪些补救可能可用于这些保证。

14.4. 镜像服务延迟删除功能

镜像服务具有延迟删除功能,这会在定义的时间段内删除镜像。如果此行为是安全问题,请考虑禁用此功能;您可以通过编辑 glance-api.conf 文件并将 latency _delete 选项设置为 False 来执行此操作。

14.5. 计算软删除功能

计算具有软删除功能,它允许在指定的时间间隔内删除的实例处于软删除状态。在此时间段内可以恢复该实例。要禁用 soft-delete 功能,请编辑 /var/lib/config-data/puppet-generated/nova_libvirt/etc/nova/nova.conf 文件并保留 reclaim_instance_interval 选项为空。

14.6. 裸机置备的安全强化

对于裸机置备基础架构,您应该考虑安全地强化基板管理控制器(BMC),特别是 IPMI。例如,您可以在 provisioning 网络中隔离这些系统,配置非默认密码和强大的密码,以及禁用不需要的管理功能。如需更多信息,请参阅供应商有关安全强化这些组件的指导。

注意

如果可能,请考虑评估基于 Redfish 的 BMC。

14.7. 硬件识别

在部署服务器时,可能并非始终有可靠的方法将其与攻击者的服务器区分开来。该功能可能依赖于硬件/BMC 到一定程度,但通常似乎没有可识别服务器中的识别方式。

14.8. 数据加密

存在该选项用于对存储在磁盘上或通过网络传输的项目数据进行加密,如下面的 OpenStack 卷加密功能。这超出了用户在将自己的数据发送到其供应商前加密自己的数据的一般建议。

代表项目加密数据的重要性与攻击者可以访问项目数据的供应商所认为的风险至关重要。在政府中,以及专用合同中的要求,甚至根据公共云供应商提供私有合同的法律要求。在选择项目加密策略前,请考虑获得风险评估和法律建议。

按实例或每个对象加密优先于项目、按项目、每个主机和按云聚合的降序。本建议对实施的复杂性和难度感兴趣。目前,在某些项目中,难以实施加密,因为每个项目甚至无法进行精细。实施者应考虑加密项目数据。

通常,数据加密可能会积极地通过丢弃密钥来可靠地销毁项目和每个实例的数据。请注意,在这样做时,以安全方式销毁这些密钥会变得非常大。

向用户对数据进行加密的机会:

  • Object Storage 对象
  • 网络信息

14.8.1. 卷加密

OpenStack 中的卷加密功能支持基于每个项目的隐私。支持以下功能:

  • 通过仪表板或命令行界面发起的加密卷类型创建和使用
  • 启用加密并选择参数,如加密算法和密钥大小
  • iSCSI 数据包中包含的卷数据已被加密
  • 如果原始卷加密,支持加密备份
  • 仪表板显示卷加密状态。包括表示卷已加密,并包含加密参数,如算法和密钥大小
  • 带有密钥管理服务的接口

14.8.2. Object Storage 对象

Object Storage(swift)支持在存储节点上静态对对象数据进行可选加密。对象数据的加密旨在降低所读取用户数据的风险,如果未经授权方获得对磁盘的物理访问权限。

静态数据加密由中间件(可能包含在代理服务器 WSGI 管道)实现。该功能是 swift 集群的内部,无法通过 API 公开。客户端不知道数据由此功能加密到 swift 服务;内部加密的数据应不会通过 swift API 向客户端返回。

在 swift 中静态时加密了以下数据:

  • 对象内容,如对象 PUT 请求正文的内容。
  • 具有非零内容的对象实体标签(ETag)。
  • 所有自定义用户对象元数据值。例如,使用 X-Object-Meta- 前缀的标头和 PUT 请求发送的元数据。

任何不包括在以上列表中的数据或元数据都不会加密,其中包括:

  • 帐户、容器和对象名称
  • 帐户和容器自定义用户元数据值
  • 所有自定义用户元数据名称
  • 对象内容类型值
  • 对象大小
  • 系统元数据

14.8.3. 块存储性能和后端

启用操作系统时,您可以使用 Intel 和 AMD 处理器中提供的硬件加速功能来提高 OpenStack 卷加密性能。

OpenStack 卷加密功能在主机上使用 dm-crypt,或者原生 QEMU 加密支持来保护卷数据。红帽建议您在创建加密卷时使用 LUKS 卷加密类型。

14.8.4. 网络信息

Compute 节点的项目数据可以通过 IPsec 或其他隧道加密。这种做法在 OpenStack 中不是常见或标准,而是可用于进取和感兴趣的实施者。同样,加密的数据仍保持加密,因为它通过网络传输。

14.9. 密钥管理

为了解决对项目数据隐私的经常提到的问题,OpenStack 社区中对大量兴趣,使数据加密更普遍。在将数据保存到云之前,最终用户更容易对其进行加密,这是项目对象(如媒体文件、数据库存档等)的可行路径。在某些情况下,客户端加密用于加密虚拟化技术保留的数据,这些数据需要客户端交互(如展示密钥)来解密数据以供将来使用。

Barbican 可以帮助项目无缝地加密数据,并使数据在无需使用密钥管理负担的情况下进行访问。提供加密和密钥管理服务作为 OpenStack 易于数据采用的一部分,可帮助客户解决有关隐私或滥用数据的问题。

卷加密功能依赖于密钥管理服务,如密钥管理器服务(barbican),用于创建和强化密钥的存储。

第 15 章 管理实例安全性

在虚拟环境中运行实例的好处之一是安全控制在部署到裸机时通常不可用的新机会。某些技术可以应用到虚拟化堆栈,为 OpenStack 部署带来更高的信息保障。具有强安全要求的 Operator 可能需要考虑部署这些技术,但并非所有情况都适用。在某些情况下,由于指定业务要求,技术可能会排除在云中使用。同样,一些技术会检查实例数据,如运行状态,这可能会对系统的用户造成意外影响。

本章介绍了这些技术以及可用于帮助提高实例或底层节点的安全性的情况。另外还会突出显示可能的隐私问题,其中包括数据直通、内省或熵源。

15.1. 为实例提供熵

熵指的是可供实例使用的随机数据的质量和源。加密技术通常依赖于随机性,这需要从熵池中提取。当实例无法获得足够的熵来支持加密技术所需的随机性时,会出现熵性。熵星号可以在实例中进行清单,因为看似不相关。例如,启动速度缓慢时可能是由实例等待 SSH 密钥生成造成的。熵星星的可能性还可增加云用户使用实例内部的质量熵源,从而降低在云中运行的应用程序的安全性。

要为实例提供高质量的熵源,您需要在云中有足够的硬件随机数字生成器(HRNG)来支持实例。对于日常操作,现代 HRNG 可以生成足够的熵来支持 50-100 Compute 节点。高带宽 HRNG 可以处理更多节点。您必须识别云的应用程序要求,以确保有足够的熵。

VirtIO RNG 是一个随机数字生成器,默认使用 /dev/urandom 作为熵的来源,以确保实例不会在引导时出现熵。它还可将其配置为使用 HRNG,或者是熵收集守护进程(EGD)等工具,提供了一种通过部署来分发熵的方法。对于实例,默认启用 virtio RNG 设备。要禁用实例的 Virtio RNG 设备,您必须在实例类型上将 hw_rng:allowed 设为 False

15.2. 将实例调度到节点

在创建实例之前,必须先选择用于镜像实例化的主机。此选择由 nova-scheduler 执行,它决定了如何分配计算和卷请求。

FilterScheduler 是计算的默认调度程序,但存在其他调度程序。该功能适用于与 过滤器提示 协作,以确定实例应启动的位置。通过这种主机选择过程,管理员可以满足许多不同的安全性和合规性要求。如果数据隔离是主要关注点,您可以选择在可能的情况下让项目实例驻留在同一主机上。相反,您可以尝试让实例位于尽可能多的不同主机上,因为可用性或容错原因。

过滤调度程序在以下主要类别下:

  • 基于资源过滤器 - 根据虚拟机监控程序主机集的系统资源使用情况确定实例的放置,并可在空闲或已用属性(如 RAM、IO 或 CPU 使用率)上触发。
  • 基于镜像的过滤器 - 根据所使用的镜像元数据(如虚拟机的操作系统或所用镜像类型)删除实例创建。
  • 基于环境过滤 - 确定实例基于外部详情的放置,如特定 IP 范围、跨可用区或在与另一个实例相同的主机上。
  • 自定义标准 - 根据用户或管理员提供的标准(如信任或元数据解析)来隔离实例创建。

可以同时应用多个过滤器。例如,ServerGroupAffinity 过滤器检查是否在一组特定主机的成员上创建实例,并且 ServerGroupAntiAffinity 过滤器检查没有在另一特定的主机集合中创建同一实例。请注意,这两个过滤器通常同时是启用的,且在每次检查给定属性值时不能相互冲突,并且同时不能两者都为 true。

filteringWorkflow1
重要

考虑禁用用于解析用户提供的对象的过滤器,或者可以操作(如元数据)。

15.3. 使用可信镜像

在云环境中,用户操作预装的镜像或其上传自身的镜像。在这两种情况下,用户应该能够确保所使用的镜像没有被篡改。验证镜像的功能是安全的基础。需要一个信任链,从镜像源到使用它的目的地。这可以通过签名从可信源获取的镜像,并在使用前验证签名来实现。下面将讨论获取和创建验证的镜像的各种方法,并附带对镜像签名验证功能的描述。

15.4. 创建镜像

OpenStack 文档提供了如何创建和上传镜像到镜像服务的指导。另外,假设您已有一个安装并强化客户端操作系统的过程。以下项目将提供如何将镜像传输到 OpenStack 的额外指导。有各种选项来获取镜像。每种方法均有特定的步骤,可以帮助验证镜像的验证。

  • 选项 1: 来自可信源的启动介质。例如,您可以从官方红帽源下载镜像,然后执行额外的 checksum 验证。
  • 选项 2: 使用 OpenStack 虚拟机镜像指南.在这种情况下,您需要遵循您的机构 OS 强化指南。
  • 选项 3:使用自动镜像构建器。以下示例使用 Oz 镜像构建程序。OpenStack 社区最近创建了名为 disk-image-builder 的新工具,它尚未进入安全评估。

在这个示例中,RHEL 6 CCE-26976-1 帮助在 Oz 中实施 NIST 800-53 第 AC-19(d)。

<template>
<name>centos64</name>
<os>
  <name>RHEL-6</name>
  <version>4</version>
  <arch>x86_64</arch>
  <install type='iso'>
  <iso>http://trusted_local_iso_mirror/isos/x86_64/RHEL-6.4-x86_64-bin-DVD1.iso</iso>
  </install>
  <rootpw>CHANGE THIS TO YOUR ROOT PASSWORD</rootpw>
</os>
<description>RHEL 6.4 x86_64</description>
<repositories>
  <repository name='epel-6'>
  <url>http://download.fedoraproject.org/pub/epel/6/$basearch</url>
  <signed>no</signed>
  </repository>
</repositories>
<packages>
  <package name='epel-release'/>
  <package name='cloud-utils'/>
  <package name='cloud-init'/>
</packages>
<commands>
  <command name='update'>
  yum update
  yum clean all
  sed -i '/^HWADDR/d' /etc/sysconfig/network-scripts/ifcfg-eth0
  echo -n > /etc/udev/rules.d/70-persistent-net.rules
  echo -n > /lib/udev/rules.d/75-persistent-net-generator.rules
  chkconfig --level 0123456 autofs off
  service autofs stop
  </command>
</commands>
</template>

请考虑避免手动镜像构建过程,因为它比较复杂且容易出错。另外,使用 Oz 等自动系统进行镜像构建,或用于引导镜像强化的配置管理实用程序(如 Chef 或 Puppet),使您能够生成一致的镜像,以及追踪一段时间内对基础镜像的合规性。

如果订阅公共云服务,您应该对云供应商进行检查,以了解用于生成其默认镜像的流程。如果该供应商允许您上传自己的镜像,则需要确保在使用该实例创建实例前验证您的镜像没有被修改。为此,请参考 _ 验证镜像签名_ 或以下段落(如果无法使用)上的以下部分。

Image Service(glance)用于将镜像上传到节点上的 Compute 服务。这种传输应该通过 TLS 进一步强化。当镜像位于节点上后,它会使用基本的 checksum 进行检查,然后根据要启动实例的大小扩展其磁盘。如果以后启动具有相同实例大小的镜像,则会从同一扩展的镜像启动。由于此扩展的镜像在启动前默认不会被重新验证,因此存在存在异常篡改的风险。除非对生成的镜像执行手动检查,否则用户将不会了解篡改。要缓解此问题,请查看验证镜像签名主题的以下部分。

15.5. 验证镜像签名

您可以启用镜像签名验证,以确保镜像服务(glance)镜像不会在 Compute 服务(nova)启动实例前不包含未经授权的更改。启用此功能后,您可以防止新实例启动,其中可能包括恶意软件或安全漏洞。

流程

  1. 在 heat 模板中,通过将 True 设置为 VerifyGlanceSignatures 参数来启用实例签名验证:

    parameter_defaults:
        VerifyGlanceSignatures: True
  2. 确保 openstack overcloud deploy 脚本中包含了用于修改 VerifyGlanceSignatures 参数的模板,并重新运行 deploy 脚本。
注意

如果您使用没有签名的镜像创建实例,则镜像无法验证,实例也不会启动。有关签名镜像的更多信息,请参阅 签署镜像服务镜像

15.6. 迁移实例

OpenStack 和底层虚拟化层为 OpenStack 节点之间的镜像实时迁移提供,以便您无缝执行 Compute 节点的滚动升级,而无需实例停机。但是,实时迁移也会存在很大的风险。要了解涉及的风险,以下是实时迁移过程中执行的高级步骤:

  1. 在目标主机上启动实例
  2. 传输内存
  3. 停止客户机和同步磁盘
  4. 传输状态
  5. 启动客户端
注意

某些操作(如冷迁移、调整大小和 shelve)都可能导致部分数量的实例数据传输给其他服务,等等。

15.6.1. 实时迁移风险

在实时迁移过程的各个阶段,实例的运行时间内存和磁盘的内容将以纯文本形式通过网络传输。因此,在使用实时迁移时需要解决多个风险。以下非行为列表详细介绍了其中的一些风险:

  • 拒绝服务(DoS):如果迁移过程中出现失败,则实例可能会丢失。
  • 数据风险:必须安全地处理内存或磁盘传输。
  • 数据操作:如果不安全地处理内存或磁盘传输,则攻击者可在迁移期间操作用户数据。
  • 代码注入:如果不安全地处理内存或磁盘传输,则攻击者可以在迁移期间在磁盘或内存中操作可执行文件。

15.6.2. 禁用实时迁移

目前,OpenStack 中默认启用实时迁移。实时迁移默认为仅管理的任务,因此用户无法启动此操作,只有管理员(可能值得信任)。可以通过将以下行添加到 nova policy.json 文件来禁用实时迁移:

"compute_extension:admin_actions:migrate": "!",
"compute_extension:admin_actions:migrateLive": "!",

另外,当阻止 TCP 端口 4915249261 时,实时迁移应该会失败,或者确保 nova 用户在计算主机之间没有免密码 SSH 访问。

请注意,实时迁移的 SSH 配置已显著降低:创建新用户(nova_migration)和 SSH 密钥仅限于该用户,且仅适用于允许的网络。然后,打包程序脚本会限制可以运行的命令(例如,在 libvirt 套接字上的 netcat)。

15.6.3. 加密的实时迁移

实时迁移流量以纯文本形式传输正在运行的实例的磁盘和内存内容,目前默认托管在内部 API 网络中。

如果有足够的要求(如升级)以保持实时迁移,则 libvirtd 可以为实时迁移提供加密的隧道。但是,这个功能没有在 OpenStack Dashboard 或 nova-client 命令中公开,只能通过手动配置 libvirtd 访问。然后,实时迁移过程会更改为以下高级别的步骤:

  1. 实例数据从虚拟机监控程序复制到 libvirtd。
  2. 在源和目标主机上的 libvirtd 进程间创建一个加密的隧道。
  3. 目标 libvirtd 主机将实例复制回底层虚拟机监控程序。
注意

对于 Red Hat OpenStack Platform 13,建议的方法是使用隧道的迁移,在将 Ceph 用作后端时默认启用。如需更多信息,请参阅 https://docs.openstack.org/nova/queens/configuration/config.html#libvirt.live_migration_tunnelled

15.7. 监控、警报和报告

实例是可以在主机之间复制的服务器镜像。因此,最好在物理和虚拟主机之间应用日志记录。应记录操作系统和应用程序事件,包括访问主机和数据的事件、用户添加和删除、权限更改等。考虑将结果导出到用于收集日志消息的日志聚合器,与它们相关联以进行分析,并存储它们供参考或进一步操作。一个用于执行此操作的通用工具是 ELK 堆栈,或 Elasticsearch、Logstash 和 Kibana。

注意

这些日志应定期检查,甚至在网络运营中心(NOC)执行的实时视图中检查。

您需要进一步确定哪个事件将触发后续发送到响应者发出的警报。

如需更多信息,请参阅 监控工具配置指南

15.8. 更新和补丁

虚拟机监控程序运行独立的虚拟机。该管理程序可以在操作系统或直接在硬件上运行(称为裸机)。对虚拟机监控程序的更新不会传播到虚拟机。例如,如果部署正在使用 KVM 且包含一组 CentOS 虚拟机,则 KVM 的更新不会更新在 CentOS 虚拟机上运行的任何内容。

考虑将虚拟机的明确所有权分配给所有者,然后负责虚拟机的强化、部署和持续功能。您还应该有一个计划定期部署更新,同时首先在类似于生产环境的环境中进行测试。

15.9. 防火墙和实例配置集

最常见的操作系统包括基于主机的防火墙,用于额外的安全层。虽然实例应该尽可能少地运行一些应用程序(在成为单用途实例的情况下,如果可能),应对实例上运行的所有应用进行性能分析,以确定应用程序需要访问的系统资源、运行所需特权的最低级别,以及预期网络流量将到达虚拟机并进出虚拟机。这个预期流量应作为允许流量添加到基于主机的防火墙中,以及任何必要的日志记录和管理通信(如 SSH 或 RDP)。防火墙配置中应明确拒绝所有其他流量。

在 Linux 实例上,上面的应用程序配置集可以与 audit2allow 等工具一起使用,以进一步保护大多数 Linux 发行版上的敏感系统信息。SELinux 结合使用用户、策略和安全上下文来划分应用程序运行所需的资源,并从不需要的其他系统资源进行分段。

注意

Red Hat OpenStack Platform 默认启用 SELinux,其策略是为 OpenStack 服务自定义的。必要时,请定期查阅这些警察。

15.10. 安全组

OpenStack 为主机和网络提供了安全组,以便向给定项目中的实例添加防御。它们与基于主机的防火墙类似,因为它们可根据端口、协议和地址允许或拒绝传入的流量。但是,安全组规则仅应用于传入流量,而基于主机的防火墙规则可以应用于传入和传出流量。主机和网络安全组规则也可以发生冲突并拒绝合法流量。考虑检查是否为正在使用的网络正确配置了安全组。详情请查看本指南中的安全组。

注意

除非特别需要禁用,否则应保持安全组和端口安全性启用。要根据防御方法进行构建,建议您将粒度规则应用到实例。

15.11. 访问实例控制台

默认情况下,可以通过虚拟控制台远程访问实例的控制台。这对故障排除非常有用。Red Hat OpenStack Platform 使用 VNC 进行远程控制台访问。

  • 考虑使用防火墙规则锁定 VNC 端口。默认情况下,nova_vnc_proxy 使用 608013080
  • 确认 VNC 流量由 TLS 加密。对于基于 director 的部署,请从 UseTLSTransportForVnc 开始。

15.12. 证书注入

如果需要通过 SSH 连接到您的实例,您可以将 Compute 配置为在创建时自动将所需的 SSH 密钥注入到实例中。

如需更多信息,请参阅 创建镜像

第 16 章 排队

排队服务可促进 OpenStack 中的进程间通信。这可使用这些消息排队服务后端实现:

  • RabbitMQ - Red Hat OpenStack Platform 默认使用 RabbitMQ。
  • Qpid

RabbitMQ 和 Qpid 都是高级消息队列协议(AMQP)框架,为对等通信提供消息队列。队列实施通常部署为集中或分散队列服务器池。

消息队列有效促进 OpenStack 部署中的命令和控制功能。允许访问队列后,不会执行进一步的授权检查。队列可以访问的服务验证实际消息有效负载中的上下文和令牌。但是,您必须注意令牌的过期日期,因为令牌可能会重新使用,并可以授权基础架构中其他服务。

OpenStack 不支持消息级信任,如消息签名。因此,您必须保护并验证消息传输本身。对于高可用性(HA)配置,您必须执行队列到队列的身份验证和加密。

16.1. 消息传递传输安全性

基于 AMQP 的解决方案(Qpid 和 RabbitMQ)支持使用 TLS 的传输级安全性。

考虑为您的消息队列启用传输级别加密。使用 TLS 进行消息传递客户端连接可以保护来自篡改并丢弃至消息传递服务器的通信。以下提供了 TLS 通常如何为两个常见消息传递服务器配置 TLS: Qpid 和 RabbitMQ。当配置消息传递服务器用来验证客户端连接的可信证书颁发机构(CA)捆绑包时,建议仅限制用于您的节点的 CA,最好是内部管理的 CA。可信 CA 的捆绑包将决定哪个客户端证书会被授权,并传递设置 TLS 连接中的客户端-服务器验证步骤。

注意

安装证书和密钥文件时,请确保文件权限受限(例如使用 chmod 0600 ),并且所有权仅限于消息传递服务器守护进程用户,以防止消息传递服务器上的其他进程和用户未经授权的访问。

16.1.1. RabbitMQ 服务器 SSL 配置

以下行应添加到系统范围的 RabbitMQ 配置文件中,通常为 /etc/rabbitmq/rabbitmq.config

[
  {rabbit, [
     {tcp_listeners, [] },
     {ssl_listeners, [{"<IP address or hostname of management network interface>", 5671}] },
     {ssl_options, [{cacertfile,"/etc/ssl/cacert.pem"},
                    {certfile,"/etc/ssl/rabbit-server-cert.pem"},
                    {keyfile,"/etc/ssl/rabbit-server-key.pem"},
                    {verify,verify_peer},
                    {fail_if_no_peer_cert,true}]}
   ]}
].
注意

tcp_listeners 选项被设置为 [],以防止其在非 SSL 端口上侦听。ssl_listeners 选项应限制为仅侦听服务的管理网络。

16.2. 队列身份验证和访问控制

RabbitMQ 和 Qpid 提供身份验证和访问控制机制来控制对队列的访问。

简单验证和安全层(SASL)是一个在互联网协议中用于身份验证和数据安全的框架。RabbitMQ 和 Qpid 均提供 SASL 和其他插入式验证机制,使其比简单用户名和密码以外,从而提高安全性。虽然 RabbitMQ 支持 SASL,OpenStack 中的支持目前不允许请求特定 SASL 身份验证机制。OpenStack 中的 RabbitMQ 支持允许通过未加密的连接或用户名和密码与 X.509 客户端证书建立安全 TLS 连接的用户名和密码。

考虑在所有 OpenStack 服务节点上配置 X.509 客户端证书,以便客户端连接到消息传递队列,并在可能的情况下(目前只有 Qpid)对 X.509 客户端证书进行身份验证。使用用户名和密码时,应为每个服务和节点创建帐户,以便精细的审计对队列的访问。

在部署前,请考虑排队服务器使用的 TLS 库。Qpid 使用 Mozilla 的 NSS 库,而 RabbitMQ 使用 Erlang 的 TLS 模块,它使用 OpenSSL。

16.3. RabbitMQ 的 OpenStack 服务配置

本节描述了 OpenStack 服务的典型 RabbitMQ 配置:

[DEFAULT]
rpc_backend = nova.openstack.common.rpc.impl_kombu
rabbit_use_ssl = True
rabbit_host = RABBIT_HOST
rabbit_port = 5671
rabbit_user = compute01
rabbit_password = RABBIT_PASS
kombu_ssl_keyfile = /etc/ssl/node-key.pem
kombu_ssl_certfile = /etc/ssl/node-cert.pem
kombu_ssl_ca_certs = /etc/ssl/cacert.pem
注意

使用合适的密码替换 RABBIT_PASS

16.4. Qpid 的 OpenStack 服务配置

本节介绍 OpenStack 服务的典型 Qpid 配置:

[DEFAULT]
rpc_backend = nova.openstack.common.rpc.impl_qpid
qpid_protocol = ssl
qpid_hostname = <IP or hostname of management network interface of messaging server>
qpid_port = 5671
qpid_username = compute01
qpid_password = QPID_PASS
注意

使用合适的密码替换 QPID_PASS

另外,如果将 SASL 与 Qpid 搭配使用(可选)指定使用 SASL 的机制:

qpid_sasl_mechanisms = <space separated list of SASL mechanisms to use for auth>

16.5. 消息队列进程隔离和策略

每个项目提供许多服务来发送和接收消息。发送消息的每个二进制都应在队列中仅回复时使用消息。

消息队列服务进程应该相互隔离,以及计算机上的其他进程。

16.6. 命名空间

Linux 使用命名空间将进程分配到独立的域。本指南的其他部分将更详细地阐述系统划分。

第 17 章 保护 Red Hat OpenStack Platform 中的端点

与 OpenStack 云互动的过程从查询 API 端点开始。虽然公共端点和私有端点面临不同的挑战,但有高价值资产在被入侵时可能会带来很大的风险。

本章为面向公共和面向私有的 API 端点建议安全增强。

17.1. 内部 API 通信

OpenStack 提供面向公共的内部管理员和私有 API 端点。默认情况下,OpenStack 组件使用公开定义的端点。建议将这些组件配置为在正确的安全域中使用 API 端点。内部管理端点允许进一步对 keystone 的访问,因此可能最好进一步隔离该问题。

服务根据 OpenStack 服务目录选择其各自的 API 端点。这些服务可能无法遵循列出的公共或内部 API 端点值。这可能会导致内部管理流量路由到外部 API 端点。

17.2. 在 Identity service catalog 中配置内部 URL

Identity 服务目录应该了解您的内部 URL。虽然默认情况下不使用此功能,但可以通过 配置提供。另外,在此行为变为默认值后,它应该与预期更改一致。

考虑将配置的端点与网络级别隔离,因为它们具有不同的访问权限级别。Admin 端点设计为供云管理员访问,因为它提供对内部或公共端点上不可用的 keystone 操作升级的访问。内部端点设计为使用内部到云(如 OpenStack 服务),并且通常无法在部署网络外访问。公共端点应启用了 TLS,而部署之外,供云用户对其操作的 API 端点。

director 会自动注册端点的内部 URL。如需更多信息,请参阅 https://github.com/openstack/tripleo-heat-templates/blob/a7857d6dfcc875eb2bc611dd9334104c18fe8ac6/network/endpoints/build_endpoint_map.py

17.3. 为内部 URL 配置应用程序

您可以强制某些服务使用特定的 API 端点。因此,建议任何与另一个服务的 API 联系的 OpenStack 服务都必须明确配置,以访问正确的内部 API 端点。

每个项目可能会存在不一致的方式来定义目标 API 端点。未来的 OpenStack 版本试图通过一致地使用 Identity 服务目录来解决这些不一致。

17.4. 粘贴和中间件

OpenStack 中的大多数 API 端点和其他 HTTP 服务都使用 Python Paste Deploy 库。从安全视角,这个库启用了通过应用程序的配置来操作请求过滤器管道。这个链中的每个元素都被称为中间件。在管道中更改过滤器顺序或添加额外的中间件可能会对安全造成无法预计的安全影响。

通常,实施者添加中间件以扩展 OpenStack 的基本功能。考虑在 HTTP 请求管道中添加非标准软件组件而带来的潜在的暴露风险。

17.5. API 端点进程隔离和策略

您可以隔离 API 端点进程来提高安全性。考虑在独立主机上的公共安全域内部署 API 端点,以增加隔离功能。

17.5.1. 配置策略来限制 metadef API

在 Red Hat OpenStack Platform(RHOSP)中,用户可以通过元数据定义(metadef)API 定义键值对和标签元数据。目前,用户可以创建的元命名空间、对象、属性、资源或标签数量没有限制。

Metadef API 可能会向未经授权的用户泄漏信息。恶意用户可以利用缺乏限制并填充镜像服务(glance)数据库,且带有无限资源,这可以创建一个服务(DoS)风格的攻击。

镜像服务策略控制 metadef API。但是,metadef API 的默认策略设置可让所有用户创建或读取 metadef 信息。由于潜在的敏感名称(如内部基础架构详情或客户名称)无法隔离元数据,因此元数据资源不会将信息暴露给恶意用户。

要使镜像服务(glance)更安全,请在 Red Hat OpenStack Platform(RHOSP)部署中默认将 metadef 修改 API 限制为仅限管理员访问。

流程

  1. 作为云管理员,创建单独的 heat 模板文件,如 lock-down-glance-metadef-api.yaml,使其包含镜像服务 metadef API 的策略覆盖:

    ...
    parameter_defaults:
      GlanceApiPolicies: {
            glance-metadef_default: { key: 'metadef_default', value: '' },
            glance-metadef_admin: { key: 'metadef_admin', value: 'role:admin' },
            glance-get_metadef_namespace: { key: 'get_metadef_namespace', value: 'rule:metadef_default' },
            glance-get_metadef_namespaces: { key: 'get_metadef_namespaces', value: 'rule:metadef_default' },
            glance-modify_metadef_namespace: { key: 'modify_metadef_namespace', value: 'rule:metadef_admin' },
            glance-add_metadef_namespace: { key: 'add_metadef_namespace', value: 'rule:metadef_admin' },
            glance-delete_metadef_namespace: { key: 'delete_metadef_namespace', value: 'rule:metadef_admin' },
            glance-get_metadef_object: { key: 'get_metadef_object', value: 'rule:metadef_default' },
            glance-get_metadef_objects: { key: 'get_metadef_objects', value: 'rule:metadef_default' },
            glance-modify_metadef_object: { key: 'modify_metadef_object', value: 'rule:metadef_admin' },
            glance-add_metadef_object: { key: 'add_metadef_object', value: 'rule:metadef_admin' },
            glance-delete_metadef_object: { key: 'delete_metadef_object', value: 'rule:metadef_admin' },
            glance-list_metadef_resource_types: { key: 'list_metadef_resource_types', value: 'rule:metadef_default' },
            glance-get_metadef_resource_type: { key: 'get_metadef_resource_type', value: 'rule:metadef_default' },
            glance-add_metadef_resource_type_association: { key: 'add_metadef_resource_type_association', value: 'rule:metadef_admin' },
            glance-remove_metadef_resource_type_association: { key: 'remove_metadef_resource_type_association', value: 'rule:metadef_admin' },
            glance-get_metadef_property: { key: 'get_metadef_property', value: 'rule:metadef_default' },
            glance-get_metadef_properties: { key: 'get_metadef_properties', value: 'rule:metadef_default' },
            glance-modify_metadef_property: { key: 'modify_metadef_property', value: 'rule:metadef_admin' },
            glance-add_metadef_property: { key: 'add_metadef_property', value: 'rule:metadef_admin' },
            glance-remove_metadef_property: { key: 'remove_metadef_property', value: 'rule:metadef_admin' },
            glance-get_metadef_tag: { key: 'get_metadef_tag', value: 'rule:metadef_default' },
            glance-get_metadef_tags: { key: 'get_metadef_tags', value: 'rule:metadef_default' },
            glance-modify_metadef_tag: { key: 'modify_metadef_tag', value: 'rule:metadef_admin' },
            glance-add_metadef_tag: { key: 'add_metadef_tag', value: 'rule:metadef_admin' },
            glance-add_metadef_tags: { key: 'add_metadef_tags', value: 'rule:metadef_admin' },
            glance-delete_metadef_tag: { key: 'delete_metadef_tag', value: 'rule:metadef_admin' },
            glance-delete_metadef_tags: { key: 'delete_metadef_tags', value: 'rule:metadef_admin' }
      }
    
    …
  2. 在部署 overcloud 时,使用 -e 选项包括部署命令中包含策略覆盖的环境文件:

    $ openstack overcloud deploy -e lock-down-glance-metadef-api.yaml

17.5.2. 启用 metadef API

如果您之前限制的元数据定义(metadef)API,或希望重新放置新的默认值,您可以覆盖修改策略,以允许用户更新其各自资源。

重要

具有依赖于对 metadef API 的写入访问权限的云管理员可能会导致所有用户访问这些 API。然而,在这种配置中,可能会意外泄漏敏感资源名称,如客户名称和内部项目。管理员必须审核其系统,以识别之前创建的资源,即使所有用户启用了读取访问权限也是如此。

流程

  1. 作为云管理员,登录 undercloud 并为策略覆盖创建一个文件。例如:

    $ cat open-up-glance-api-metadef.yaml
  2. 配置策略覆盖文件,允许所有用户进行 metadef API 读写访问:

    GlanceApiPolicies: {
        glance-metadef_default: { key: 'metadef_default', value: '' },
        glance-get_metadef_namespace: { key: 'get_metadef_namespace', value: 'rule:metadef_default' },
        glance-get_metadef_namespaces: { key: 'get_metadef_namespaces', value: 'rule:metadef_default' },
        glance-modify_metadef_namespace: { key: 'modify_metadef_namespace', value: 'rule:metadef_default' },
        glance-add_metadef_namespace: { key: 'add_metadef_namespace', value: 'rule:metadef_default' },
        glance-delete_metadef_namespace: { key: 'delete_metadef_namespace', value: 'rule:metadef_default' },
        glance-get_metadef_object: { key: 'get_metadef_object', value: 'rule:metadef_default' },
        glance-get_metadef_objects: { key: 'get_metadef_objects', value: 'rule:metadef_default' },
        glance-modify_metadef_object: { key: 'modify_metadef_object', value: 'rule:metadef_default' },
        glance-add_metadef_object: { key: 'add_metadef_object', value: 'rule:metadef_default' },
        glance-delete_metadef_object: { key: 'delete_metadef_object', value: 'rule:metadef_default' },
        glance-list_metadef_resource_types: { key: 'list_metadef_resource_types', value: 'rule:metadef_default' },
        glance-get_metadef_resource_type: { key: 'get_metadef_resource_type', value: 'rule:metadef_default' },
        glance-add_metadef_resource_type_association: { key: 'add_metadef_resource_type_association', value: 'rule:metadef_default' },
        glance-remove_metadef_resource_type_association: { key: 'remove_metadef_resource_type_association', value: 'rule:metadef_default' },
        glance-get_metadef_property: { key: 'get_metadef_property', value: 'rule:metadef_default' },
        glance-get_metadef_properties: { key: 'get_metadef_properties', value: 'rule:metadef_default' },
        glance-modify_metadef_property: { key: 'modify_metadef_property', value: 'rule:metadef_default' },
        glance-add_metadef_property: { key: 'add_metadef_property', value: 'rule:metadef_default' },
        glance-remove_metadef_property: { key: 'remove_metadef_property', value: 'rule:metadef_default' },
        glance-get_metadef_tag: { key: 'get_metadef_tag', value: 'rule:metadef_default' },
        glance-get_metadef_tags: { key: 'get_metadef_tags', value: 'rule:metadef_default' },
        glance-modify_metadef_tag: { key: 'modify_metadef_tag', value: 'rule:metadef_default' },
        glance-add_metadef_tag: { key: 'add_metadef_tag', value: 'rule:metadef_default' },
        glance-add_metadef_tags: { key: 'add_metadef_tags', value: 'rule:metadef_default' },
        glance-delete_metadef_tag: { key: 'delete_metadef_tag', value: 'rule:metadef_default' },
        glance-delete_metadef_tags: { key: 'delete_metadef_tags', value: 'rule:metadef_default' }
      }
    注意

    您必须将所有 metadef 策略配置为使用 rule:metadeta_default

  3. 在部署 overcloud 时,使用 -e 选项在部署命令中包括新策略文件:

    $ openstack overcloud deploy -e open-up-glance-api-metadef.yaml

17.6. 更改 HAProxy 的 SSL/TLS 密码和规则

如果在 overcloud 中启用了 SSL/TLS,请考虑加强与 HAProxy 配置一起使用的 SSL/TLS 密码和规则。通过强化 SSL/TLS 密码,您可以帮助避免 SSL/TLS 漏洞,如 POODLE 漏洞

  1. 创建名为 tls-ciphers.yaml 的 heat 模板环境文件:

    touch ~/templates/tls-ciphers.yaml
  2. 使用环境文件中的 ExtraConfig hook 将值应用到 tripleo::haproxy::ssl_cipher_suitetripleo::haproxy::ssl_options hieradata:

    parameter_defaults:
      ExtraConfig:
        tripleo::haproxy::ssl_cipher_suite:: `DHE-RSA-AES128-CCM:DHE-RSA-AES256-CCM:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305`
    
        tripleo::haproxy::ssl_options:: no-sslv3 no-tls-tickets
    注意

    cipher 集合是一个连续行。

  3. 在部署 overcloud 时,使用 overcloud deploy 命令包含 tls-ciphers.yaml 环境文件:

    openstack overcloud deploy --templates \
    ...
    -e /home/stack/templates/tls-ciphers.yaml
    ...

17.7. 网络策略

API 端点通常跨越多个安全区域,因此您必须特别注意 API 进程的分离。例如,在网络设计级别上,您可以考虑仅限制对指定系统的访问。如需更多信息,请参阅有关安全区的指导。

通过仔细建模,您可以使用网络 ACL 和 IDS 技术强制网络服务之间的显式点通信。作为关键的跨域服务,这种明确的执行方法适用于 OpenStack 的消息队列服务。

要实施策略,您可以配置服务、基于主机的防火墙(如 iptables)、本地策略(SELinux)以及可选的全局网络策略。

17.8. 强制访问控制

您应该将 API 端点进程相互隔离,并相互隔离其他进程。这些进程的配置应受 Discretionary Access Controls(DAC)和强制访问控制(MAC)限制在这些进程中。这些增强访问控制的目标是帮助控制 API 端点安全漏洞。

17.9. API 端点速率限制

速率限制是一种控制基于网络应用程序接收的事件频率的方法。如果不存在可靠的速率限制,则可能导致应用程序容易受到各种拒绝的服务攻击。对于 API 而言,这种 API 特别适用,其性质旨在接受类似请求类型和操作的频率。

建议所有端点(特别是公共)都提供额外的保护层,例如,使用物理网络设计、速率限制代理或 Web 应用防火墙。

关键在于,操作员在配置和实施任何速率限制功能时可仔细地规划并考虑用户和服务的个人性能需求。

请注意,对于 Red Hat OpenStack Platform 部署,所有服务都放置在负载均衡代理后面。

第 18 章 实现 Federation

警告

红帽目前不支持联合。这个功能只应用于测试,不应在生产环境中部署。

18.1. 使用红帽单点登录与 IdM 联合

您可以使用 Red Hat Single Sign-On(RH-SSO)来联合您的 IdM 用户进行 OpenStack 身份验证(authN)。联合允许您的 IdM 用户登录到 OpenStack 仪表板,而无需向任何 OpenStack 服务公开凭证。相反,当仪表板需要用户凭证时,会把用户转发到 Red Hat Single Sign-On(RH-SSO),并允许他们在其中输入其 IdM 凭证。因此,RH-SSO 断言回到控制面板,用户已通过身份验证,而 Dashboard 则允许用户访问项目。

18.2. 联合工作流

本节介绍身份服务(keystone)、RH-SSO 和 IdM 如何相互交互。OpenStack 中的联合使用身份提供程序和服务提供程序的概念:

Identity Provider (IdP)- 存储用户帐户的服务。在这种情况下,IdM 中保存的用户帐户将使用 RH-SSO 向 Keystone 呈现。

Service Provider (SP)- 需要来自 IdP 的用户的身份验证的服务。在这种情况下,keystone 是向 IdM 用户授予 Dashboard 访问权限的服务供应商。

在下图中,keystone(SP)与 RH-SSO(IdP)通信,也可以用作其他 IdP 的通用适配器。在此配置中,您可以将 keystone 指向 RH-SSO,RH-SSO 会将请求转发到它支持的身份提供程序(称为身份验证模块),这些请求目前包含 IdM 和 Active Directory。这可以通过让 Service Provider(SP)和 Identity Provider(IdP)交换元数据来实现,然后每个系统管理员做出信任决定。结果是 IdP 可以放心地断言,然后 SP 可以收到这些断言。

联合 rhsso idm

如需更多信息,请参阅联合指南 :https://access.redhat.com/documentation/en-us/red_hat_openstack_platform/16.2/html-single/federate_with_identity_service/