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

unc*_*eat 3 lambda amazon-s3 amazon-web-services 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/*"
                }
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

注意:我还尝试了删除条件并将资源更改为“ 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": [
                        "..."
                    ]
                }
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

致歉的文字墙。

我不明白为什么我的角色无法获取带有前缀“ incoming /”的对象。

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

S3.download_file(bucket, key, localfile)
Run Code Online (Sandbox Code Playgroud)

Bru*_*eis 5

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

正因为如此,你AllowGetObject与条件s3:prefix == ...不匹配任何GET(对象)的请求(因为这些请求不包含政策重点“S3:前缀”!),所以你有效地不允许在角色政策这些请求。由于您似乎也不允许在存储桶策略上使用该请求,并且在任何地方都没有Deny语句,因此您的Lambda代码被隐式拒绝

您应该使用一个Resource替代,正如你所说,你已经尝试对政策模拟器:"Resource": "arn:aws:s3:::bucket-name/incoming/*"

另外-您可能有理由完全像以前那样指定策略,但这似乎有点不寻常-通常"Resource",当您要描述前缀时,与S3相关的策略上的元素将类似于...incoming/*,而不是只是...incoming*。这样可以防止某些意外结果。例如,假设您有一个名为的“文件夹” incoming/,然后创建了一个名为的文件夹incoming-top-secret/。您编写策略的方式将授予对这两个前缀的访问权限!但是,再次重申-在不真正了解环境的确切细节的情况下,很难说出您真正需要什么。只是想确保您(和其他阅读此书的人)知道这个细微(但很重要)的细节!

根据您的描述,这就是我能想到的。如果您尝试了这些更改,但仍然无法使用,请使用您尝试过的新政策相应地更新您的问题。祝好运!


小智 0

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

    {
        "Sid": "AllowIncomingGet",
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::bucket-name/incoming/*",
        "Condition": {
            "IpAddress": {
                "aws:SourceIp": [
                    "..."
                ]
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)