Cloudfront 私有内容 + 签名 URL 架构

Posted

技术标签:

【中文标题】Cloudfront 私有内容 + 签名 URL 架构【英文标题】:Cloudfront private content + signed urls architecture 【发布时间】:2011-09-14 14:23:34 【问题描述】:

首先让我快速介绍一下我正在考虑迁移到 S3+Cloudfront 的系统架构。

我们在树中有许多实体顺序。树的叶子有很多资源(具体是jpg图片),一般在20-5000左右,平均200左右。每个资源都有一个唯一的 URL,通过我们今天的 colo 设置提供。

我可以将所有这些资源转移到 S3,在此基础上设置 Cloudfront 并完成。要是我不用保护资源就好了。

大多数实体是公开的(即约 99%),其余实体以多种方式(登录名、IP、时间等)中的一种方式受到保护。一旦实体受到保护,所有资源也必须受到保护,并且只有在执行有效授权后才能访问。

我可以通过创建两个 S3 存储桶来解决这个问题 - 一个是私有的,一个是公有的。对于私有内容,我会在用户获得授权后生成签名的 Cloudfront URL。但是,实体的状态可能会任意从公共变为私有,反之亦然。系统管理员可能会在实体树的任何级别更改实体,从而导致整个树的级联更改。一次更改可能会导致约 20k 个实体发生更改,乘以 200 个资源,这将影响 400 万个资源。

我可以在后台运行一项服务来监控状态变化,但这会很麻烦,并且更改 400 万个 S3 项目的 ACL 需要相当长的时间,而在这种情况下,我们要么拥有不受保护的私人内容,要么我们必须为其生成签名 URL 的公共内容。

另一种可能性是默认将所有资源设为私有。在向实体发出的每个请求中,我们将生成一个自定义策略,为该特定用户授予对实体中包含的所有资源的访问权限(通过在自定义策略中使用通配符 url)。这将需要为每个访问者、每个实体创建一个策略——不过这不是问题。但是,这意味着我们的用户无法再缓存任何内容,因为每个新会话的 URL 都会更改。虽然对于私有内容来说不是问题,但对于我们来说,放弃对大约 99% 的公共实体的所有缓存会很糟糕。

另一种选择是将所有内容保密,并将上述方法用于私有实体。对于公共实体,我们可以为每个公共实体生成一个所有用户都将共享的自定义策略。如果我们将生命周期设置为 6 小时并确保在 5 小时后生成新策略,则用户将确保至少一小时的策略生命周期。这具有启用缓存长达 6 小时的优势,同时允许私有内容在状态更改后可能长达 6 小时公开。这是可以接受的,但我不确定它是否值得(尝试计算当前请求的缓存/命中率)。显然,我们可以调整 5/6 小时边界,以启用更长/更短的缓存,但代价是更长/更短地暴露于私人实体。

有人部署了类似的解决方案吗?我忽略的任何可能有用的 AWS 功能?一般有什么cmet?

【问题讨论】:

@Mark 你的编辑真的值得一个答案,我也赞成! 根据您的反馈,我删除了已编辑的部分并添加了答案。谢谢! 【参考方案1】:

应大家的要求,我自己来回答这个问题。

在收集相关指标并进行一些计算后,我们最终得出结论,我们可以使用更少的缓存,但被 CloudFront 更快的对象服务速度所抵消。实际实现详见我的博客:How to Set Up and Serve Private Content Using S3 and Amazon CloudFront

【讨论】:

你知道如何用 php 做到这一点吗? @NullPoiиteя 您会以完全相同的方式进行操作。至于 PHP 语法,不好意思,我没用过 PHP,所以你得自己查。 亚马逊文档不过是一坨屎......我有工作代码,但不知道它为什么工作(这使得它容易受到攻击)【参考方案2】:

同一存储桶中的资产可以有不同的隐私政策。 因此,您可以在同一个存储桶中拥有公共资产和私有资产。

在上传时,只需设置隐私设置。

然后只需签署 URL 即可访问私有资产。

【讨论】:

以上是关于Cloudfront 私有内容 + 签名 URL 架构的主要内容,如果未能解决你的问题,请参考以下文章

通过 CloudFront 进行私有 HTTP 实时流式传输

使用 Ruby 为 CloudFront 创建签名 URL

如何使用预设策略加密 Amazon CloudFront 签名以进行私有内容访问

通过 AWS 开发工具包创建签名的 S3 和 Cloudfront URL

Amazon Cloudfront 签名 URL 访问被拒绝问题

使用 Cloudfront/CDN 预签名的 S3 URL