我使用 Amazon Simple Storage Service (Amazon S3) 存储桶通过 S3 静态网站托管端点来托管静态网站。我想对我从 S3 静态网站托管端点收到的“Access Denied”(拒绝访问)错误进行故障排除。
解决方案
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
存储桶中的对象必须可以公开访问
S3 静态网站端点仅支持可公开访问的内容。要验证您的 S3 存储桶中的某个对象是否可以公开访问,请在 Web 浏览器中打开该对象的 URL。或者,您可以在该 URL 上运行 curl 命令。
以下是 S3 对象的示例 URL:
http://doc-example-bucket.s3-website-us-east-1.amazonaws.com/index.html
如果 Web 浏览器或 curl 命令返回 Access Denied(拒绝访问)错误,则说明对象不可公开访问。要解决此问题,请创建一个存储桶策略,以允许对存储桶中的所有对象进行公共读取访问。
S3 存储桶策略必须允许访问 s3:GetObject 操作
检查您的存储桶策略是否包含阻止对 s3:GetObject 操作进行公共读取访问的拒绝语句。即使您的存储桶策略中包含针对 s3:GetObject 的显式允许语句,但显式拒绝语句始终会覆盖显式允许语句。
要检查您的存储桶策略,请完成以下步骤:
- 打开 Amazon S3 控制台,然后选择您的存储桶。
- 选择 Permissions(权限)选项卡。
- 查看存储桶策略中是否存在包含 "Action": "s3:GetObject" or "Action": "s3:*" 的语句。
- 如果语句阻止对 s3:GetObject 的公共读取访问,请修改存储桶策略。
拥有存储桶的账户也必须拥有对象
要允许对对象进行公共读取访问,拥有该存储桶的 AWS 账户也必须拥有这些对象。创建存储桶或对象的 AWS Identity and Access Management (IAM) 身份账户拥有该存储桶或对象。
**注意:**S3 对象所有权不适用于对象的访问控制列表 (ACL) 授予的公共读取访问权限。
您可以使用 Amazon S3 控制台来检查存储桶和对象所有者。您可以在存储桶或对象的 Permissions(权限)选项卡上找到所有者。
要使用 AWS CLI 检查同一账户是否拥有您的 Amazon S3 存储桶和对象,请完成以下步骤:
-
要检索存储桶所有者的 S3 规范 ID,请运行 list-buckets 命令:
aws s3api list-buckets --query Owner.ID
-
要检索对象所有者的 S3 规范 ID,请运行 list-objects 命令:
aws s3api list-objects --bucket DOC-EXAMPLE-BUCKET --prefix index.html
**注意:**上述命令将返回单个对象。要检查多个对象,请运行 list 命令。
-
如果存储桶所有者和对象所有者的规范 ID 不匹配,请将对象的所有者更改为存储桶所有者。在对象所有者的账户中,运行 get-object-acl 命令来检索分配给对象的 ACL 权限:
aws s3api get-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name
-
如果对象没有 bucket-owner-full-control ACL 权限,请从对象所有者的账户运行 put-object-acl 命令:
aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name --acl bucket-owner-full-control
-
如果对象具有 bucket-owner-full-control ACL 权限,请从存储桶所有者的账户运行以下命令:
aws s3 cp s3://DOC-EXAMPLE-BUCKET/index.html s3://DOC-EXAMPLE-BUCKET/index.html --storage-class STANDARD
**注意:**上述命令会将对象复制到其自身,并更改对象的所有者。
您还可以使用 S3 对象所有权向存储桶所有者授予匿名用户或其他账户上传的任何对象的自动所有权。
您无法对对象使用 AWS KMS 加密
AWS Key Management Service (AWS KMS) 不支持匿名请求。因此,允许匿名或公共访问的 Amazon S3 存储桶不适用于使用 AWS KMS 加密的对象。要从对象中删除 AWS KMS 加密,您必须使用 Amazon S3 静态网站端点。
**注意:**请使用具有 Amazon S3 托管式密钥的服务器端加密来加密对象,而不是 AWS KMS 加密。
要检查是否对对象使用了 KMS 加密,您可以使用 Amazon S3 控制台。在 Object overview(对象概述)页面上,检查 Encryption(加密)对话框中是否选择了 AWS-KMS。您也可以运行 AWS CLI 命令 head-object。如果此命令返回的 server-side encryption 为 aws:kms,则表明对象是使用 AWS KMS 加密的。
要使用 Amazon S3 控制台更改对象的加密设置,请参阅指定具有 Amazon S3 托管式密钥的服务器端加密 (SSE-S3)。
要使用 AWS CLI 更改对象的加密设置,请确认该对象的存储桶没有默认加密。如果存储桶没有默认加密,请运行以下命令将对象复制到其自身,以移除对象的加密:
aws s3 cp s3://DOC-EXAMPLE-BUCKET/index.html s3://DOC-EXAMPLE-BUCKET/index.html --storage-class STANDARD --sse AES256
**警告:**当您将对象复制到其自身时,Amazon S3 会删除 storage-class 和 website-redirect-location 的设置。要在新对象中保留这些设置,请确保在复制请求中明确指定 storage-class 或 website-redirect-location 值。
如果您在存储桶上激活了版本控制,则当您更改加密时,默认加密会创建对象的新版本。
所请求的对象必须存在于 S3 存储桶中
如果执行请求的用户没有 s3:ListBucket 权限,则用户会因为缺失对象而收到 Access Denied(拒绝访问)错误。
要检查存储桶中是否存在该对象,请运行 AWS CLI 命令 head-object。
**注意:**S3 对象名称区分大小写。如果请求中没有有效的对象名称,则 Amazon S3 会报告该对象缺失。
如果存储桶中存在该对象,则 Access Denied(拒绝访问)错误不会屏蔽 404 Not Found(404 未找到)错误。要解决 Access Denied(拒绝访问)错误,请验证其他配置要求。
如果存储桶中不存在该对象,则 Access Denied(拒绝访问)错误将屏蔽 404 Not Found(404 未找到)错误。解决与对象缺失相关的问题。
**注意:**最佳安全做法是不激活公共 s3:ListBucket 访问权限。公共 s3:ListBucket 访问权限允许用户查看和列出存储桶中的所有对象。此访问权限会向用户公开对象元数据详细信息(例如,密钥和大小),即使用户没有下载对象的权限也是如此。
关闭存储桶上的 Amazon S3 屏蔽公共访问权限
Amazon S3 屏蔽公共访问权限会覆盖允许公共读取访问的权限。确认没有为您的 S3 存储桶或账户配置 Amazon S3 屏蔽公共访问权限设置。
相关信息
Hosting Internal HTTPS Static Websites with Application Load Balancer, S3, and AWS PrivateLink