AWS Lambda函数似乎忽略了其指定的执行角色

ccj*_*mne 3 amazon-s3 amazon-web-services aws-lambda

我正在尝试做什么

让 Lambda 函数访问(具有读写权限)我拥有的特定存储桶

不过,只有一个存储桶,它不需要访问其他任何东西。

我做了什么

  1. 我设置了一个公共存储桶(实际上是对的,我实际上希望任何人都可以访问它的内容),名为orca-resources
  2. 我创建了一个名为 的 IAM 角色lamba-s3-orca-resources。它被设置为供 Lambda 服务使用。
  3. 我创建了一个 Lambda 函数,最终将由 API Gateway 触发
  4. 我编写了尽可能少的代码来尝试破坏我的策略:我正在访问我的另一个lamba-s3-orca-resources存储桶,该存储桶未明确允许我的IAM 角色访问

测试该函数实际上会产生我希望不可用的存储桶的内容。而且,s3:listObjects甚至不在我的Allow《行动》中。

我在忽略什么?

拉姆达函数

其代码:

'use strict';

const aws = require('aws-sdk');
const s3 = new aws.S3();

exports.handler = (event, context, callback) => {
    s3.listObjects({Bucket: 'orca-exe'}, callback);
};
Run Code Online (Sandbox Code Playgroud)

其执行作用:

{
  "roleName": "lamba-s3-orca-resources",
  "policies": [
    {
      "document": {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
              "s3:PutObject",
              "s3:GetObject",
              "s3:GetObjectTagging",
              "s3:ListBucket",
              "s3:DeleteObject"
            ],
            "Resource": [
              "arn:aws:s3:::orca-resources/*",
              "arn:aws:s3:::orca-resources"
            ]
          }
        ]
      },
      "name": "orca-resources-only",
      "type": "inline"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*bot 6

\n

“AWS Lambda 函数似乎忽略了其指定的执行角色”

\n
\n\n

从某种意义上说,这是事实,而且是有意为之,因为 Lambda 服务或您的函数实际上并不知道执行角色的详细信息。Lambda 函数和 Lambda 基础设施实际上并不查看或了解与执行角色关联的权限。Lambda 不负责执行此政策。

\n\n

幕后有一些黑魔法将所有这些缝合在一起,了解其工作原理可能有助于解释为什么您所看到的行为是预期的和正确的。

\n\n

首先,Lambda 执行角色是 IAM 角色。

\n\n
\n

问:什么是 IAM 角色?

\n\n

IAM 角色是一个 IAM 实体,它定义了一组用于发出 AWS 服务请求的权限。IAM 角色不与特定用户或组关联。相反,受信任的实体承担角色,例如 IAM 用户、应用程序或 AWS 服务(例如 EC2)。

\n\n

https://aws.amazon.com/iam/faqs/

\n
\n\n

当您担任角色时,系统会向您颁发一组临时凭证 - 访问密钥和秘密(类似于 IAM 用户凭证)以及传达相关权限的安全或会话令牌,所有这些凭证在使用时都必须附带这些凭证。用于签署请求。在 Lambda 函数中,这一切都是自动完成的。

\n\n

当您的 Lambda 函数被调用时,Lambda 服务本身会调用AssumeRole会话令牌服务。

\n\n
\n

AssumeRole

\n\n

返回一组临时安全凭证(由访问密钥 ID、秘密访问密钥和安全令牌组成),您可以使用它们来访问您通常无法访问的 AWS 资源。

\n\n

https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html

\n
\n\n

此操作(您的角色的信任策略允许)返回一组凭证,这些凭证将作为环境变量放入 Lambda 容器的环境中,其名称类似于AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN(具体名称取决于环境))。

\n\n

然后,AWS 开发工具包会自动使用这些环境变量对您在 Lambda 函数中生成的所有请求进行签名。

\n\n

Lambda 中没有任何内容根据角色策略筛选这些请求,原因有几个:与简单地允许目标服务的正常身份验证和授权机制对目标服务进行身份验证和授权相比,这将是一个更加复杂且容易出现漏洞的解决方案。请求...但也许更重要的是,Lambda 服务实际上无法告诉您的代码正在通过 AWS SDK 尝试执行哪些操作,因为这些请求默认情况下通过 HTTPS 传输到服务端点,因此不可能他们要接受检查。

\n\n

然后,您发出请求的服务将验证凭据并在 IAM 和 STS 的帮助下授权请求 - 确定请求签名是否有效、附带的令牌是否有效以及针对指定资源尝试的操作是否有效。允许。

\n\n

最后一点是你的假设模糊的地方。

\n\n

处理请求的服务必须回答两个问题:

\n\n
    \n
  • 发出请求的委托人是否拥有其自己帐户的许可发出请求,以及
  • \n
  • 发出请求的主体是否拥有拥有该资源的账户的权限权限来发出请求
  • \n
\n\n

这是两个问题,但是当主体(角色)和资源(存储桶)由同一帐户拥有时,它们可以合并为一个问题,通过组合多个位置的结果来回答该问题。

\n\n
\n

访问策略描述谁有权访问什么。您可以将访问策略与资源(桶和对象)或用户关联。因此,您可以将可用的 Amazon S3 访问策略分类如下:

\n\n

基于资源的策略\xe2\x80\x93 存储桶策略和访问控制列表 (ACL) 是基于资源的,因为您将它们附加到 Amazon S3 资源。

\n\n

用户策略\xe2\x80\x93 您可以使用 IAM 管理对 Amazon S3 资源的访问。您可以在您的账户中创建 IAM 用户、组和角色,并向他们附加访问策略,授予他们对 AWS 资源(包括 Amazon S3)的访问权限。

\n\n

当 Amazon S3 收到请求时,它必须评估所有访问策略以确定是授权还是拒绝该请求。有关 Amazon S3 如何评估这些策略的更多信息,请参阅Amazon S3 如何授权请求

\n\n

https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-overview.html

\n
\n\n

正如您在评论中指出的那样,这解释了明显矛盾的行为:

\n\n
\n

“此外,这里的文档似乎非常明确地否认了未明确允许的内容。”

\n
\n\n

文档是正确的,您也是正确的,只是您没有考虑到明确允许的内容包括资源所有者(存储桶的帐户所有者)已经明确允许的内容。

\n\n

如果存储桶所有者允许每个人执行特定操作……那么,您的 Lambda 函数的执行角色就是每个人的一部分。因此,在 Lambda 执行角色策略中授予访问权限是多余且不必要的,因为账户所有者已经将该权限授予了所有人Deny角色政策中缺乏明确的意味着明确的Allow意味着存储桶策略中的显式允许发生建议的操作。

\n\n
\n

另外,政策模拟器确实给了我我所期望的行为。”

\n
\n\n

策略模拟器不会对真实服务进行真正的调用,因此当像存储桶这样的资源有自己的策略时,有必要在模拟中显式包含资源本身的策略。

\n\n
\n

要在模拟器中使用基于资源的策略,您必须在模拟中包含该资源,并选中该复选框以在模拟中包含该资源的策略。

\n\n

https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html

\n
\n\n

否则,您只是孤立地测试角色策略。

\n\n
\n\n

请注意,有关列出存储桶中对象的 S3 策略的文档中存在一些混乱。 尽管 Node.JS SDK 方法调用是 ,但在 IAM 策略中允许执行此操作s3:ListBucketlistObjects()。策略模拟器中有一个名为的操作,ListObjects它要么是计划/未来功能的一部分,要么只是一个错误,因为最后检查该操作与 S3 的有效 IAM 策略操作不对应。在IAM 用户指南 的 S3 部分中,s3:ListBucket正确地超链接到 S3 API 参考中的列出对象操作,但却s3:ListObjects是一个循环超链接,直接返回到 IAM 用户指南中的同一页面(无处链接)。我已经尝试在 AWS 寻找人员来解释或纠正这种差异,但到目前为止还没有成功。

\n