访问受限于 VPC 端点的 S3 网站从 VPC 内部获取 403

S3 website with access restricted to VPC endpoint is getting 403 from inside the VPC

我想创建一个配置为用作网站的 S3 存储桶,并且我想将对 S3 网站的访问限制为来自特定 VPC 内部的请求 而已。

我正在使用 Cloudformation 设置存储桶和存储桶策略。

存储桶 CF 已启用 WebsiteConfiguration 并将 AccessControl 设置为 PublicRead

  ContentStorageBucket:
    Type: AWS::S3::Bucket
    Properties: 
      AccessControl: PublicRead
      BucketName: "bucket-name"
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html

存储桶策略包括两个条件:一个条件授予在办公室 IP 上访问存储桶的完全访问权限,另一个条件授予通过 VPC 端点的访问权限。代码如下:

  ContentStorageBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref ContentStorageBucket
      PolicyDocument:
        Id: BucketPolicy
        Version: '2012-10-17'
        Statement:
        - Sid: FullAccessFromParticularIP
          Action:
          - s3:*
          Effect: "Allow"
          Resource:
          - !GetAtt [ ContentStorageBucket, Arn ]
          - Fn::Join:
            - '/'
            - - !GetAtt [ ContentStorageBucket, Arn ]
              - '*'
          Principal: "*"
          Condition:
            IpAddress:
              aws:SourceIp: "x.x.x.x"
        - Sid: FullAccessFromInsideVpcEndpoint
          Action:
          - s3:*
          Effect: "Allow"
          Resource:
          - !GetAtt [ ContentStorageBucket, Arn ]
          - Fn::Join:
            - '/'
            - - !GetAtt [ ContentStorageBucket, Arn ]
              - '*'
          Principal: "*"
          Condition:
            StringEquals:
              aws:sourceVpce: "vpce-xxxx"

为了测试上述政策条件,我做了以下工作:

备注:

鉴于此,我目前不确定如何进一步调试它。您对可能出现的问题有什么建议吗?如果问题不清楚或有任何需要澄清的地方,请告诉我。感谢您的帮助!

为了让资源使用 S3 的 VPC 端点,VPC 路由器必须将发往 S3 的所有流量指向 VPC 端点。 AWS 允许您使用 BGP 前缀列表,而不是自行维护所有特定于 S3 的 CIDR 块的列表,这是 AWS 中的第一个 class 资源。

要查找 S3 运行 的前缀列表,请执行以下命令(您的输出应该与我的匹配,因为这应该是跨所有帐户的相同区域范围,但最好检查一下)。使用您的 VPC 的区域。

aws ec2 describe-prefix-lists --region us-east-1

我得到以下输出:

{
    "PrefixLists": [
        {
            "Cidrs": [
                "54.231.0.0/17",
                "52.216.0.0/15"
            ],
            "PrefixListId": "pl-63a5400a",
            "PrefixListName": "com.amazonaws.us-east-1.s3"
        },
        {
            "Cidrs": [
                "52.94.0.0/22",
                "52.119.224.0/20"
            ],
            "PrefixListId": "pl-02cd2c6b",
            "PrefixListName": "com.amazonaws.us-east-1.dynamodb"
        }
    ]
}

对于com.amazonaws.us-east-1.s3,前缀列表id为pl-63a5400a,

这样您就可以在 table 为相关子网提供服务的任何路由中创建一个路由。目的地应该是前缀列表 (pl-63a5400a),目标应该是 VPC 端点 ID (vpce-XXXXXXXX)(您可以通过 aws ec2 describe-vpc-endpoints 找到它)。

这在控制台上是微不足道的。我不记得如何从命令行执行此操作,我想你必须发送一个 cli-input-json 以及类似下面的内容,但我还没有测试过。这留作 reader 的练习。

{
  "DestinationPrefixListId": "pl-63a5400a",
  "GatewayId": "vpce-12345678",
  "RouteTableid": "rt-90123456"
}