AWSs

AWS 机密引擎根据 IAM 策略动态生成 AWS 访问凭据。这通常简化了 AWS IAM 的使用,因为它不需要在 Web 界面中点击。此外,该过程可以被编码并映射到内部身份验证方法(例如 LDAP)。基于 AWS IAM 生成凭据具有有效期,会在 Vault 租约到期时自动撤销。

Vault 支持从 AWS 获取三种不同类型的凭据:

  1. iam_user: Vault 将为每个租约创建一个 IAM 用户,将角色中指定的托管和内联 IAM 策略附加到用户,如果在角色上指定了权限边界,那么这个权限边界也会被附加。然后 Vault 将为 IAM 用户生成 access key 和 secret key,并将它们返回给调用者。 IAM 用户没有会话令牌,所以不会返回会话令牌。 Vault 将在 TTL 到期时删除 IAM 用户。
  2. assumed_role: Vault 会调用 sts:AssumeRole 并返回 access key、secret key 和会话令牌给调用者
  3. federation_token: Vault 会调用 sts:GetFederationToken 传入配置的 AWS 策略文档并将 access key、secret key 和会话令牌返回给调用者。

配置

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

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

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

  1. 配置 Vault 用来与 AWS 通信生成 IAM 凭据的凭据:
$ vault write aws/config/root \
    access_key=AKIAJWVN5Z4FOFT7NLNA \
    secret_key=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 \
    region=us-east-1

Vault 使用这里配置的凭据连接到 AWS。因此,这些凭据本身拥有的策略必须是要生成的 IAM 凭据所拥有策略的超集。由于 Vault 使用官方 AWS SDK,因此它将使用 SDK 指定使用的凭据,也可以使用标准 AWS 环境变量、共享文件凭据或 IAM 角色/ECS 任务凭据作为凭据。 (请注意,如果想要使用 STS 联合令牌,Vault 就不能使用 IAM 角色凭据,因为与角色关联的临时安全凭据无权使用 GetFederationToken。)

注意:虽然上面配置的 Vault 的路径是 aws/config/root,也不要使用 AWS 根账户凭据,而是生成专用用户或角色。

  1. 配置一个映射到 AWS 中的一组权限以及 AWS 凭据类型的 Vault 角色。当用户生成凭据时,该凭据会根据使用的 Vault 角色生成。一个例子:
$ vault write aws/roles/my-role \
    credential_type=iam_user \
    policy_document=-<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:*",
      "Resource": "*"
    }
  ]
}
EOF

上面的例子会创建一个名为“my-role”的角色。当用户使用这个角色生成凭据时,Vault 将创建一个 IAM 用户并将指定的策略文档附加到 IAM 用户。然后 Vault 将为 IAM 用户创建访问密钥和秘密密钥并返回这些凭据。也可以指定用户内联策略,外加可选的对现有 AWS 策略的完整 ARN 或一组 IAM 组的引用:

$ vault write aws/roles/my-other-role \
    policy_arns=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess,arn:aws:iam::aws:policy/IAMReadOnlyAccess \
    iam_groups=group1,group2 \
    credential_type=iam_user \
    policy_document=-<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:*",
      "Resource": "*"
    }
  ]
}
EOF

可以阅读 AWS IAM 策略文档获取更多有关 IAM 策略的信息。

可用标志

配置完机密引擎后拥有合适权限的 Vault 令牌的用户或者机器就可以用它来生成凭据了。

  1. 通过读取 /creds 端点加上角色名的路径来生成一个新的凭据:
$ vault read aws/creds/my-role
Key                Value
---                -----
lease_id           aws/creds/my-role/f3e92392-7d9c-09c8-c921-575d62fe80d8
lease_duration     768h
lease_renewable    true
access_key         AKIAIOWQXTLW36DV7IEA
secret_key         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
security_token     <nil>

每次执行该命令都会生成一个新的凭据。

遗憾的是,与 AWS 其他服务一样,IAM 凭据创建后需要等待 5-10 秒(有时更长)才能正常使用,如果是在自动化流程中使用该命令需要注意这一点。

想要立即可用的凭据,请考虑使用 STS 获取密钥的方法。 STS 令牌支持的 IAM 凭据在生成后立即可用。

  1. 轮替 Vault 用来与 AWS 通信使用的凭据:
$ vault write -f aws/config/rotate-root
Key           Value
---           -----
access_key    AKIA3ALIVABCDG5XC8H4

注意:由于 AWS 的最终一致的特点,调用此端点后,从 Vault 到 AWS 的后续调用可能会失败几秒钟,直到 AWS 再次变得一致。

为 Vault 设置 IAM 策略的例子

配置在 aws/config/root 的凭据需要管理动态 IAM 用户的权限。这里有一份 AWS IAM 策略的例子,该策略授予了大多数 Vault 所需要的权限:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:AttachUserPolicy",
        "iam:CreateAccessKey",
        "iam:CreateUser",
        "iam:DeleteAccessKey",
        "iam:DeleteUser",
        "iam:DeleteUserPolicy",
        "iam:DetachUserPolicy",
        "iam:ListAccessKeys",
        "iam:ListAttachedUserPolicies",
        "iam:ListGroupsForUser",
        "iam:ListUserPolicies",
        "iam:PutUserPolicy",
        "iam:AddUserToGroup",
        "iam:RemoveUserFromGroup"
      ],
      "Resource": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:user/vault-*"]
    }
  ]
}

Vault 也支持在创建 IAM 用户时应用权限边界。如果希望强制 Vault 始终将权限边界附加到 IAM 用户,可以使用如下策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:CreateAccessKey",
        "iam:DeleteAccessKey",
        "iam:DeleteUser",
        "iam:ListAccessKeys",
        "iam:ListAttachedUserPolicies",
        "iam:ListGroupsForUser",
        "iam:ListUserPolicies",
        "iam:AddUserToGroup",
        "iam:RemoveUserFromGroup"
      ],
      "Resource": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:user/vault-*"]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iam:AttachUserPolicy",
        "iam:CreateUser",
        "iam:DeleteUserPolicy",
        "iam:DetachUserPolicy",
        "iam:PutUserPolicy"
      ],
      "Resource": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:user/vault-*"],
      "Condition": {
        "StringEquals": {
          "iam:PermissionsBoundary": [
            "arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:policy/PolicyName"
          ]
        }
      }
    }
  ]
}

这里的“iam:PermissionsBoundary”条件包含希望确保 Vault 使用的权限边界策略列表。此策略将确保 Vault 使用给定的权限边界中的一个(不是全部)。

STS 凭据

上面我们演示了如何使用 iam_user 凭据。如前所述,Vault 也支持 assumed_rolefederation_token 凭据。

STS 联合(Federation)令牌

注意:由于 AWS 中的限制,为了使用 federation_token 凭据,Vault 必须配置为使用 IAM 用户凭据。 AWS 不允许使用临时凭据(例如那些来自 IAM 实例配置文件的凭据)。

STS 联合令牌继承了一组权限,他们是四组权限的组合(交集):

  1. 配置在 aws/config/root 的凭据所拥有的权限
  2. 配置在 Vault 的角色中的内联策略
  3. 配置在 Vault 的角色的托管策略的 ARN
  4. 一个 IAM 或是 STS 操作上的隐式的拒绝策略

credential_typefederation_token 的角色可以在 Vault 角色中指定一个或多个 policy_documentpolicy_arnsiam_groups 参数。

配置在 aws/config/root 的凭据需要有 sts:GetFederationToken 的 IAM 权限以及委托给 STS 联合令牌的权限。例如,aws/config/root 凭据上的策略将允许创建具有委托给 ec2:* 的权限(或任意 ec2:* 权限的子集)的 STS 联合令牌:

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": [
      "ec2:*",
      "sts:GetFederationToken"
    ],
    "Resource": "*"
  }
}

然后 ec2_admin 角色将分配一个具有相同的 ec2:* 权限的内联策略。

$ vault write aws/roles/ec2_admin \
    credential_type=federation_token \
    policy_document=@policy.json

这里的 policy.json 文件将包含具有类似权限的内联策略,但没有 sts:GetFederationToken 权限。 (我们可以授予 sts:GetFederationToken 权限,但 STS 附加了一个隐式拒绝,覆盖了我们授予的权限。)

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "ec2:*",
    "Resource": "*"
  }
}

要生成一组新的 STS 联合令牌凭据,我们只需向 aws/sts 路径写入:

$ vault write aws/sts/ec2_admin ttl=60m
Key             Value
lease_id        aws/sts/ec2_admin/31d771a6-fb39-f46b-fdc5-945109106422
lease_duration  60m0s
lease_renewable false
access_key      ASIAJYYYY2AA5K4WIXXX
secret_key      HSs0DYYYYYY9W81DXtI0K7X84H+OVZXK5BXXXX
security_token  AQoDYXdzEEwasAKwQyZUtZaCjVNDiXXXXXXXXgUgBBVUUbSyujLjsw6jYzboOQ89vUVIehUw/9MreAifXFmfdbjTr3g6zc0me9M+dB95DyhetFItX5QThw0lEsVQWSiIeIotGmg7mjT1//e7CJc4LpxbW707loFX1TYD1ilNnblEsIBKGlRNXZ+QJdguY4VkzXxv2urxIH0Sl14xtqsRPboV7eYruSEZlAuP3FLmqFbmA0AFPCT37cLf/vUHinSbvw49C4c9WQLH7CeFPhDub7/rub/QU/lCjjJ43IqIRo9jYgcEvvdRkQSt70zO8moGCc7pFvmL7XGhISegQpEzudErTE/PdhjlGpAKGR3d5qKrHpPYK/k480wk1Ai/t1dTa/8/3jUYTUeIkaJpNBnupQt7qoaXXXXXXXXXX

STS AssumeRole

assumed_role 凭据通常用于跨账户身份验证或单点登录 (SSO) 场景。为了使用 assumed_role 凭据,必须在 Vault 之外进行配置:

  1. 一个 IAM 角色
  2. IAM 内联策略以及可选的附加到 IAM 角色的托管策略
  3. IAM 信任策略附加到 IAM 角色以授予 Vault 代入角色的权限

与使用 federation_token 凭据相比,使用 assumed_role 凭据有如下的优势:

  1. 如果角色的 IAM 策略允许的话,assumed_role 凭据可以调用 IAM 和 STS 操作。
  2. assumed_role 支持跨账户身份验证
  3. 临时凭据(例如在使用了 IAM 实例配置文件的 EC2 实例上运行 Vault 使用的凭据)可以读取assumed_role 凭据(但不能检索 federation_token 凭据)。

配置在 aws/config/root 的凭据必须有一个允许指定角色执行 sts:AssumeRole 的 IAM 策略:

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:role/RoleNameToAssume"
  }
}

我们必须为要代入的 IAM 角色附加一个信任策略,从而允许配置在 aws/root/config 凭据代入该角色。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:user/VAULT-AWS-ROOT-CONFIG-USER-NAME"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

在设置一个 Vault 角色的 credential_typeassumed_role 的时候,可以设置不止一个 IAM 角色 ARN。这样做的话,Vault 客户端可以在从该角色检索凭据时选择他们想要代入的角色 ARN。

此外,我们可以同时设定 policy_documentpolicy_arns 参数;如果这样设定的话,这两个参数同时对要授予代入角色的 IAM 权限进行过滤。如果设置了 iam_groups,则在调用 sts:AssumeRole 时,每个 IAM 组的内联和附加策略都会被添加到 policy_documentpolicy_arns 参数中。对于要放行的操作,它必须得到要代入的 AWS 角色上的 IAM 策略,以及 Vault 角色上指定的 policy_document(如果设置了的话)以及 policy_arns 参数指定的托管策略的许可。 (policy_document 参数被作为 Policy 参数传入 sts:AssumeRole API 调用,而 policy_arns 参数被作为 PolicyArns 参数传入同一调用。)

注意:当设置了多个 role_arns 时,请求凭据的客户端可以指定在 Vault 角色上定义的某个角色 ARN 以获得凭据。但是,当指定了 policy_documentpolicy_arnsiam_groups 时,这将适用于从 AWS 检索的所有角色凭据。

让我们使用我们要代入的角色的 ARN 来创建一个“deploy”策略:

$ vault write aws/roles/deploy \
    role_arns=arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:role/RoleNameToAssume \
    credential_type=assumed_role

为了生成一组新的代入角色 STS 凭据,我们再次对 aws/sts 路径进行写操作:

$ vault write aws/sts/deploy ttl=60m
Key             Value
lease_id        aws/sts/deploy/31d771a6-fb39-f46b-fdc5-945109106422
lease_duration  60m0s
lease_renewable false
access_key      ASIAJYYYY2AA5K4WIXXX
secret_key      HSs0DYYYYYY9W81DXtI0K7X84H+OVZXK5BXXXX
security_token  AQoDYXdzEEwasAKwQyZUtZaCjVNDiXXXXXXXXgUgBBVUUbSyujLjsw6jYzboOQ89vUVIehUw/9MreAifXFmfdbjTr3g6zc0me9M+dB95DyhetFItX5QThw0lEsVQWSiIeIotGmg7mjT1//e7CJc4LpxbW707loFX1TYD1ilNnblEsIBKGlRNXZ+QJdguY4VkzXxv2urxIH0Sl14xtqsRPboV7eYruSEZlAuP3FLmqFbmA0AFPCT37cLf/vUHinSbvw49C4c9WQLH7CeFPhDub7/rub/QU/lCjjJ43IqIRo9jYgcEvvdRkQSt70zO8moGCc7pFvmL7XGhISegQpEzudErTE/PdhjlGpAKGR3d5qKrHpPYK/k480wk1Ai/t1dTa/8/3jUYTUeIkaJpNBnupQt7qoaXXXXXXXXXX

故障排查

动态 IAM 用户错误

如果看到类似于以下任一内容的错误消息,则写入 aws/config/root 的根凭据权限不足:

$ vault read aws/creds/deploy
* Error creating IAM user: User: arn:aws:iam::000000000000:user/hashicorp is not authorized to perform: iam:CreateUser on resource: arn:aws:iam::000000000000:user/vault-root-1432735386-4059

$ vault revoke aws/creds/deploy/774cfb27-c22d-6e78-0077-254879d1af3c
Revoke error: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/sys/revoke/aws/creds/deploy/774cfb27-c22d-6e78-0077-254879d1af3c
Code: 400. Errors:

* invalid request

任何时候如果遇到问题,都可以运行 vault path-help aws 或是使用子路径来获取交互式帮助信息。

STS 联合令牌错误

Vault 使用配置在 aws/config 的 IAM 凭据生成 STS 令牌。

这些凭据必须具有两个属性:

  • 他们必须有权限调用 sts:GetFederationToken
  • 他们所拥有的权限必须至少与要附加到待生成的 STS 凭据的权限相等

如果上述任一一个条件得不到满足,就会返回 "403 not-authorized"。

查阅 http://docs.aws.amazon.com/STS/latest/APIReference/API_GetFederationToken.html 获取更多信息。

使用 STS 令牌时,建议使用 Vault 0.5.1 或更高版本,以避免超过 AWS 对 STS 令牌名称的 32 个字符的限制而导致验证错误。

AWS 读取实例元数据超时

影响 Vault 1.4 及以后的版本

Vault 在 EC2 实例上使用实例元数据服务的时候,例如从实例配置文件中获取凭据,使用到实例元数据服务 (IMDSv2) 的 v2 版本时可能会出现延迟。 Vault 使用的 AWS SDK 首先尝试连接到 IMDSv2,如果超时,则回退到 v1。在 Vault 1.4 中,此超时最多可能需要 2 分钟。在 Vault 1.5.5 及更高版本中最多可能需要 2 秒钟。

超时会发生在 Vault 和 IMDSv2 之间存在代理,并且实例 hop 限制设置为小于 Vault 和 IMDSv2 之间的“hop”数的时候。例如,如果 Vault 在 EC2 实例上的 docker 中运行,并且实例 hop 限制设置为 1,AWS SDK 客户端将尝试连接到 IMDSv2,超时并回退到 IMDSv1,因为 docker 和 IMDS 之间存在额外的网络 hop.

为避免超时行为,可以在底层 EC2 实例上调整 hop 限制。对于 docker 示例,将 hop 限制设置为 2 就可以让 Vault 中的 AWS SDK 无延迟地连接到 IMDSv2。

results matching ""

    No results matching ""