如何限制对特定VPC的S3存储桶访问,同时允许控制台访问。

3
我正在设置一些S3存储桶,并希望将它们的访问限制在VPC中,同时仍允许从AWS控制台访问这些存储桶。
此处所建议的,我已创建了一个S3终端节点,并将其添加到主路由表中。终端节点上的策略允许对所有资源进行完全访问。
我创建了一个S3策略(见下文)并将其添加到了存储桶中。但是,一旦我保存该策略,就无法从控制台访问该存储桶。
我还尝试在“StringNotEquals”条件中明确添加一个用户,格式为“aws:username”:“user1”,但没有成功。
{
"Version": "2012-10-17",
"Id": "Policy-S3-Bucket-myBucket",
"Statement": [

    {
        "Sid": "Access-via-VPC-only",
        "Principal": "*",
        "Action": "s3:*",
        "Effect": "Deny",
        "Resource": [
            "arn:aws:s3:::myBucket",
            "arn:aws:s3:::myBucket/*"
        ],
        "Condition": {
            "StringNotEquals": {
                "aws:sourceVpc": "vpc-01c9d66c12345"
            }
        }
    },
    {
        "Sid": "Allow-console-access",
        "Action": [
          "s3:*"
        ],
        "Effect": "Allow",
        "Resource": [
          "arn:aws:s3:::myBucket",
          "arn:aws:s3:::myBucket/*"
      ],
        "Principal": {
          "AWS": [
            "arn:aws:iam::<account-id>:user/user1", "arn:aws:iam::<account-id>:user/user2"
          ]
        }
      }
]
}

预期结果是S3存储桶仅可通过上述VPC和AWS控制台进行访问。

实际结果为:

存储桶概览显示“错误:拒绝访问”,权限页面(公共访问设置)显示:“您无权查看此配置。请联系您的帐户管理员请求访问权限。”

我必须使用根用户登录并删除策略,以恢复对存储桶的访问。


当您说要允许从控制台访问时,您实际上是指希望S3存储桶对特定的IAM用户可访问(无论使用何种机制,包括控制台、SDK、AWSCLI),还是仅仅指控制台访问?您尝试创建的策略表明您想要实现后者。 - jarmod
具体来说,我想通过AWS控制台使S3存储桶对管理员(IAM)用户可用。这意味着直接在控制台中编辑存储桶配置、更改策略等。目前这是不可能的。通过SDK和AWSCLI访问也很好,尽管我目前不知道如何实现。在SDK / CLI方面,我会使用角色(再次,我需要弄清楚正确的方法是什么)。 - Michael Boeni
你能测试一下只包含第一个“deny”语句的策略(删除当前拥有的“allow”语句),并将条件修改为:“StringNotEquals”:{“aws:sourceVpce”:“vpc-01c9d66c12345”,“aws:username”:“user1”,“aws:username”:“user2”}。最好在你不关心的新存储桶上进行测试,以防万一。 - jarmod
我已经尝试过了。看起来这将导致一个AND语句,而不是OR。据我所理解,您可以为单个键设置多个值,这些值被视为“OR”。另一方面,两个键被视为AND。因此,上述内容需要同时满足"aws:sourceVpce" = "vpc-01c9d66c12345" AND "aws:username" = "user1" 两个语句才能成立。 - Michael Boeni
是的,这是一个AND。然而,我提出的策略无论如何都不会起作用,因为您不能在同一条件中拥有多个aws:username元素。 - jarmod
4个回答

0

我找到了一个看起来可行的解决方案。我已经在策略模拟器中进行了测试,它在实际环境中也似乎能够正常工作。以下策略可以解决问题:

{
    "Version": "2012-10-17",
    "Id": "Policy-S3-Bucket-myBucket",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:username": ["user1", "user2"]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": ["s3:ListBucket"],
            "Resource": ["arn:aws:s3:::myBucket"],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpc": "vpc-01c9d66c12345"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": ["s3:ListBucket"],
            "Resource": ["arn:aws:s3:::myBucket"],
            "Condition": {
                "StringEquals": {
                    "aws:username": ["user1", "user2"]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": ["arn:aws:s3:::myBucket/*"],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpc": "vpc-01c9d66c12345"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": ["arn:aws:s3:::myBucket/*"],
            "Condition": {
                "StringEquals": {
                    "aws:username": ["user1", "user2"]
                }
            }
        }
    ]
}

该策略要求源VPC字符串或用户名必须符合条件中列出的内容之一。

不可否认,该策略冗长而且存在大量重复。如果有人有更高效解决方案的想法,我非常乐意倾听。


请注意,此策略允许来自vpc-01c9d66c12345的访问,但不会阻止其他VPC的访问。因此,在某种意义上,它并没有“将对[VPC中的S3存储桶]的访问限制为一个VPC”,这是您所声明的要求之一。除非您真的需要防止来自其他VPC的访问,否则可能可以接受这种情况 - 就目前而言,例如,拥有s3:*权限的任何人都可以从另一个VPC访问此存储桶。 - jarmod
嗯,那不是意图。什么让你觉得其他VPC可以访问这些桶?这只有在您是指定用户之一时才有效,不是吗?因此,如果您要么在提到的VPC中,要么是user1或user2,则可以访问,否则您就不能访问...对吗? - Michael Boeni
运行时的有效策略是S3存储桶策略和客户端拥有的IAM策略的组合。例如,如果客户端拥有允许对资源:* 进行s3:* 操作的IAM策略,则他们可以写入此S3存储桶 - 存储桶策略中没有任何内容会拒绝该IAM访问。S3存储桶策略并没有明确允许它,但也没有明确拒绝它,而IAM策略将允许它。策略评估为显式拒绝 > 显式允许 > 隐式拒绝。默认情况下,在缺少策略的情况下,所有内容都是隐式拒绝,正如您所期望的那样。 - jarmod

0

这个策略已经经过测试,可以提供您所需的一切:

 Statement": {        
        "Sid": "Allow-anonymous-access-from-specific-VPC",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::bucket_name/*",
        "Condition": {
            "StringEquals": {
                "aws:SourceVpc": "some-vpc-id"
            }
        }
    }

这将允许来自“some-vpc-id”的请求进行匿名访问,同时仍然允许AWS控制台访问。

您的VPC必须配置S3端点才能正常工作。


0

我曾经遇到过同样的问题。 当我尝试从在线示例中使用严格拒绝选项时,我失去了对我的存储桶的控制台访问权限(我猜这种情况发生在很多人身上)。我不得不在VPC中的堡垒主机上从aws控制台中删除存储桶。

最终对我有效的版本是这个(使用全新的存储桶)。 请注意,存储桶具有以下特点:

Block all public access
✅ On

所以似乎默认情况下是拒绝的,然后这个允许策略就有意义了。

{
    "Version": "2012-10-17",
    "Id": "Policy-S3-Bucket-myBucket",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::bucket_name",
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpce": "some-vpce-id"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::bucket_name/*",
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpce": "some-vpce-id"
                }
            }
        }
    ]
}

我测试了下载链接,从我的电脑上失败了,但是从VPC内的堡垒主机上成功了,因此似乎仍然正确地拒绝公共流量。


-1

关键在于除非来自用户或VPC,否则拒绝所有内容,但必须处于相同的条件。策略的工作方式是拒绝规则优先于其他规则,因此如果您拒绝了,那么您不能在随后的规则中允许;它已经被拒绝了,就是这样。

顺便说一下,根用户的aws:userid是账户ID。可能使用此用户是一个不好的做法,但没办法 :P

因此,我的存储桶现在只接受来自VPC和通过AWS Web控制台登录的用户的流量(这样我就不会在Web控制台中遇到访问被拒绝的错误)。

{
"Version": "2012-10-17",
"Id": "Policy154336817545456388",
"Statement": [
    {
        "Sid": "Block-if-not-from-VPC-or-Me",
        "Effect": "Deny",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": [
            "arn:aws:s3:::bucket-name",
            "arn:aws:s3:::bucket-name/*"
        ],
        "Condition": {
            "StringNotEquals": {
                "aws:SourceVpce": "vpce-4598ujfjrhc",
                "aws:userid": "576767373466"
            }
        }
    }
    ]
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接