如何对来自 Amazon S3 的 403 访问被拒绝错误执行故障排查?

4 分钟阅读
1

我的用户尝试访问我的 Amazon Simple Storage Service (Amazon S3) 桶中的对象,但 Amazon S3 返回“403 访问被拒绝”错误。

解决方法

使用 AWS Systems Manager 自动化文档

使用 AWS Systems Manager 上的 AWSSupport-TroubleshootS3PublicRead 自动化文档。此自动化文档可帮助您诊断关于从您指定的公共 S3 桶读取对象的问题。

检查桶和对象所有权

对于来自 GetObjectHeadObject 请求的 AccessDenied 错误,请检查该对象是否也归桶拥有者所有。此外,请验证桶拥有者是否具有读取或完全控制访问控制列表(ACL)权限

确认拥有这些对象的账户

默认情况下,S3 对象归上传该对象的 AWS 账户所有。即使桶归另一个账户所有,也是如此。如果其他账户可以将对象上传到您的桶,则验证您的用户无法访问的对象所属的账户。

**注意:**如果在运行 AWS CLI 命令时收到错误消息,请确保您使用的是最新版本的 AWS CLI

1.    通过查询拥有者 ID 运行 list-buckets AWS 命令行界面(AWS CLI)命令以获取账户的 Amazon S3 规范 ID。

aws s3api list-buckets --query "Owner.ID"

2.    运行 list-objects 命令以获取用户无法访问的对象所属账户的 Amazon S3 规范 ID。将 DOC-EXAMPLE-BUCKET 替换为您的桶名称,并将 exampleprefix 替换为您的前缀值。

aws s3api list-objects --bucket DOC-EXAMPLE-BUCKET --prefix exampleprefix

**提示:**使用 list-objects 命令可查看多个对象。

3.    如果规范 ID 不匹配,则您不拥有该对象。对象拥有者可以通过运行 put-object-acl 命令授予您对该对象的完全控制权限。将 DOC-EXAMPLE-BUCKET 替换为包含对象的桶的名称。将 exampleobject.jpg 替换为您的密钥名称。

aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key exampleobject.jpg --acl bucket-owner-full-control

4.    在对象拥有者将对象的 ACL 更改为 bucket-owner-full-control 后,桶拥有者可以访问该对象。但是,仅更改 ACL 不会更改对象的所有权。要将对象拥有者更改为桶的账户,请从桶账户运行 cp 命令,将对象复制到其自身上。

将所有新对象复制到另一个账户的桶中

1.    设置一个桶策略,该策略要求使用 bucket-owner-full-control ACL 上传对象

2.    在 AWS 管理控制台中激活 S3 对象所有权并将其设置为首选的桶拥有者

然后,使用 bucket-owner-full-control ACL 上传该对象时,该对象的拥有者将自动更新为桶拥有者。

创建具有桶权限的 IAM 角色

对于持续的跨账户权限,在账户中创建具有桶权限的 IAM 角色。然后,授予另一个 AWS 账户代入该 IAM 角色的权限。有关详细信息,请参阅教程: 使用 IAM 角色委托跨 AWS 账户的访问权限

查看桶策略或 IAM 用户策略

查看桶策略或关联的 IAM 用户策略中可能拒绝访问的任何语句。验证对桶的请求是否满足桶策略或 IAM 策略中的任何条件。检查策略中是否有任何错误的拒绝语句、缺失的操作或错误的空格。

拒绝语句条件

根据以下内容检查拒绝语句是否存在阻止访问的条件:

  • 多重身份验证(MFA)
  • 加密密钥
  • 特定的 IP 地址
  • 特定的 VPC 或 VPC 端点
  • 特定的 IAM 用户或角色

**注意:**如果您要求进行 MFA,且用户通过 AWS CLI 发送请求,请确保用户配置 AWS CLI 以使用 MFA

例如,在下面的桶策略中,Statement1 允许公共访问权限从 DOC-EXAMPLE-BUCKET 下载对象 (s3:GetObject)。然而,Statement2 明确地拒绝所有人从 DOC-EXAMPLE-BUCKET 下载对象,除非请求来自 VPC 端点 vpce-1a2b3c4d。在这种情况下,拒绝语句优先。这意味着尝试从 vpce-1a2b3c4d 以外下载对象的用户将被拒绝访问。

{
  "Id": "Policy1234567890123",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Statement1",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
      "Principal": "*"
    },
    {
      "Sid": "Statement2",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Deny",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpce": "vpce-1a2b3c4d"
        }
      },
      "Principal": "*"
    }
  ]
}

桶策略或 IAM 策略

检查桶策略或 IAM 策略是否允许用户需要采取的 Amazon S3 操作。例如,以下桶策略不包含 s3:PutObjectAcl 操作的权限。如果 IAM 用户尝试修改对象的访问控制列表(ACL),则用户会遇到“访问被拒绝”错误。

{
  "Id": "Policy1234567890123",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234567890123",
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:user/Dave"
        ]
      }
    }
  ]
}

其他策略错误

确认桶策略或 IAM 用户策略中没有任何多余的空格或不正确的 ARN。

例如,如果 IAM 策略的 Amazon 资源名称(ARN)中存在一个多余的空格,如下所示:arn:aws:s3::: DOC-EXAMPLE-BUCKET/*。在这种情况下,ARN 会被错误地评估为 arn:aws:s3:::%20DOC-EXAMPLE-BUCKET/,并向 IAM 用户发出访问被拒绝的错误。

确认 IAM 权限边界允许访问 Amazon S3

查看在尝试访问桶的 IAM 身份上设置的 IAM 权限边界。确认 IAM 权限边界允许访问 Amazon S3。

检查桶的 Amazon S3 屏蔽公共访问权限设置

如果您在被允许的公共读取请求上遇到“访问被拒绝”错误,请检查桶的 Amazon S3 屏蔽公共访问权限设置。

在账户和桶级别查看“S3 屏蔽公共访问权限”设置。这些设置会覆盖允许公共读取访问的权限。Amazon S3 屏蔽公共访问权限可以应用于各个桶或 AWS 账户。

查看用户凭证

查看用户已配置用于访问 Amazon S3 的凭证。必须将 AWS SDK 和 AWS CLI 配置为使用可访问您的桶的 IAM 用户或角色的凭证。

对于 AWS CLI,运行 configure 命令以检查所配置的凭证:

aws configure list

如果用户通过 Amazon Elastic Compute Cloud (Amazon EC2) 实例访问您的桶,则验证实例是否使用了正确的角色。连接到实例,然后运行 get-caller-identity 命令:

aws sts get-caller-identity

查看临时安全证书

如果用户收到使用 AWS Security Token Service (AWS STS) 授予的临时安全凭证发出的“访问被拒绝”错误,请查看关联的会话策略。当管理员使用 AssumeRole API 调用或 assume-role 命令创建临时安全凭证时,他们可以传递特定于会话的策略。

要查找与来自 Amazon S3 的访问被拒绝错误相关联的会话策略,请在 AWS CloudTrail 事件历史记录中查找 AssumeRole 事件。请确保在与访问 Amazon S3 的失败请求相同的时间范围内查找 AssumeRole 事件。然后,查看相关 CloudTrail 日志 requestParameters 字段中的任何 policypolicyArns 参数。确认关联的策略或策略 ARN 授予了必要的 Amazon S3 权限。

例如,下面的 CloudTrail 日志代码段显示临时凭证包含一个内联会话策略,该策略将 s3:GetObject 权限授予 DOC-EXAMPLE-BUCKET

"requestParameters": {
	"roleArn": "arn:aws:iam::123412341234:role/S3AdminAccess",
	"roleSessionName": "s3rolesession",
	"policy": "{
	"Version": "2012-10-17",
	"Statement": [{
			"Effect": "Allow",
			"Action": [
				"s3:GetObject"
			],
			"Resource": ["arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"]
		}
	}
]
}
"
}

确认 Amazon VPC 端点策略包含访问 S3 桶和对象的正确权限

如果用户使用通过 VPC 端点路由的 EC2 实例访问您的桶,则检查 VPC 端点策略

例如,以下 VPC 端点策略仅允许访问 DOC-EXAMPLE-BUCKET。通过此 VPC 端点发送请求的用户无法访问任何其他桶。

{
  "Id": "Policy1234567890123",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234567890123",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Principal": "*"
    }
  ]
}

查看您的 Amazon S3 访问点的 IAM 策略

如果您使用 Amazon S3 接入点管理对桶的访问,请查看访问点的 IAM 策略

只有在底层桶策略也允许相同的访问时,访问点策略中授予的权限才有效。确认桶策略和访问点策略授予了正确的权限。

确认对象没有丢失对象或包含特殊字符

检查桶中是否存在请求的对象。否则,请求找不到对象,Amazon S3 会假定该对象不存在。如果您没有适当的 s3:ListBucket 权限,那么您会收到“访问被拒绝”错误(而不是“404 未找到”错误)。

具有特殊字符(例如空格)的对象需要进行特殊处理才能检索该对象。

运行 head-object AWS CLI 命令以检查桶中是否存在某对象。将 DOC-EXAMPLE-BUCKET 替换为您要检查的桶的名称。

aws s3api head-object --bucket DOC-EXAMPLE-BUCKET --key exampleobject.jpg

如果桶中存在该对象,则“访问被拒绝”错误不会屏蔽“404 未找到”错误。检查其他配置要求以解决“访问被拒绝”错误。

如果桶中不存在该对象,则“访问被拒绝”错误将屏蔽“404 未找到”错误。解决与对象缺失相关的问题。

检查 AWS KMS 加密配置

请注意以下有关 AWS KMS (SSE-KMS) 加密的注意事项:

  • 如果 IAM 用户无法访问用户具有完全权限的对象,则检查该对象是否经 SSE-KMS 加密。您可以使用 Amazon S3 控制台查看对象的属性,其中包括对象的服务器端加密信息。
  • 如果对象经 SSE-KMS 加密,请确保 KMS 密钥策略授予 IAM 用户使用密钥所需的最低权限。例如,如果 IAM 用户仅使用密钥下载 S3 对象,则 IAM 用户必须拥有 kms:Decrypt 权限。有关更多信息,请参阅允许访问 AWS 账户并激活 IAM 策略
  • 如果 IAM 身份和密钥在同一账户中,则需要使用密钥策略授予 kms:Decrypt 权限。密钥策略必须引用与 IAM 策略相同的 IAM 身份。
  • 如果 IAM 用户所属的账户与 AWS KMS 密钥不同,则还必须在 IAM 策略上授予这些权限。例如,要下载 SSE-KMS 加密的对象,必须在密钥策略和 IAM 策略中指定 kms:Decrypt 权限。有关 IAM 用户和 AWS KMS 密钥之间的跨账户存取的更多信息,请参阅允许其他账户中的用户使用 KMS 密钥

确认 request-payer 参数由用户指定(如果您使用的是申请方付款)

如果您的桶激活了申请方付款,则其他账户的用户在向您的桶发送请求时必须指定 request-payer 参数。要检查是否已打开“申请方付款”,请使用 Amazon S3 控制台查看桶属性

以下 AWS CLI 命令示例包含访问启用了“申请方付款”的跨账户桶的正确参数:

aws s3 cp exampleobject.jpg s3://DOC-EXAMPLE-BUCKET/exampleobject.jpg --request-payer requester

检查您的 AWS Organizations 服务控制策略

如果您使用的是 AWS Organizations,请检查服务控制策略以确保允许访问 Amazon S3。服务控制策略为受影响的账户指定最大权限。例如,以下策略显式拒绝了对 Amazon S3 的访问,会导致“访问被拒绝”错误:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

有关 AWS Organizations 功能的更多信息,请参阅启用组织中的所有功能

相关信息

Amazon S3 故障排除

获取用于 AWS Support 的 Amazon S3 请求 ID

AWS 官方
AWS 官方已更新 2 年前