S3存储桶策略和IAM角色冲突

时间:2016-08-17 04:50:10

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

我尝试使用S3存储桶策略提供对存储桶的一般访问权限,同时还允许使用角色策略对角色进行特定访问。 Lambda函数使用该角色来处理存储桶中的对象。它在第一个障碍时停止 - 它不能使用前缀“incoming /”获取任何内容,即使它在角色策略中被允许,并且未在存储桶策略中明确拒绝。

角色政策:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowBucketPut",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::bucket-name/*"
        },
        {
            "Sid": "AllowIncomingGetDelete",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::bucket-name",
            "Condition": {
                "StringLike": {
                    "s3:prefix": "incoming/*"
                }
            }
        }
    ]
}

注意:我还尝试删除条件并将资源更改为“arn:aws:s3 ::: bucket-name / incoming *”,这似乎只会改变策略模拟器的行为方式。另一个注意事项:来自存储桶的带有“incoming / *”前缀的GET在模拟器中工作,而不是在实践中。

我没有删除以下存储桶政策中的任何声明,因为我不确定可能相关的内容。 IP地址已被删除。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicList",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::bucket-name",
            "Condition": {
                "StringLike": {
                    "s3:prefix": "public*"
                }
            }
        },
        {
            "Sid": "AllowPublicGet",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket-name/public*"
        },
        {
            "Sid": "AllowPrivateList",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::bucket-name",
            "Condition": {
                "StringLike": {
                    "s3:prefix": "private*"
                },
                "IpAddress": {
                    "aws:SourceIp": [
                        "..."
                    ]
                }
            }
        },
        {
            "Sid": "AllowPrivateGet",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket-name/private*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "..."
                    ]
                }
            }
        },
        {
            "Sid": "AllowIncomingPut",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::bucket-name/incoming*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "..."
                    ]
                }
            }
        }
    ]
}

为文本墙道歉。

我不明白为什么我的角色无法使用前缀“incoming /".

获取对象

执行以下操作时,Lambda函数正在拒绝403访问:

S3.download_file(bucket, key, localfile)

2 个答案:

答案 0 :(得分:5)

根据文档(http://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html),s3:prefix条件仅适用于s3:ListBucket API,以强制调用者在ListBucket操作上指定前缀。它似乎不适用于GetObject API调用。

因此,条件为Allow的{​​{1}}上的GetObject与任何GET(对象)请求都不匹配(因为这些请求不包含策略密钥" s3:前缀"!),因此您实际上不允许在角色策略中使用这些请求。由于您似乎不会在存储桶策略中允许该请求,并且在任何地方都没有拒绝语句,因此您的Lambda代码被隐式拒绝

您应该使用s3:prefix == ...,正如您所提到的,您已尝试使用政策模拟器:Resource

此外 - 您可能有理由完全像您一样指定策略,但是当您想要描述前缀时,它似乎有点不寻常 - 通常是与S3相关的策略上的"Resource": "arn:aws:s3:::bucket-name/incoming/*"元素,将是"Resource",而不仅仅是...incoming/*。这可以防止一些意外的结果。例如,假设您有一个"文件夹"调用...incoming*,然后创建一个名为incoming/的文件夹。您编写策略的方式是,您可以授予对这两个前缀的访问权限!但同样 - 如果不真正了解环境的具体细节,很难说出你真正需要的东西。只是想确保你(以及其他任何读过这篇文章的人)都知道这个微妙(但很重要)的细节!

根据您给出的描述,这是我能想到的全部内容。如果您尝试进行这些更改,但仍然无效,请使用您尝试过的新政策相应地更新您的问题。祝你好运!

答案 1 :(得分:0)

您可以尝试将以下语句添加到存储分区策略吗?

    {
        "Sid": "AllowIncomingGet",
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::bucket-name/incoming/*",
        "Condition": {
            "IpAddress": {
                "aws:SourceIp": [
                    "..."
                ]
            }
        }
    }
相关问题