使用 CloudFront 和 S3 安全地交付静态网站

您好,
我是系统解决方案部门的Lynn。
我现在已经是第三年从事基础设施工程师工作了,当时我正在上网浏览,心想“我对 S3 了解不多,也许我应该多了解一下它('ω')”,然后就看到了这篇文章。
虽然文章中写道:“接下来,我想写一篇关于如何与 Cloudfront 结合进行分发的文章”,但当时并没有相关的文章,所以我决定借此机会,在时隔九年后,以接力的方式写一篇关于这方面的文章。
总体流程
创建 S3 存储桶
↓
上传 HTML 文件到存储桶
↓
创建 CloudFront 分发
↓
S3 存储桶策略设置
↓
尝试访问
试试看
创建 S3 存储桶
① 进入 S3 控制台后,点击“创建存储桶”。

② 将存储桶类型指定为“通用”,并输入存储桶名称。
* 存储桶名称必须在全球范围内唯一。

③ 其他设置默认即可,但请确保将公共访问设置设为“阻止所有公共访问”。
这是因为我们只想通过 CloudFront 分发 S3 存储桶中的文件。

③ 确认后,点击“创建存储桶”。

它被创造出来了!
④ 上传文件
在存储桶列表屏幕上点击存储桶名称 > 上传

上传您想要显示的静态文件。
在本例中,我上传了这个 HTML 文件(index.html)。(由 ChatGPT 创建)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>谢谢</title> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%20%20%20%20body%20%7B%0A%20 ...背景颜色%20%20%20%20h1%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20字体大小%3A%202.5em%3B%0A%20% 20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20p%20%7B%0A%20%20%20%20%20%20%20%20%20%2 0%20%20font-size%3A%201.2em%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;style&gt;" title="&lt;style&gt;" /> </head> <body> <h1>感谢阅读本文! </h1> <p>希望您已经学会如何使用 CloudFront 和 S3 安全地提供静态网站服务。 </p> </body> </html>
CloudFront 配置
现在我们已经设置好了要分发的文件,接下来我们将配置 CloudFront。
转到 CloudFront > 创建分发。
| 设置项目 | 价值 |
| 分销选项 | 单个网站或应用程序 |
| 源域 | 您创建的 S3 存储桶 |
| 姓名 | 选修的 |
| 源访问 | 源访问控制设置(推荐) |
在为源访问选择“源访问控制设置(推荐)”后,您将创建一个新的源访问控制 (OAC)


创建 OAC 后,它将自动添加到源访问控制中。
其他设置默认都没问题,所以点击“创建分发”。
如果你能创建出这样的分发包,那就万事俱备了!

顺便问一下,OAC(源访问控制)是什么?
此策略用于控制从 CloudFront 对 S3 存储桶的访问。S3
存储桶能够识别来自 CloudFront 的请求,并阻止来自其他来源的访问。OAC
于 2022 年推出,是 OAI(源访问身份)的继任者。OAC
允许比 OAI 更详细的策略配置,并且还支持以下 OAI 不支持的功能:
- 使用 AWS KMS 的 Amazon S3 服务器端加密 (SSE-KMS)
- 对 Amazon S3 的动态请求(PUT 和 DELETE)。
S3 存储桶策略设置
CloudFront > 分发 > 单击您创建的分发 > 单击“源”选项卡
对选定的来源按“编辑”。

转到源访问,复制图像中显示的策略,然后导航到 S3 存储桶权限。

跳转到 S3 存储桶屏幕后,选择“权限”选项卡并编辑存储桶策略。

粘贴您之前复制的策略文件并保存更改。
复制后的保单内容将如下所示:
{ "版本": "2008-10-17", "ID": "PolicyForCloudFrontPrivateContent", "语句": [ { "Sid": "AllowCloudFrontServicePrincipal", "效果": "允许", "主体": { "服务": "cloudfront.amazonaws.com" }, "操作": "s3:GetObject", "资源": "arn:aws:s3:::cloudfront-s3-rin-test-bucket/*", "条件": { "字符串等于": { "AWS:源Arn": "arn:aws:cloudfront::xxxxxxxxxx:distribution/EE49MGYO530OK" } } } ] }
每项政策的含义(要点摘录)
| 主要的 | 指定了 CloudFront 服务, 该服务仅允许 CloudFront 访问 S3 存储桶中的对象。 |
| 行动 | "s3:GetObject" 表示获取对象的权限。 |
| 资源 | 指定存储桶中的所有对象。 |
| 健康)状况 | 它只允许来自特定 CloudFront 分发的请求。 |
既然你已经走到这一步了,那就准备出发吧!
尝试访问它
这次我们不链接自己的域名,而是直接访问分发域名。
您可以在分发包的“常规”部分找到您的分发包域名。

上传的HTML文件已成功显示!

我还想确认 S3 是否不可公开访问,所以我将尝试访问 S3 URL。

正如预期的那样,访问被拒绝!
2