如何使用 SES 委托人和 IAM 角色委托人编写 AWS Bucket Policy

How to write AWS Bucket Policy with SES principal and IAM role principal

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

我试过两个语句,一个将主体设置为 'services',另一个设置为目标角色(添加两个只是为了看看是否可行)

{
"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/[文件 ID]

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

感谢任何帮助:D

让我知道是否需要添加任何其他内容

[更新]

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

角色:服务开发

此角色附加了两个策略。

1) 服务FS:

{
"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 的复选框,如果我 取消选中 然后模拟器说允许权限但是如果我 选中 然后我得到以下错误: The simulation could not be performed! : Simulation failed!

据我了解您的要求,您需要一个 S3 存储桶策略(以允许 SES 将对象放入您的 S3 存储桶)并且您需要一个 IAM 角色,您的 Lambda 函数将使用该角色列出该存储桶并 put/get 该桶中的对象。 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/* 资源——它是对桶而不是对象的操作)