如何使用 IAM 策略排查“访问被拒绝”或“未经授权的操作”错误?

4 分钟阅读
0

我正在尝试对 AWS 资源执行操作,但收到“访问被拒绝”或“未经授权的操作”错误。如何排查此类权限问题?

简短描述

要排查 AWS Identity and Access Management(IAM)策略的问题,请执行下列操作:

解决方案

确定 API 调用方并理解错误消息

重要提示:

请务必在查看 IAM 策略前代表正确的 IAM 实体进行 API 调用。如果错误消息不包含调用方信息,请按照下列步骤确定 API 调用方:

  1. 打开 AWS 管理控制台
  2. 在页面的右上角,选择账户信息旁边的箭头。
  3. 如果您以 IAM 角色的身份登录,“当前活跃身份”表示代入角色的名称,“账户 ID”表示账户 ID。
  4. 如果您以联合用户的身份登录,“联合用户”表示联合身份验证角色的名称和角色会话名称。

-或-

使用 AWS CLI 命令 get-caller-identity 来确定 API 调用方。您也可以使用带 --debug 标志的 AWS CLI 命令通过与下面的内容相似的输出确定凭证来源:

2018-03-13 16:23:57,570 - MainThread - botocore.credentials - INFO - Found credentials in shared credentials file: ~/.aws/credentials

检查 IAM 策略权限

通过检查附加的 IAM 策略来验证是否已授予 API 调用方必要的权限。有关更多信息,请参阅确定是允许还是拒绝账户内的请求

评估 AWS Organizations SCP

如果 AWS 账户是 AWS Organizations 的一部分,则可以在分层级别应用 SCP 以允许或拒绝操作。SCP 权限由 AWS 账户中的所有 IAM 实体继承。确保 SCP 中未明确拒绝 API 调用方。

确保被调用的 API 在影响调用方的组织 SCP 策略中没有被明确拒绝

查看基于身份的策略和基于资源的策略

确保 IAM 实体基于身份的策略中有针对 API 调用方的明确允许语句。然后,确保 API 支持资源级权限。如果 API 调用方不支持资源级权限,请确保在 IAM 策略语句的资源元素中指定了通配符**“*”**。

您可以将基于资源的策略附加到 AWS 服务中的资源,以提供访问权限。有关更多信息,请参阅基于身份的策略和基于资源的策略

要查看 IAM 策略摘要,请执行下列操作:

  1. 打开 IAM 控制台
  2. 在导航窗格中,选择策略
  3. 选择策略名称旁边的箭头来展开策略详细信息视图。

在下面的示例中,策略不起作用,因为并非所有 Amazon Elastic Compute Cloud(Amazon EC2)API 操作都支持资源级权限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SorryThisIsNotGoingToWorkAsExpected",
            "Effect": "Allow",
            "Action": ["ec2:*"],
            "Resource": "arn:aws:ec2:us-east-1:accountid:instance/*"
        }
    ]
}

尝试使用 run-instances AWS CLI 命令在 us-east-1 区域启动 Amazon EC2 实例的 IAM 用户会收到类似以下内容的错误消息:

"An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. Encoded authorization failure message:…"

要解决此问题,请将资源更改为通配符**“*”**。这是因为 Amazon EC2 仅支持部分资源级权限

要解码授权失败消息以获取有关此失败的原因的更多详细信息,请使用类似于以下内容的 DecodeAuthorizationMessage API 操作:

$ aws sts decode-authorization-message --encoded-message <encoded-message-from-the-error>

检查权限边界

如果 IAM 实体附加了权限边界,则边界将设置该实体拥有的最大权限。

评估会话策略

如果 API 调用方是 IAM 角色或联合用户,则会在会话持续时间内传递会话策略。会话的权限是如下策略的交集:用于创建会话的 IAM 实体的基于身份的策略和会话策略。确保 IAM 策略和实体中存在 API 调用。

确保策略中的条件键受 API 支持

AWS 条件键可用于将向 AWS 发出的 API 请求中的元素与 IAM 策略中指定的键值进行比较。条件键可以是全局条件键,也可以由 AWS 服务定义。AWS 服务特定的条件键只能在该服务中使用(例如,EC2 API 操作中的 EC2 条件)。有关更多信息,请参阅 Actions, resources, and condition context keys for AWS services

一个条件元素可以包含多个条件,并且每个条件块中可包含多个键值对。有关更多信息,请参阅创建具有多个键或值的条件

在此策略示例中,如果 IAM API 请求由 IAM 用户 admin 调用且源 IP 地址为 1.1.1.0/24 或 2.2.2.0/24,则条件元素匹配。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iam:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:username": "admin"
        },
        "IpAddress": {
          "aws:SourceIp": [
            "1.1.1.0/24",
            "2.2.2.0/24"
          ]
        }
      }
    }
  ]
}

IAM 策略错误和问题排查示例

查看以下示例,以确定错误消息、API 调用方、API 和正在被调用的资源:

错误消息示例API 调用方API资源何时
A:“An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.”未知DescribeInstances未知发生错误时
B:“An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::123456789012:user/test is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/EC2-FullAccess”arn:aws:iam::123456789012:user/testAssumeRolearn:aws:iam::123456789012:role/EC2-FullAccess发生错误时
C:“An error occurred (AccessDenied) when calling the GetSessionToken operation: Cannot call GetSessionToken with session credentials”未知GetSessionToken未知发生错误时
D:“An error occurred (UnauthorizedOperation) when calling the AssociateIamInstanceProfile operation: You are not authorized to perform this operation.Encoded authorization failure message: ....”未知AssociateIamInstanceProfile未知发生错误时

通过使用此评估方法,您可以确定针对不同 AWS 服务的权限问题收到的错误消息的原因。有关更多详细信息,请参阅下列错误消息和问题排查步骤:

示例错误消息 A:

此错误消息指示您无权调用 DescribeInstances API。

要解决此错误,请执行下面的步骤:

  1. 确定 API 调用方。
  2. 确认 ec2:DescribeInstances API 操作未包含在任何拒绝语句中。
  3. 确认 ec2:DescribeInstances API 操作已包含在允许语句中。
  4. 确认未针对此 API 操作指定资源。**注意:**此 API 操作不支持资源级权限
  5. 请确认允许语句中指定的所有 IAM 条件受 DescribeInstances 操作支持,并且条件相匹配。

有关更多信息,请参阅 DescribeInstanceStatus

示例错误消息 B:

此错误消息包含 API 名称、API 调用方和目标资源。请确保调用 API 的 IAM 身份拥有正确的资源访问权限。使用之前的评估方法查看 IAM 策略。

要解决此错误,请按照以下步骤确认 IAM 角色的信任策略: EC2-FullAccess:

  1. 确认 arn:aws:iam::123456789012:user/test 或 arn:aws:iam::123456789012:root 未包含在信任策略的任何拒绝语句中。
  2. 确认 arn:aws:iam::123456789012:user/test 或 arn:aws:iam::123456789012:root 已包含在信任策略的允许语句中。
  3. 确认允许语句中指定的所有 IAM 条件均受 sts:AssumeRole API 操作支持并且匹配。

请按照下列步骤确认附加到 API 调用方的 IAM 策略(arn:aws:iam::123456789012:user/test):

  1. 确认 arn:aws:iam::123456789012:role/EC2-FullAccess 未包含在任何含有 sts:AssumeRole API 操作的拒绝语句中。
  2. 如果 arn:aws:iam::123456789012:root 包含在信任策略的允许语句中,则确认 arn:aws:iam::123456789012:role/EC2-FullAccess 包含在含有 sts:AssumeRole API 操作的 IAM 策略的允许语句中。
  3. 确认允许语句中指定的所有 IAM 条件均受 sts:AssumeRole API 操作支持并且匹配。

示例错误消息 C:

此错误消息指示 get-session-token 不受临时凭证支持。有关更多信息,请参阅 Comparing the AWS STS API operations

示例错误消息 D:

此错误消息返回一则可以提供授权失败详细信息的编码消息。要对错误消息进行解码并获得授权失败的详细信息,请参阅 DecodeAuthorizationMessage。在对错误消息进行解码后,确定 API 调用方并查看资源级权限和条件。

要解决此错误,请按照下列步骤查看 IAM 策略权限:

  1. 如果错误消息指示 API 被明确拒绝,则从匹配的语句中删除 ec2:AssociateIamInstanceProfile 或 iam:PassRole API 操作。
  2. 确认 ec2:AssociateIamInstanceProfile 和 iam:PassRole 位于含有受支持和正确的资源目标的允许语句中。例如,确认 ec2:AssociateIamInstanceProfile API 操作的资源目标是 EC2 实例并且 iam:PassRole 的资源目标是 IAM 角色。
  3. 如果 ec2:AssociateIamInstanceProfile 和 iam:PassRole API 操作位于同一个允许语句中,确认所有条件均受 ec2:AssociateIamInstanceProfile 和 iam:PassRole API 操作支持,并且相关条件匹配。
  4. 如果 ec2:AssociateIamInstanceProfile 和 iam:PassRole API 操作位于不同的允许语句中,确认各允许语句中的所有条件均受操作支持,并且相关条件匹配。

有关更多信息,请参阅 Policy evaluation logicDetermining whether a request is allowed or denied within an account


相关信息

排查 IAM 策略问题

为什么我在尝试承担跨账户 IAM 角色时收到“AccessDenied”或“Invalid information”错误?

IAM JSON 策略元素参考