Azure

Azure 机密引擎能够动态生成 Azure 服务主体(principal),并为其分配角色和所属的组。 Vault 角色可以映射到一个或多个 Azure 角色,还可以选择是否分配到组,从而提供一种简单、灵活的方式来管理授予给生成的服务主体的权限。

每个服务主体都关联了一个 Vault 租约。当租约过期时(正常到期吊销或提前主动吊销),服务主体将被自动删除。

如果将现有服务主体设置为角色配置的一部分,那么将动态生成新密码而不是新服务主体。当租约被吊销时,密码将被删除。

注意,微软将关闭他们的 Azure Active Directory API,并将于 2022 年停用。如果当前正在使用本机密引擎,需要更新凭据以包含 Microsoft Graph API 权限并将 use_microsoft_graph_api 配置项设置为 true。有关更多详细信息,请参阅 API 文档

配置

大部分机密引擎在工作之前必须要先进行配置。这些步骤通常是由系统管理员来完成。

  1. 启用 Azure 机密引擎:
$ vault secrets enable azure
Success! Enabled the azure secrets engine at: azure/

默认情况下,机密引擎会挂载到名字对应的路径上。要在不同路径上启用机密引擎,请使用 -path 参数。

  1. 使用账号凭据配置机密引擎:
$ vault write azure/config \
    subscription_id=$AZURE_SUBSCRIPTION_ID \
    tenant_id=$AZURE_TENANT_ID \
    client_id=$AZURE_CLIENT_ID \
    client_secret=$AZURE_CLIENT_SECRET \
    use_microsoft_graph_api=true

Success! Data written to: azure/config

如果在启用了托管服务身份(Managed Service Identity, MSI)的 Azure 虚拟机上运行 Vault,可以省略 client_idclient_secret

  1. 配置一个 Vault 角色。一个 Vault 角色要么被配置使用一个现存的服务主体,要么是一组将要被赋予动态创建的服务主体上的 Azure 角色。

可以用以下命令配置一个名为 "my-role" 的角色使用一个现存的服务主体:

$ vault write azure/roles/my-role \
    application_object_id=<existing_app_obj_id> \
    ttl=1h

或者,把 Vault 角色配置成为新建的服务主体赋予一些 Azure 角色:

$ vault write azure/roles/my-role ttl=1h azure_roles=-<<EOF
    [
        {
            "role_name": "Contributor",
            "scope":  "/subscriptions/<uuid>/resourceGroups/Website"
        }
    ]
EOF

角色也可以将其 TTL 配置成为挂载点上配置的 TTL 不同的值。

可用标志

配置完机密引擎后拥有合适权限的 Vault 令牌的用户或者机器就可以用它来生成凭据了。使用现存服务主体或是创建新的服务主体在创建凭据时的用法时一样的。

要用"my-role"角色创建凭据:

$ vault read azure/creds/my-role

Key                Value
---                -----
lease_id           azure/creds/sp_role/1afd0969-ad23-73e2-f974-962f7ac1c2b4
lease_duration     60m
lease_renewable    true
client_id          408bf248-dd4e-4be5-919a-7f6207a307ab
client_secret      ad06228a-2db9-4e0a-8a5d-e047c7f32594

该路径生成一组可更新的凭据。应用程序可以使用 client_id/client_secret 登录,并且将拥有由配置的服务主体或在“my-role”配置中设置的 Azure 角色集合提供的访问权限。

角色

Vault 角色允许配置成使用一个现存的服务主体或使用一组 Azure 角色,每个角色都可以设置自己的 TTL 参数。如果没有设置现存的服务主体,那么配置的 Azure 角色会被分配给新创建的服务主体。 Vault 角色可以配置它自己的 ttl 和/或 max_ttl 值。在创建租约时,会使用更靠近角色的位置上配置的 TTL 值(角色上的配置优于挂载点上的配置)。

Application Object IDs

如果要使用现存的服务主体,则必须在 Vault 角色上设置 Application Object ID。可以通过使用 az 命令行工具或通过 Azure 门户网站查找所需的应用程序来找到此 ID。请注意,必须提供 Application Object ID,而不是 Application ID。

Azure 角色

如果使用动态服务主体,那么必须在 Vault 角色上配置要使用的 Azure 角色。Azure 角色通过一个 JSON 格式列表配置,每个元素都描述了要分配的 Azure 角色和范围。可以使用 role_name 参数(比如 “Owner”)或 role_id 参数(“/subscriptions/.../roleDefinitions/...”)指定 Azure 角色。 role_id 是 Vault 最终使用的 ID; role_name 在角色管理操作时很方便。写入配置时所有角色都必须存在,否则操作将失败。角色查找优先级是:

  1. 如果配置了 role_id,则对其进行验证后更新相应的 role_name
  2. 如果只配置了 role_name,会根据角色名进行一次大小写敏感的搜索,只有查询到正好一个匹配记录才算成功。role_id 字段会在成功匹配到角色 ID 时更新。

不管使用哪种方式定义角色,都必须要设置相应的 scope 参数。

Azure 组

如果使用动态服务主体,可以在 Vault 角色上配置一组 Azure 组。当服务主体被创建时,它会被分派到这些组里。与用于指定 Azure 角色的格式类似,Azure 组可以通过它们的 group_nameobject_id 进行引用。按名称设置的组必须返回一个匹配的组。

角色配置示例:

$ vault write azure/roles/my-role \
    ttl=1h \
    max_ttl=24h \
    azure_roles=@az_roles.json \
    azure_groups=@az_groups.json

$ cat az_roles.json
[
  {
    "role_name": "Contributor",
    "scope":  "/subscriptions/<uuid>/resourceGroups/Website"
  },
  {
    "role_id": "/subscriptions/<uuid>/providers/Microsoft.Authorization/roleDefinitions/<uuid>",
    "scope":  "/subscriptions/<uuid>"
  },
  {
    "role_name": "This won't matter as it will be overwritten",
    "role_id": "/subscriptions/<uuid>/providers/Microsoft.Authorization/roleDefinitions/<uuid>",
    "scope":  "/subscriptions/<uuid>/resourceGroups/Database"
  }
]

$ cat az_groups.json
[
  {
    "group_name": "foo",
  },
  {
    "group_name": "This won't matter as it will be overwritten",
    "object_id": "a6a834a6-36c3-4575-8e2b-05095963d603"
  }
]

身份验证

Azure 机密引擎必须具有足够的权限才能读取 Azure 角色信息以及管理服务主体。身份验证参数可以在引擎中设置或通过环境变量读取。优先读取环境变量。

如果没有配置 client id 和 client secret,并且 Vault 在 Azure VM 上运行,则 Vault 将尝试使用托管服务标识 (MSI) 来访问 Azure。请注意,使用 MSI 时,仍必须在配置或环境变量中明确提供 tenet id 和 subscription id。

MS Graph 权限

配置由 Vault 使用来管理 Azure 的服务主体需要具备以下 Azure 权限:

Permission Name Type
Application.Read.All Application
Application.ReadWrite.All Application
Application.ReadWrite.OwnedBy Application
Directory.Read.All Application
Directory.ReadWrite.All Application
Group.Read.All Application
Group.ReadWrite.All Application
GroupMember.Read.All Application
GroupMember.ReadWrite.All Application
Permission Name Type
Application.Read.All Delegated
Application.ReadWrite.All Delegated
Directory.AccessAsUser.All Delegated
Directory.Read.All Delegated
Directory.ReadWrite.All Delegated
Group.Read.All Delegated
Group.ReadWrite.All Delegated
GroupMember.Read.All Delegated
GroupMember.ReadWrite.All Delegated

此外,需要下列额外的 IAM 角色,并且需要使用 Azure 门户添加到服务主体:

  • "Owner" 角色

在动态创建服务主体或是使用现存服务主体之间进行选择

如果可以通过 RBAC 系统和 Vault 角色中定义的 Azure 角色创建所需的 Azure 资源,则首选动态创建服务主体。这种形式的凭证与任何其他客户端完全分离,发布后不受权限变更的影响,并提供最佳的审计粒度。

但是,某些 Azure 服务无法通过 RBAC 系统提供访问权限。在这些情况下,可以使用必要的访问权限设置现存的服务主体,并且 Vault 可以为该服务主体创建新密码。对服务主体权限的任何变更都会影响所有使用该服务主体的客户端。此外,Azure 无法提供有关操作使用哪个凭据的任何日志记录。

使用现存服务主体时的一个重要限制是 Azure 限制单个 Application 的密码数量。此限制基于应用程序对象大小,并没有明确规定,但实际上每个 Application 可以创建数百个密码。如果达到对象大小,将返回错误。可以通过减少 Vault 角色配置的 TTL 或使用一个权限完全相同的其他 Azure 服务主体创建另一个 Vault 角色来绕过该限制。

额外的注意事项

  • 如果引用的 Azure 角色不存在,则不会生成凭据。只有在所有角色的分配都成功时才会生成服务主体。如果使用的自定义 Azure 角色定义可能会在某些时候被删除,请务必注意这一点。
  • Azure 角色只会在创建服务主体时分配一次。如果 Vault 角色变更了使用的 Azure 角色列表,这些变更将不会反映在任何现存服务主体中,即使在令牌续约之后也是如此。
  • 签发凭据所需的时间与必须分配的 Azure 角色数大致成正比。此操作需要一些时间(通常需要 10 秒,并且可能超过一分钟)。
  • 生成的 Azure 服务主体凭据不会在 Azure 端设置超时属性。 Vault 将通过删除服务主体来吊销访问权限。
  • 动态创建的服务主体的应用程序名称将以 vault- 为前缀。同样,添加到现有服务主体的任何密码的 keyId 都将以 ffffff 开头。这些可用于使用 az 命令行工具或门户搜索 Vault 创建的凭据。

results matching ""

    No results matching ""