【问题标题】:How to write AWS Bucket Policy with SES principal and IAM role principal如何使用 SES 主体和 IAM 角色主体编写 AWS 存储桶策略
【发布时间】:2019-04-07 00:42:01
【问题描述】:

我最初设置 SES 来接收电子邮件,在此过程中,我创建了一个存储桶策略,允许该服务将电子邮件放入 S3。我现在有一个 lambda 函数,它应该能够使用 STS 承担角色并访问同一个存储桶。不幸的是,我无法找出正确的策略来允许服务和 IAM 角色访问同一个存储桶,现在我得到“拒绝访问”。我使用策略模拟器来验证其他所有功能是否正常运行,例如,我添加了一个通用策略,其中包含针对目标角色的更多操作,如果我告诉模拟器忽略存储桶策略,那么它会说它可以访问文件。

我尝试了两个语句,一个将主体设置为“服务”,另一个设置为目标角色(添加两个只是为了看看是否可以工作)

{
"Version": "2012-10-17",
"Id": "Policy1478013193612",
"Statement": [
    {
        "Sid": "Stmt1478013187203",
        "Effect": "Allow",
        "Principal": {
            "Service": "ses.amazonaws.com"
        },
        "Action": [
            "s3:PutObject",
            "s3:GetObject"
        ],
        "Resource": "arn:aws:s3:::email-01-bucket/*"
    },
    {
        "Sid": "Stmt55",
        "Effect": "Allow",
        "Principal": {
            "AWS": [
                "arn:aws:sts::[id-num-with-no-dashes]:assumed-role/[role-name]/[session-name]",
                "arn:aws:iam::[id-num-with-no-dashes]:role/[role-name]"
            ]
        },
        "Action": [
            "s3:PutObject",
            "s3:GetObject"
        ],
        "Resource": "arn:aws:s3:::email-01-bucket/*"
    }
]
}

我也尝试将它放在 1 语句中:

{
"Version": "2012-10-17",
"Id": "Policy1478013193612",
"Statement": [
    {
        "Sid": "Stmt1478013187203",
        "Effect": "Allow",
        "Principal": {
            "AWS": [
                "arn:aws:sts::[id-num-with-no-dashes]:assumed-role/[role-name]/[session-name]",
                "arn:aws:iam::[id-num-with-no-dashes]:role/[role-name]"
            ],
            "Service": "ses.amazonaws.com"
        },
        "Action": [
            "s3:PutObject",
            "s3:GetObject"
        ],
        "Resource": "arn:aws:s3:::email-01-bucket/*"
    }
]
}

顺便说一句,文件路径是: arn:aws:s3:::email-01-bucket/email/[file-id]

我无法放入 ListBucket,因为它会引发错误。

任何帮助表示赞赏:D

如果我应该添加其他内容,请告诉我

[更新]

为了使找到正确的策略更容易,我将描述我目前在 IAM 策略模拟器中设置的内容,我假设如果我们可以让它在这里工作,那么它应该可以在 lambda 函数上工作。

角色:服务开发

此角色附加了两个策略。

1) 服务文件系统:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
            "s3:PutObject",
            "s3:GetObject",
            "s3:PutBucketLogging",
            "s3:ListBucket"
        ],
        "Resource": "arn:aws:s3:::email-01-bucket/*"
    }
]
}

2) AWSLambdaBasicExecutionRole

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
        ],
        "Resource": "*"
    }
]
}

在策略模拟器中:

下拉列表Select Service 设置为S3

下拉列表Select Action 设置为GetObject

Resource > Object 下输入现有文件arn:aws:s3:::email-01-bucket/email/u245hnt85uivpfkrrlhgo0jt86gfjgnca2fgocg1 的路径(在仔细检查文件是否确实存在之后)

一旦我这样做了,现在左侧有一个 Resource Policies 部分,它向我显示了附加到我的存储桶的存储桶策略,其中包含以下策略:

{
"Version": "2012-10-17",
"Id": "Policy1478013193612",
"Statement": [
    {
        "Sid": "Stmt1478013187203",
        "Effect": "Allow",
        "Principal": {
            "Service": "ses.amazonaws.com"
        },
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::email-01-bucket/*"
    }
]
}

现在这里是我迷路的地方,回到Resource > Object 区域,我在该区域指定现有文件的路径,如果我取消选中,则有一个标记为Include Resource Policy 的复选框> 然后模拟器说允许该权限,但是如果我 check 它然后我得到以下错误: The simulation could not be performed! : Simulation failed!

【问题讨论】:

  • 向 Lambda 函数授予权限的典型方式是让与 Lambda 函数的 IAM 角色关联的策略授予权限。您通常不会通过 S3 存储桶策略执行此操作(除非您专门尝试拒绝所有委托人除了该 IAM 角色)。
  • 就像我在开头提到的,存储桶策略是为 SES 服务添加的,我仍然需要这个服务才能工作,所以我不能删除它。我还尝试使用仅将 SES 作为主体的存储桶策略,然后针对 IAM 角色使用单独的策略,但我仍然收到“拒绝访问”。
  • 存储桶策略确实需要 SES 权限,但它不需要并且通常不应该具有 Lambda 权限。独立于存储桶策略调试 Lambda 权限。
  • @jarmod 我做了,在验证其他一切是否正常工作时,我创建了一个 IAM 角色策略,其中包含所有必需的 S3 存储桶相关操作。在策略模拟器中,当切换“包含资源策略”选项“关闭”时它可以工作,但如果我将其“打开”则不会。似乎存储桶策略与角色权限冲突。
  • 存储桶策略不会与 IAM 策略冲突,除非存储桶策略有 Deny 语句。让我们更好地了解您的 Lambda 正在调用哪些 API 调用,以及为什么它的 IAM 角色不足。除了 GetObject 和 PutObject,您的 Lambda 还在做什么?

标签: amazon-web-services amazon-s3 amazon-ses amazon-policy


【解决方案1】:

据我了解您的要求,您需要一个 S3 存储桶策略(以允许 SES 将对象放入您的 S3 存储桶),并且您需要一个 IAM 角色,您的 Lambda 函数将使用该角色列出该存储桶并放置/获取那个桶里的对象。 IAM 角色还需要信任关系,允许 AWS Lambda 服务代表您代入该角色(这样您就不必在代码中手动代入该角色)。

具体来说:

  • 不要将 Lambda 权限添加到 S3 存储桶策略
  • 不要在 Lambda 中使用 STS 来承担角色;只需使用该角色配置 Lambda
  • 通常情况下,您不必在 Lambda 函数中显式编写与担任角色或获取权限相关的任何内容(Lambda 服务会为您完成这一切)

S3 存储桶策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowSESPuts",
            "Effect": "Allow",
            "Principal": {
                "Service": "ses.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::BUCKET-NAME/*",
            "Condition": {
                "StringEquals": {
                    "aws:Referer": "AWSACCOUNTID"
                }
            }
        }
    ]
}

IAM 角色:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "sidlist",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::BUCKET-NAME"
        },
        {
            "Sid": "sidputget",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::BUCKET-NAME/*"
        }
    ]
}

IAM 角色的信任关系:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

我不确定您为什么在示例中包含 s3:PutBucketLogging,但如果您确实需要它,请将其添加到 Lambda 的 IAM 角色中,以针对 arn:aws:s3:::BUCKET-NAME 资源(而不是 arn: aws:s3:::BUCKET-NAME/* 资源——这是对存储桶而不是对象的操作)

【讨论】:

  • 嗨@jarmod,我使用STS 的原因是因为我在本地测试我的代码,我不想每次都部署我的代码。我认为 STS 可以在我的本地和 lambda 函数中工作。最奇怪的事情发生了,在对我的策略进行了如此多的排列之后,我决定将所有内容恢复为我最初拥有的内容,并将角色策略更新为只有 2 个操作,get 和 put + 打开日志记录。我真的不知道怎么做,但我停止了权限问题,一切正常 O.O
  • 抱歉回复晚了,我出城了一会儿。无论如何,既然你是唯一一个回复并实际提供有用建议的人,我会告诉你重点:D
猜你喜欢
  • 2018-06-08
  • 2017-09-14
  • 2016-12-23
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多