【问题标题】:AWS Lambda function seems to ignore its specified Execution RoleAWS Lambda 函数似乎忽略了其指定的执行角色
【发布时间】:2018-06-22 12:01:10
【问题描述】:

我想做什么

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

虽然只有一个 Bucket,它不需要访问其他任何东西。

我做了什么

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

测试函数实际上会产生我希望不可用的 Bucket 的内容。此外,s3:listObjects 甚至不在我的 Allowed 操作中。

我忽略了什么?

Lambda 函数

它的代码:

'use strict';

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

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

它的执行角色:

{
  "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"
    }
  ]
}

【问题讨论】:

  • 我们看不到你的回调函数做了什么,但大概你 100% 确定它正在列出对象。仔细检查为 Lambda 函数配置的角色,然后仔细检查与该角色关联的策略列表。 PS 你应该授予你的 Lambda 函数对 CloudWatch Logs (logs:*) 的权限,否则它将无法写入日志。
  • 执行角色中的Allow 效果不会将您在函数中可以做的事情限制为仅限于那些事情Allow 是附加的,不是排他的。如果存储桶策略或存储桶 ACL 允许某个操作,则 Lambda 函数可以执行此操作,而无需执行角色策略中的特定引用。
  • 还要注意没有s3:ListObjects这样的操作。文档中提到了它,但这是未来的功能或文档错误。 s3:ListBucket 是允许在存储桶中列出对象的操作。
  • @Michael-sqlbot 不知何故,NodeJS 的 aws-sdk 只知道 s3.listObjects,那里没有 listBucket。此外,here 文档似乎非常清楚地确实否认没有明确允许的内容。另外,Policy Simulator 确实给了我我期望的行为。
  • @Michael-sqlbot 实际上,我必须明确拒绝一切。 "Action": "*", "NotResource": [ "arn:aws:s3:::orca-resources/*", "arn:aws:s3:::orca-resources" ]。你是对的。我认为您必须通过 Role 的策略 THEN Bucket 的策略,但系统似乎比我想象的要宽松!

标签: amazon-web-services amazon-s3 aws-lambda


【解决方案1】:

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

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

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

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

问:什么是 IAM 角色?

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

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

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

当您的 Lambda 函数被调用时,Lambda 服务本身会调用 Session Token Service 中的AssumeRole

AssumeRole

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

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

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

AWS SDK 然后automatically uses these environment variables 对您在 Lambda 函数中生成的所有请求进行签名。

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

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

最后一点是您的假设模糊不清的地方。

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

  • 发出请求的委托人是否有权从其自己的帐户发出请求,并且
  • 发出请求的委托人是否有权拥有资源的帐户发出请求

这是两个问题,但当委托人(角色)和资源(存储桶)属于同一个账户时,它们可以合并为一个问题,通过组合来自多个地方的结果来回答。

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

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

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

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

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

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

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

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

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

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

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

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

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

否则,您只能单独测试角色策略。


请注意,文档中关于列出存储桶中对象的 S3 策略存在一些混淆。 The action for allowing this in IAM policies is s3:ListBucket 尽管 Node.JS SDK 方法调用是 listObjects()。策略模拟器中有一个名为 ListObjects 的操作,它要么是计划/未来功能的一部分,要么只是一个错误,因为最后检查不对应于 S3 的有效 IAM 策略操作。在S3 section of the IAM User Guide 中,s3:ListBucket 正确超链接到 S3 API 参考中的 List Objects 操作,但 s3:ListObjects 是一个循环超链接,直接返回到 IAM 用户指南中的同一页面(无处链接)。到目前为止,我尝试在 AWS 上找人来解释或更正这种差异,但没有成功。

【讨论】:

  • 非常感谢您非常提供这个非常有启发性和受过教育的答案!仍然让我想知道在访问离开帐户自己的资源时访问控制是否会有所不同,但至少现在它确实都有意义 - 再次感谢。
猜你喜欢
  • 2011-05-20
  • 1970-01-01
  • 2017-03-21
  • 2016-04-08
  • 2021-06-02
  • 2021-10-28
  • 2016-09-30
  • 2016-03-16
  • 2014-02-03
相关资源
最近更新 更多