【问题标题】:How to set same endpoint for set of S3 buckets on Amazon?如何为亚马逊上的一组 S3 存储桶设置相同的端点?
【发布时间】:2016-12-31 16:32:18
【问题描述】:

我有以下 S3 存储桶

  • “client1”
  • “client2”
  • ...
  • “clientX”

我们的客户通过 jar 应用程序将数据上传到他们的存储桶(client1 到存储桶 client1 等)。这是和平的代码:

BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3 s3client = new AmazonS3Client(credentials);
s3client.setRegion(Region.getRegion(Regions.US_EAST_1));
File file = new File(OUTPUT_DIRECTORY + '/' + fileName);
s3client.putObject(new PutObjectRequest(bucketName, datasource + '/' + fileName, file));

问题是,他们有用于输出流量的防火墙。他们必须在防火墙中允许 URL .amazonaws.com。是否可以将端点设置为我们的域 storage.domain.com ?

我们预计将来会更改区域,但我们所有的客户现在都被锁定到 amazonaws.com = US_EAST_1 区域 -> 我们所有的客户都需要更改防火墙中的规则。

如果端点是 storage.domain.com - 一切都会好的 :)

预期客户 URL 示例

  • client1 会将数据放到 URL client1.storage.domain.com
  • client2 会将数据放到 URL client2.storage.domain.com
  • clientX 会将数据放到 URL clientX.storage.domain.com

我们知道 CloudFront 中的设置,但它是按存储桶设置的。我们正在寻找一种全球 AWS 设置的解决方案。我们该怎么做?

非常感谢

【问题讨论】:

  • 部分答案很大程度上取决于您是否将使用 HTTPS。几乎不可想象你不会,但这是我们需要知道的一个细节。另外,为什么客户端需要打开您的整个域或整个子域,而不是客户端的特定域?而且,那些根据 IP 地址而不是主机名列入白名单的客户端呢?
  • 是的,我们将使用 HTTPS。我们希望所有客户端都有一个端点——一个上传点——防火墙中所有客户端的相同规则。易于管理。

标签: amazon-web-services amazon-s3 aws-sdk amazon-cloudfront


【解决方案1】:

这里有很多因素在起作用,其中最重要的是对 SSL 的支持。

首先,我们需要消除一个明显不起作用的选项:

S3 支持以域名命名每个存储桶,然后使用 CNAME 指向每个存储桶。因此,例如,如果您将存储桶命名为 client-1.storage.example.com,然后为 client-1.storage.example.com CNAME client-1.storage.example.com.s3.amazonaws.com 指向 DNS CNAME(在 Route 53 中),则此存储桶可在 Internet 上以 client-1.storage.example.com 访问。

这仅在您不尝试使用 HTTPS 时有效。限制的原因是多种因素的组合,这些因素超出了此答案的范围。没有仅使用 S3 的解决方法。解决方法需要额外的组件。

即使上面的场景不适用于您的应用程序,我们暂时假设它会,因为它使另一个问题很容易说明:

我们正在寻找一种全球 AWS 设置的解决方案

即使有可能,这也可能不是一个好主意。在上述场景中,您很想设置通配符 CNAME,以便 *.storage.example.com CNAME s3[-region].amazonaws.com 为您提供一个神奇的 DNS 条目,该条目适用于名称匹配 *.storage.example.com 并在适当区域创建的任何存储桶。 .. 但是这样的配置存在一个严重的漏洞——我可以创建一个名为sqlbot.storage.example.com 的存储桶(假设不存在这样的存储桶),现在我有一个您无法控制的存储桶,使用您域下的主机名,你没有任何办法知道它,或者阻止它。我可能会使用它来破坏您客户的安全,因为现在我的存储桶可以从您客户的防火墙内部访问,这要归功于通配符配置。

不,您确实需要自动化部署每个客户端的步骤,无论最终解决方案如何,而不是依赖于单一的全局设置。所有 AWS 服务(S3、Route 53 等)都适合自动化。

CloudFront 似乎它拥有最简单解决方案的关键,它允许您将每个客户端主机名映射到他们自己的存储桶。是的,这确实需要为每个客户端配置 CloudFront 分配,但此操作也可以自动化,并且每个 CloudFront 分配不收费。 CloudFront 的唯一费用是与使用相关的(每个请求和每 GB 传输)。这里的其他优势包括 SSL 支持(包括来自 ACM 的通配符 *.storage.example.com 证书,可以在多个 CloudFront 分配之间共享)以及使用 CloudFront 在路径中的事实,您不需要存储桶名称和主机名相同。

这还使您能够将每个存储桶放置在该特定存储桶最理想的区域中。但是,由于 CloudFront 施加的大小限制,它仅限于大小不超过 20 GB 的文件。

但是,将 CloudFront 用于具有大量上传的应用程序的问题当然是您要为上传支付带宽费用。在欧洲、加拿大和美国,它很便宜(0.02 美元/GB),但在印度要贵得多(0.16 美元/GB),其他地区的价格在这两个极端之间有所不同。 (您也使用 CloudFront 为下载付费,但在这种情况下,当通过 CloudFront 拉取下载时,S3 不会向您收取任何带宽费用......所以考虑因素通常不那么重要,并且在 S3 前面添加 CloudFront下载实际上可能比单独使用 S3 便宜一些)。

因此,虽然 CloudFront 可能是官方答案,但仍有一些考虑因素可能存在问题。

S3 传输加速避免了您提到的另一个问题——存储桶区域。启用了传输加速的存储桶可以在https://bucket-name.s3-accelerate.amazonaws.com 访问,无论存储桶区域如何,因此这是一个较小的漏洞,但只有存储桶名称中没有点的存储桶才支持传输加速功能。传输加速会带来额外的带宽费用。

那么这会给你带来什么影响呢?

我认为没有一种内置的“无服务器”解决方案是简单、全局、自动和廉价的。

根据我的经验,具有安全意识以限制域访问 Web 的客户似乎不太可能同时愿意将有效的通配符 (*.storage.example.com) 列入白名单,并且可以导致信任不应信任的流量。诚然,它会比 *.amazonaws.com 更好,但不清楚到底好多少。

我也有理由相信,许多安全配置依赖于静态 IP 地址白名单,而不是按名称列入白名单...在 HTTPS 环境中按名称过滤有其自身的含义和复杂性。

面对这种情况,我的解决方案将围绕部署在 EC2 中的代理服务器(与存储桶位于同一区域)展开,它将请求中的主机名转换为存储桶名称并将请求转发到 S3。这些可以部署在 ELB 后面,也可以部署在弹性 IP 地址上,使用 Route 53 中的 DNS 进行负载平衡,这样您就可以为需要它们的客户端提供静态端点 IP 地址。

另请注意,任何涉及 Host: 标头重写 AWS Signature V4 授权请求的场景都意味着您必须修改应用程序的代码以使用目标 S3 端点的真实主机名对请求进行签名,同时将请求发送到不同的主机名。避免这种情况的唯一方法是直接向存储桶端点(包括传输加速端点)发送请求。

【讨论】:

    【解决方案2】:

    不确定您是否负担得起(由于您可能需要支付额外费用),但这应该可行:

    您可能需要配置安全组和 NACL。如果您需要更多详细信息,请告诉我。

    【讨论】:

    • 此解决方案存在差距。您不能简单地“通过 Internet 网关路由来自 Route 53 的所有流量”,也不能通过 Internet 网关访问 S3 VPC 终端节点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多