通过来自确定的 IP 范围和 Lambda 的预签名 URL 限制 S3 访问。不能结合这两个条件 - S3 政策

Restrict S3 access by pre-signed URLs from determined IP range and Lambda. can't combine both conditions - S3 Policy

最近我开始致力于保护对我的 S3 存储桶的访问,我有两个来源,我想授予访问权限和拒绝访问任何不同的来源。

在这种情况下,获取访问权限的来源是,例如我的本地 IP 或 VPC IP 范围和 Lambda 函数。

我创建了以下 S3 存储桶策略:

{
    "Version": "2019-10-10",
    "Statement": [
        {
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::480311425080:role/<lambda role name>",
                    "arn:aws:sts::480311425080:assumed-role/<lambda role name>/<Lambda function name>"
                ],
                "Service": "lambda.amazonaws.com"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<bucket name>/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "<ip adress>/32",
                        "<ip adress>/32"
                    ]
                }
            }
        }
    ]
}

如您所见,我使用 NotPrincipal 来排除我的相应角色和 Lambda 被拒绝,我使用 NotIpaddress 来排除我的有效 IP 被拒绝。

在这种情况下,我仍然可以从我的 Lambda 函数连接到 S3,但也仍然可以从 "supposidly none authorized IPs" 连接到它。所以条件

            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "<ip adress>/32",
                        "<ip adress>/32"
                    ]
                }
            }

没有按预期工作。

也许您会告诉我们只为 NotPrincipal 使用角色 ARN,但它也不起作用。

仅将主体作为角色"without specifying the arn with lambda function"

            "NotPrincipal": {
                "AWS": "arn:aws:iam::880719415082:role/lambda_s3_access"
            },

应用IP过滤条件,但Lambda无法连接

有什么想法吗?

亲切的问候,

Rshad

A​​mazon S3 存储桶默认是私有的。因此,没有必要使用 Deny 语句 除非您希望覆盖其他策略中授予的权限。 (例如Admins可以访问所有的bucket,但是这个bucket是一个例外。)

授予 Lambda 函数 访问 Amazon S3 存储桶的权限:

  • 创建具有访问存储桶权限的 IAM 角色
  • 将 IAM 角色分配给 Lambda 函数

如果您希望 Amazon EC2 实例 也可以访问存储桶,请为该实例分配类似的角色。通常,不需要分配存储桶访问权限 "to a VPC"。相反,向希望访问存储桶的资源授予权限。

要从您的自己的(个人)IP 地址 授予对存储桶的访问权限,请在所需的 S3 存储桶上创建存储桶策略:

{
  "Version": "2012-10-17",
  "Id": "S3PolicyId1",
  "Statement": [
    {
      "Sid": "IPAllow",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::examplebucket/*",
      "Condition": {
         "IpAddress": {"aws:SourceIp": "54.240.143.55/32"}
      } 
    } 
  ]
}

我找到了评论问题的解决方案。下面,我评论一些细节。

有一个 VPC ...

1.Lambda 添加到 VPC `为此,请遵循:[1]

2.AWS S3 或您的 Lambda 函数将访问的任何其他 AWS 组件创建 VPC 端点,以便 Lambda 可以通过 VPC 方法访问它们。

3. 调整创建boto S3客户端的方式,使其使用path而不是通过virtual host连接到S3“这是默认方式”。这是通过以下方式完成的:

s3 = boto3.client('s3', 'us-west-2', config=Config(s3={'addressing_style': 'path'}))

详情请查看:[2]

编辑 2019 年 10 月 15 日

我们刚刚检查过,通过为 S3 创建 VPC endpoint,Lambda 能够与 S3 连接,而无需更改使用 boto3 创建客户端的方式。我们继续旧形式:

s3 = boto3.resource('s3')

然后我们丢弃:

s3 = s3 = boto3.client('s3', 'us-west-2', config=Config(s3={'addressing_style': 'path'}))

编辑结束 2019 年 10 月 15 日

4. 为 Lambda 中使用的 IAM 角色创建一个新策略,并使用它创建 presigned-urls。这样我们就可以限制对 IP 范围和 VPC 的访问 "to guarantee access for Lambda"

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "******/32",
                        "******/32"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpc": "vpc-******"
                }
            }
        }
    ]
}

参考资料:

[1] https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html

[2] https://boto3.amazonaws.com/v1/documentation/api/1.9.42/guide/s3.html#changing-the-addressing-style