繁体   English   中英

AWS CLI S3 调用 HeadObject 操作时发生客户端错误 (403):禁止访问

[英]AWS CLI S3 A client error (403) occurred when calling the HeadObject operation: Forbidden

我正在尝试设置一个 Amazon Linux AMI(ami-f0091d91) 并有一个运行复制命令以从 S3 存储桶复制的脚本。

aws --debug s3 cp s3://aws-codedeploy-us-west-2/latest/codedeploy-agent.noarch.rpm .

此脚本在我的本地机器上运行完美,但在 Amazon Image 上失败并出现以下错误:

2016-03-22 01:07:47,110 - MainThread - botocore.auth - DEBUG - StringToSign: HEAD

Tue, 22 Mar 2016 01:07:47 GMT
x-amz-security-token:AQoDYXdzEPr//////////wEa4ANtcDKVDItVq8Z5OKms8wpQ3MS4dxLtxVq6Om1aWDhLmZhL2zdqiasNBV4nQtVqwyPsRVyxl1Urq1BBCnZzDdl4blSklm6dvu+3efjwjhudk7AKaCEHWlTd/VR3cksSNMFTcI9aIUUwzGW8lD9y8MVpKzDkpxzNB7ZJbr9HQNu8uF/st0f45+ABLm8X4FsBPCl2I3wKqvwV/s2VioP/tJf7RGQK3FC079oxw3mOid5sEi28o0Qp4h/Vy9xEHQ28YQNHXOBafHi0vt7vZpOtOfCJBzXvKbk4zRXbLMamnWVe3V0dArncbNEgL1aAi1ooSQ8+Xps8ufFnqDp7HsquAj50p459XnPedv90uFFd6YnwiVkng9nNTAF+2Jo73+eKTt955Us25Chxvk72nAQsAZlt6NpfR+fF/Qs7jjMGSF6ucjkKbm0x5aCqCw6YknsoE1Rtn8Qz9tFxTmUzyCTNd7uRaxbswm7oHOdsM/Q69otjzqSIztlwgUh2M53LzgChQYx5RjYlrjcyAolRguJjpSq3LwZ5NEacm/W17bDOdaZL3y1977rSJrCxb7lmnHCOER5W0tsF9+XUGW1LMX69EWgFYdn5QNqFk6mcJsZWrR9dkehaQwjLPcv/29QcM+b5u/0goazCtwU=
/aws-codedeploy-us-west-2/latest/codedeploy-agent.noarch.rpm
2016-03-22 01:07:47,111 - MainThread - botocore.endpoint - DEBUG - Sending http request: <PreparedRequest [HEAD]>
2016-03-22 01:07:47,111 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - INFO - Starting new HTTPS connection (1): aws-codedeploy-us-west-2.s3.amazonaws.com
2016-03-22 01:07:47,151 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - DEBUG - "HEAD /latest/codedeploy-agent.noarch.rpm HTTP/1.1" 403 0
2016-03-22 01:07:47,151 - MainThread - botocore.parsers - DEBUG - Response headers: {'x-amz-id-2': '0mRvGge9ugu+KKyDmROm4jcTa1hAnA5Ax8vUlkKZXoJ//HVJAKxbpFHvOGaqiECa4sgon2F1kXw=', 'server': 'AmazonS3', 'transfer-encoding': 'chunked', 'x-amz-request-id': '6204CD88E880E5DD', 'date': 'Tue, 22 Mar 2016 01:07:46 GMT', 'content-type': 'application/xml'}
2016-03-22 01:07:47,152 - MainThread - botocore.parsers - DEBUG - Response body:

2016-03-22 01:07:47,152 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.HeadObject: calling handler <botocore.retryhandler.RetryHandler object at 0x7f421075bcd0>
2016-03-22 01:07:47,152 - MainThread - botocore.retryhandler - DEBUG - No retry needed.
2016-03-22 01:07:47,152 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.HeadObject: calling handler <function enhance_error_msg at 0x7f4211085758>
2016-03-22 01:07:47,152 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.HeadObject: calling handler <awscli.errorhandler.ErrorHandler object at 0x7f421100cc90>
2016-03-22 01:07:47,152 - MainThread - awscli.errorhandler - DEBUG - HTTP Response Code: 403
2016-03-22 01:07:47,152 - MainThread - awscli.customizations.s3.s3handler - DEBUG - Exception caught during task execution: A client error (403) occurred when calling the HeadObject operation: Forbidden
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/awscli/customizations/s3/s3handler.py", line 100, in call
    total_files, total_parts = self._enqueue_tasks(files)
  File "/usr/local/lib/python2.7/site-packages/awscli/customizations/s3/s3handler.py", line 178, in _enqueue_tasks
    for filename in files:
  File "/usr/local/lib/python2.7/site-packages/awscli/customizations/s3/fileinfobuilder.py", line 31, in call
    for file_base in files:
  File "/usr/local/lib/python2.7/site-packages/awscli/customizations/s3/filegenerator.py", line 142, in call
    for src_path, extra_information in file_iterator:
  File "/usr/local/lib/python2.7/site-packages/awscli/customizations/s3/filegenerator.py", line 314, in list_objects
    yield self._list_single_object(s3_path)
  File "/usr/local/lib/python2.7/site-packages/awscli/customizations/s3/filegenerator.py", line 343, in _list_single_object
    response = self._client.head_object(**params)
  File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 228, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 488, in _make_api_call
    model=operation_model, context=request_context
  File "/usr/local/lib/python2.7/site-packages/botocore/hooks.py", line 226, in emit
    return self._emit(event_name, kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/hooks.py", line 209, in _emit
    response = handler(**kwargs)
  File "/usr/local/lib/python2.7/site-packages/awscli/errorhandler.py", line 70, in __call__
    http_status_code=http_response.status_code)
ClientError: A client error (403) occurred when calling the HeadObject operation: Forbidden
2016-03-22 01:07:47,153 - Thread-1 - awscli.customizations.s3.executor - DEBUG - Received print task: PrintTask(message='A client error (403) occurred when calling the HeadObject operation: Forbidden', error=True, total_parts=None, warning=None)
A client error (403) occurred when calling the HeadObject operation: Forbidden

但是,当我使用--no-sign-request选项运行它时,它可以完美运行:

aws --debug --no-sign-request s3 cp s3://aws-codedeploy-us-west-2/latest/codedeploy-agent.noarch.rpm .

有人可以解释这是怎么回事吗?

在我的情况下,问题是用户访问策略中的Resource语句。

首先我们有"Resource": "arn:aws:s3:::BUCKET_NAME" ,但是为了访问存储桶中的对象,您需要在末尾添加/*"Resource": "arn:aws:s3:::BUCKET_NAME/*"

AWS 文档

存储桶访问权限指定允许哪些用户访问存储桶中的对象以及他们拥有哪些类型的访问权限。 对象访问权限指定允许哪些用户访问对象以及他们拥有哪些类型的访问权限。 例如,一个用户可能只有读取权限,而另一个用户可能具有读取和写入权限。

我想到了。 我在创建 EC2 实例的云形成模板中出现错误。 因此,尝试访问上述代码部署存储桶的 EC2 实例位于不同的区域(不是 us-west-2)。 似乎存储桶(由亚马逊拥有)上的访问策略只允许从它们所属的区域进行访问。当我修复模板中的错误(它是错误的参数映射)时,错误消失了

自己尝试解决这个问题,发现没有 HeadBucket 权限。 看起来有,因为这是错误消息告诉你的,但实际上HEAD操作需要ListBucket权限。 我还发现我的 IAM 策略和存储桶策略存在冲突。 确保同时检查两者。

如果您从另一个 aws 帐户复制文件,请检查您的对象所有者。

在我的情况下,我从另一个没有 acl 的 aws 帐户复制文件,所以文件的所有者是另一个 aws 帐户,这意味着该文件属于原始帐户。

要修复它,请使用 acl 复制或同步 s3 文件,例如:

aws s3 cp --acl bucket-owner-full-control s3://bucket1/key s3://bucket2/key

可能有很多原因,(最愚蠢的一个是)当指定的对象或文件在该位置不存在时,AWS S3 会引发403 错误

就我而言,我在尝试获取 S3 存储桶文件夹上的对象时遇到此错误。 但是在那个文件夹中我的对象不在这里(我放错了文件夹),所以 S3 发送这条消息。 希望它也可以帮助你。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAllS3ActionsInUserFolder",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::your_bucket_name",
                "arn:aws:s3:::your_bucket_name/*"
            ]
        }
    ]
}

"arn:aws:s3:::your_bucket_name""arn:aws:s3:::your_bucket_name/*"添加到策略配置中为我解决了这个问题。

mybucket中的任何对象上运行HeadObject时对我有用的最小权限:

        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::mybucket/*",
                "arn:aws:s3:::mybucket"
            ]
        }

我收到错误A client error (403) occurred when calling the HeadObject operation: Forbidden for my aws cli copy command aws s3 cp s3://bucket/file file 我使用的是 IAM 角色,该角色使用Inline Policy具有完全 S3 访问权限。

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

如果我改为从Managed Policies为其提供完整的 S3 访问权限,则该命令有效。 我认为这一定是亚马逊的错误,因为两种情况下的政策完全相同。

造成这种情况的原因之一可能是您尝试访问需要 V4 签名的区域的存储桶。 尝试明确提供区域,如--region cn-north-1

我遇到了这个问题,在命令中添加--recursive会有所帮助。

在这一点上,它并不完全有意义,因为您(像我一样)只是试图复制一个文件,但它确实成功了!

403 - 表示我知道你是谁,但你无权按照你的要求去做。

就我而言,问题出在策略中 - 在可视化编辑器中指定策略时我没有选择对象

在此处输入图像描述

放弃对整个 s3(所有操作,所有存储桶)的访问权,只是为了解除对自己的阻塞,这是一种糟糕的做法。

上面的 403 错误通常是由于缺少文件的“读取”权限。 在 S3 中读取文件的读取操作是s3:GetObject

        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::mybucketname/path/*",
                "arn:aws:s3:::mybucketname"
            ]
        }

解决方案 1:IAM 中的新策略(告诉角色/用户了解 S3)

您可以使用以下内容创建策略(例如MY_S3_READER ),并将其附加到正在执行该工作的用户或角色。 (例如 EC2 实例的 IAM 角色)

这是您的策略的确切 JSON:(只需替换mybucketnamepath

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::mybucketname/path/*",
                "arn:aws:s3:::mybucketname"
            ]
        }
    ]
}

创建此政策。 然后,转到 IAM > Roles > Attach Policy 并附加它。

解决方案 2:在 S3 中编辑 Buckey 策略(告诉 S3 知道用户/角色)

转到 S3 中的存储桶,然后添加以下示例:(替换mybucketnamemyip

{
    "Version": "2012-10-17",
    "Id": "SourceIP",
    "Statement": [
        {
            "Sid": "ValidIpAllowRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::mybucketname",
                "arn:aws:s3:::mybucketname/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "myip/32"
                }
            }
        }
    ]
}

如果您想按用户或角色(而不是 IP 地址)更改此读取权限,请删除Condition部分,并将“Principal”更改为"Principal": { "AWS": "<IAM User/Role's ARN>" }, ".

补充说明

  1. 通过aws s3 cpaws s3 ls手动检查权限以加快调试速度。

  2. 权限更改有时需要长达 30 秒才能生效。 要有耐心。

  3. 请注意,要执行“ ls ”(例如aws s3 ls s3://mybucket/mypath ),您需要s3:ListBucket访问权限。

  4. 重要通过cURL或类似工具(例如 AJAX 调用上的axios )通过其 HTTP(S) URL 访问文件需要您手动授予 IP 访问权限,或提供适当的标头,或首先从 SDK 获取签名Url

由于我的 EC2 实例的时钟不同步,我收到此错误消息。

我能够使用以下方法修复 Ubuntu:

sudo ntpdate ntp.ubuntu.com
sudo apt-get install ntp

我因错误配置的测试事件而收到此错误。 我更改了源存储桶 ARN,但忘记编辑默认 S3 存储桶名称。

即确保在测试事件的存储桶部分中,ARN 和存储桶名称都设置正确:

"bucket": {
  "arn": "arn:aws:s3:::your_bucket_name",
  "name": "your_bucket_name",
  "ownerIdentity": {
    "principalId": "EXAMPLE"
  }

我也经历过这种行为。 就我而言,我发现如果 IAM 策略无权读取对象 ( s3:GetObject ),则会引发相同的错误。

我同意你的观点,从 aws 控制台和 cli 引发的错误没有得到很好的解释,可能会引起混淆。

如果在凭据/角色不明确的环境中运行,请确保包含--profile=yourprofile标志,以便 cli 知道要使用的凭据。 例如:

aws s3 cp s3://yourbucket destination.txt --profile=yourprofile

将成功,而以下产生 HeadObject 错误

aws s3 cp s3://yourbucket destination.txt

配置文件设置引用configcredentials文件中的条目。

我有一个 lambda 函数做同样的事情,从一个桶复制到另一个桶。

lambda 有权使用源存储桶作为触发器。

配置选项卡

在此处输入图像描述

但它还需要操作存储桶的权限。

权限选项卡

在此处输入图像描述

如果 s3 不存在,那么您需要编辑 lambda 使用的角色并添加它(请参阅 s3FullAccess)

在此处输入图像描述

对我来说,这是因为我启用了 MFA,并为其提供了访问密钥和密钥,但不允许在我使用的 docker 映像中进行令牌身份验证。 这也可能导致此错误。 这是一个适用范围非常广泛的错误。

在 GET 请求工作时,我收到了 HEAD 请求的 403。 原来是 s3 权限中的 CORS 配置。 我不得不添加 HEAD

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

我也经历过这种场景。

我有一个使用 AWS4-HMAC-SHA256 的策略的存储桶。 原来我的 awscli 没有更新到最新版本。 我的是 aws-cli/1.10.8。 升级它已经解决了这个问题。

pip install awscli --upgrade --user

https://docs.aws.amazon.com/cli/latest/userguide/installing.html

当涉及跨账户 S3 访问时

IAM 用户策略不会覆盖为外部账户中的存储桶定义的策略。

s3:GetObject 必须允许 accountA/user 以及 accountB/bucket

我通过正确设置系统时间来解决这个问题。

确保 aws 存储桶区域正确且您的系统时间与 aws 区域时间匹配

当我遇到这个问题时,我发现我的问题是“源帐户”中的文件被“第三方”复制到那里,并且所有者不是源帐户。

我必须使用 --metadata-directive REPLACE 将对象重新复制到同一个存储桶中

亚马逊文档中的详细解释

权限

您需要 s3:GetObject 权限才能执行此操作。 有关详细信息,请参阅在策略中指定权限。 如果您请求的对象不存在,Amazon S3 返回的错误取决于您是否还具有 s3:ListBucket 权限。

 If you have the s3:ListBucket permission on the bucket, Amazon S3 returns an HTTP status code 404 ("no such key") error. If you don't have the s3:ListBucket permission, Amazon S3 returns an HTTP status code 403 ("access denied") error.

以下操作与 HeadObject 相关:

 GetObject

来源: https ://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html

也许这会对某人有所帮助。 就我而言,我正在运行 CodeBuild 作业,并且 CodeBuild 执行角色对 S3 具有完全访问权限。 我试图通过 CLI 列出 S3 存储桶中的密钥。 但是,我在aws-cli Docker 映像中使用 CLI,并根据本文通过环境变量传递凭据:

https://docs.aws.amazon.com/codebuild/latest/userguide/troubleshooting.html#troubleshooting-versions

无论我尝试什么,任何使用aws s3api ...的调用都会失败并出现同样的 403 错误。 我的解决方案是转换为普通的 s3 CLI 调用(而不是 s3api CLI 调用):

aws s3 ls s3://bucket/key --recursive

这种改变奏效了。 使用aws s3api did not

问题在于您为您正在使用的角色授予警察权限,如果您使用 AWS Glue,您需要创建具有这些权限的警察, https://docs.aws.amazon.com/glue/latest/dg/create- sagemaker-notebook-policy.html

这将解决"(403) occurred when calling the HeadObject operation: Forbidden"

如果有人最终来到这里并试图在 terraform 中实施解决方案,这是我的:

module "s3_files_label" {
  source      = "git::https://github.com/cloudposse/terraform-null-label.git?ref=0.24.1"
  namespace   = var.client
  environment = var.environment
  attributes  = ["backend-api-logs"]
}

module "s3_files" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "2.7.0"

  bucket = module.s3_files_label.id
  acl    = "private"

  cors_rule = jsonencode([
    {
      allowed_headers = ["*"]
      allowed_methods = ["GET", "PUT", "POST"]
      allowed_origins = ["https://${var.route53_domain}"]
      expose_headers  = []
      max_age_seconds = 0
    }
  ])
}

module "s3_user" {
  source      = "cloudposse/iam-system-user/aws"
  version     = "0.20.2"
  namespace   = var.client
  environment = var.environment
  name        = "s3-user"

  inline_policies_map = {
    s3 = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:ListBuckets",
                "s3:ListBucket",
                "s3:HeadObject",
                "s3:GetObject"
            ],
            "Resource": [
                "${module.s3_files.s3_bucket_arn}",
                "${module.s3_files.s3_bucket_arn}/*"
            ]
        },
        {
            "Sid": "list",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
EOF
  }

  tags = module.config.tags
}

我遇到了这个问题,但解决方案与上述不同 - 我试图通过传输加速端点来解决它,但它没有在 S3 存储桶上启用。

除了其他答案之外,该错误还可能是由于缺少用于 S3 存储桶的 SSE-KMS 的 KMS 密钥的权限。

就我而言,我的政策没有"s3:HeadObject",权限

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:HeadObject"
            ],
            "Resource": [
                "arn:aws:s3:::<your_bucket_name>",
                "arn:aws:s3:::<your_bucket_name>/*"
            ],
            "Effect": "Allow"
        }
    ]
}

将此策略分配给分配给您的 ec2(或任何尝试访问您的 S3 的服务)的 IAM 角色

我遇到过同样的问题。 我 99% 确定这是由于缺乏权限,所以我将 IAM 角色的策略更改为完全访问权限,尽管这不是好的做法。 使用:

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

正如其他人的上述评论所述。

然而,这并没有奏效,因为我在周日晚上刚刚创建了我的 AWS 账户,我想立即使用它。 我当时在美国东部地区,比我的时间晚了 12 个小时。 我花了整整一夜的时间试图解决这个问题,但没有成功。

周二下午,我在同一台笔记本电脑上回来,一切都很顺利。

权限的更改需要几分钟是不正确的。 最长可能需要 48 小时。

我会简单地使用以下 AWS IAM 策略,牢记最佳 AWS 最佳实践和最小特权原则:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Sid1",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": [
                "arn:aws:s3:::[BUCKET_NAME]"
            ]
        },
        {
            "Sid": "Sid2",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::[BUCKET_NAME]/*"
            ]
        }
    ]
}

这是由于未授权访问存储桶。 你应该像这样重新配置:

aws configure

输入您的访问密钥和秘密访问密钥。 然后将默认区域名称设置为与存储区域相同。

它会工作。

您缺少HeadBucket权限。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM