防止非所有者查看或操纵访问规则

包含您的 Launchpad 蓝图的 URL

https://blueprints.launchpad.net/manila/+spec/protect-access-rules

在 OpenStack 共享文件系统服务 (Manila) 中,由于默认 RBAC,共享访问规则(又称“访问控制列表”)可以被拥有该共享的所有项目用户创建、查看和删除。访问规则可能包含敏感信息。本规范提出了一种防止项目所有用户之间共享此敏感信息的方法。

问题描述

在为共享创建访问规则时,用户可以提供请求的访问类型 (access_type)、客户端标识 (access_to)、访问级别 (access_level) 和元数据。所有这些信息都命名空间到共享的项目。因此,所有项目用户都可以查看与项目中的共享关联的访问规则。有时这可能不是期望的。当用户创建 CephX 访问规则时,他们可以通过 Manila 获取 CephX 访问密钥,该密钥可以是私有信息。在项目中的其他用户之间共享此密钥意味着 CephX 用户密钥对多个 OpenStack 项目用户可见且可用。如果目标只是允许一部分 OpenStack 用户访问共享,那么这种级别的可见性会使目的落空。如果单个 CephX 用户需要具有不同的访问级别(“只读”与“读写”);由于 CephX 用户 (access_to) 和 CephX 访问密钥 (access_key) 很容易获得,因此无法阻止项目用户之间的未经授权访问。

在具有 IP 访问控制的 NFS 的情况下,用户可能不想出于安全原因“泄露”客户端的 IP 地址,即使是在同一项目的其他用户之间也是如此。

用例

在使用 CephFS 共享时,不同的 OpenStack 用户希望保护他们自己的 CephX 访问密钥,使其不被项目中的其他用户看到。

OpenStack 计算服务 (Nova) 创建一个访问规则,以便将共享挂载到计算主机上,并通过 VirtIOFS 使其可用于虚拟机。它期望访问规则数据 (access_toaccess_key) 不对其他用户可见。 [1] 重要的是要澄清,Nova 将使用用户自己的令牌执行 API 交互。但是,Manila 将依赖于 nova 也提供 X-Service-Token 标头。这样做将允许 manila 对 nova 服务用户有利地施加任何可见性限制,而不是项目用户。

Nova 还希望防止用户删除自创建的访问规则,因为这将导致将共享硬挂载到计算主机。

提议的变更

在创建访问规则时,用户将能够限制 access_toaccess_key 字段的可见性,仅限于他们自己。受限制的访问规则对所有项目用户仍然可见,但是,这些敏感字段仅对施加限制的用户可见。项目中的其他用户无法删除受限制的访问规则。只有用户或权限更高的用户(“admin”)才能删除限制。删除限制后,项目中的其他用户可以查看先前受限制的访问规则的所有详细信息。

这些限制将通过 资源锁 实现。在本文档的其余部分中,为了简洁起见,我们将把施加限制的资源锁称为“访问规则锁”。访问规则 API 将被增强,以自动创建此类访问规则锁,并根据新的 API 输入参数删除它。

OpenStack 服务(例如 nova)可以使用 X-Service-Token 并代理用户的令牌。在这种情况下,服务用户创建的限制将对服务用户有利。这意味着敏感的访问规则字段只能被服务用户查看,并且规则只能被服务用户删除。在内部,manila 将通过记录“锁用户上下文”来强制执行此操作。因此,即使在使用用户的令牌时,如果提供了服务令牌,用户也无法更新或删除锁。只有服务用户或具有“admin”角色的用户才能删除或更新锁。Manila 将验证 X-Service-Token 是否对应于具有 service 角色的用户。

限制访问规则的能力将有一个重要的注意事项。虽然限制了访问规则的删除,但相应的共享仍然可以被删除。为了防止删除共享,可以使用 专用的资源删除锁

备选方案

此功能可以限制为仅“admin”和“service”用户。在这种情况下,将直接通过 RBAC 实现可见性和操作限制会更容易。但是,这种方法不利于云的自助服务特性。常规用户必须通过管理员用户才能获得施加这些限制的能力。

数据模型影响

无。

REST API 影响

创建带有限制的访问规则:

POST /shares/{share_id}/action

正常的 http 响应代码

  • 202 - 接受访问规则创建

预期的 http 错误代码

  • 401 - 未授权;用户未进行身份验证

  • 400 - 请求错误

  • 403 - 禁止;用户被策略禁止

  • 404 - 微版本中不存在 API

请求示例

{
    "allow_access": {
        "access_type": "ip",
        "access_to": "203.0.113.10",
        "restrict": "True"
    }
}

响应示例

{
    "access": {
        "share_id": "406ea93b-32e9-4907-a117-148b3945749f",
        "created_at": "2023-04-30T09:14:48.000000",
        "updated_at": null,
        "access_type": "ip",
        "access_to": "203.0.113.10",
        "access_level": "rw",
        "access_key": null,
        "id": "a25b2df3-90bd-4add-afa6-5f0dbbd50452",
        "metadata": null
    }
}

当访问规则应用了限制时,没有“admin”或“service”角色的其他用户将看到 access_toaccess_secret 字段设置为 ******

删除带有限制的访问规则:

POST /shares/{share_id}/action

正常的 http 响应代码

  • 202 - 接受访问规则删除

预期的 http 错误代码

  • 401 - 未授权;用户未进行身份验证

  • 400 - 请求错误

  • 403 - 禁止;用户被策略禁止

  • 404 - 微版本中不存在 API

请求示例

{
    "deny_access": {
        "access_id": "a25b2df3-90bd-4add-afa6-5f0dbbd50452",
        "unrestrict": "True",
    }
}

API 不提供响应体。如果未指定“unrestrict”字段,则无法删除受限制的访问规则。在这种情况下,API 将响应 HTTP 400。如果指定了“unrestrict”字段,但是执行此操作的用户不是限制规则的用户;或者如果锁用户上下文为“service”,则不是“service”用户,则 API 将响应错误代码 HTTP 403。

创建现有访问规则的限制

POST /v2/resource-locks

正常的 http 响应代码

  • 200 - 锁创建成功

预期的 http 错误代码

  • 401 - 未授权;用户未进行身份验证

  • 400 - 请求错误

  • 400 - 访问规则上的操作不被识别

  • 400 - 未识别的访问规则(项目命名空间中没有这样的规则)

  • 403 - 禁止;用户被策略禁止

  • 404 - 微版本中不存在 API

请求示例

{
    'resource_lock': {
        'resource_action': 'view,delete',
        'resource_type': 'access_rule',
        'resource_id': '222e1229-3de7-4678-9cb9-20cfd4ca9776',
        'lock_reason': 'infra host rule managed by fancyuser1'
    }
}

响应示例

{
    'resource_lock': {
        'id': '413080b6-1a20-48e1-9516-b2c509d034ec',
        'user_id': 'cec1dd3e297b45348228f4fc3f5dba38',
        'project_id': '2e47ac4e2cf04a5b8b8509de8177d65d',
        'resource_action': 'view,delete',
        'resource_type': 'access_rule',
        'resource_id': 'a448e0d2-7501-4b99-a447-1b89e3961e39',
        'lock_reason': 'infra host rule managed by fancyuser1',
        'created_at': '2023-04-28T09:49:58-05:00',
        'updated_at': None
    }
}

更新访问规则限制

要删除或更新访问规则限制而不删除访问规则,请参阅 allow-locking-shares-against-deletion.html#update-resource-locks

其他 API 影响

当共享上存在访问规则限制时,无法接受将共享移动到 OpenStack 项目的传输请求,同时保持规则不变。API 将响应 409 Conflict。

REST API 微版本将增加,表明这些新功能。只有在使用等于或晚于出现这些 API 更改的微版本的 API 时,才能应用访问规则限制。但是,如果存在访问规则限制,则无法通过使用较低的 API 微版本来绕过它们。

驱动程序影响

无。此更改会影响 API 行为,并且与后端驱动程序无关。

安全影响

拟议的更改增强了访问控制列表的安全模型。可以对新的和现有的访问规则创建限制。增强功能是选择加入的。

通知影响

其他最终用户影响

OpenStack CLI 插件和 python-manilaclient SDK 将支持此功能。CLI 交互如下所示

  • 创建带有限制的访问规则

    openstack share access create <share> <access_type> <access_to> \
       [--access-level <access_level> \
       [--restrict] \
       [--properties [<key=value> ...]] \
       [--wait]
    
  • 设置访问规则的限制

    openstack share lock create <access_id> \
    --resource-action view-or-delete \
    --resource-type access \
    [--reason <lock_reason>}]
    
  • 取消设置访问规则的限制

    openstack share lock delete <lock_id>
    
  • 删除带有限制的访问规则

    openstack share access delete <access_rule_id> --unrestrict
    

性能影响

访问规则限制会在 API 方法中引入先决条件,以列出和删除访问规则。评估这些先决条件会引入轻微的性能下降。应该通过 resource_locks 数据库表中的适当索引来改善这一点。

其他部署者影响

开发人员影响

实现

负责人

主要负责人

gouthamr

其他负责人

carloss

工作项

  • 使用 manila-tempest-tests 进行测试

  • python-manilaclient、openstacksdk、manila-ui 中的支持

  • 文档

依赖项

此功能由 Nova/VirtioFS 功能 [1] 所需。

测试

代码更改将涵盖单元和 tempest 测试。

文档影响

  • API 参考

  • 用户指南文档

参考资料

[1] VirtIOFS 规范

[2] Manila Specs: Allow locking shares against deletion

[3] 2023.2 Bobcat PTG 讨论