在 AWS 上安全的静态网站托管:使用 CloudFront + 私有 S3 存储桶和 Origin Access Control
Source: Dev.to
End State
一个托管在 Amazon S3 上的静态网站,通过 Amazon CloudFront 全球分发,使用私有访问。
Browser / curl
↓
CloudFront Distribution (HTTPS)
↓
Origin Access Control (OAC)
↓
Private S3 bucket
↓
index.html
最终可用的 URL(在完成教程前不可用):
https://d11v1nvbkt9lgm.cloudfront.net/
全部配置完成后的结果:
- HTTP 200
- 内容来自 S3
- 已被 CloudFront 缓存
- Bucket 未公开
Step‑by‑Step What I Did
1️⃣ Create an S3 bucket
- Bucket name:
devops-bucket-alok - 上传了
index.html - 启用了 Static Website Hosting
Note: S3 static website hosting ≠ S3 REST API endpoint.
2️⃣ Create a CloudFront distribution
- Origin: 上面创建的 S3 bucket
- Default behavior:
* - Viewer policy: 将 HTTP 重定向到 HTTPS
- Allowed methods: GET, HEAD
创建的 CloudFront 域名:d11v1nvbkt9lgm.cloudfront.net
❌ Problem 1 – 403 AccessDenied from CloudFront
Symptoms
-
浏览器显示 XML 错误页面。
-
curl输出:HTTP/2 403 server: AmazonS3 x-cache: Error from cloudfront -
CloudFront 能够访问 S3,但 S3 因为 bucket 没有对 CloudFront 的权限而拒绝请求。
Root cause
- CloudFront Origin Access Control (OAC) 不能与 S3 website endpoints 配合使用(这些端点需要公开访问)。
- OAC 只能与 S3 REST endpoint 配合使用。
Correct decision – 使用 bucket 的 REST endpoint。
创建了一个名为 devops-day0-oac 的 Origin Access Control 并将其附加到 origin,但仍收到 403。
OAC 并不是魔法;CloudFront 会对请求进行签名,但 S3 仍然需要一个 bucket policy 来允许这些签名请求。
❌ Problem 4 – “Where do I check if it’s attached?”
最让人沮丧的是 CloudFront 会提示你:
“You must allow access using this policy statement”
AWS 并 不会 自动应用所需的 bucket policy。
3️⃣ Add S3 Bucket Policy (Key Step)
-
在 S3 控制台中:devops-bucket-alok → Permissions → Bucket policy。
-
粘贴 CloudFront 生成的策略,该策略:
- 允许
cloudfront.amazonaws.com - 限制访问到你的 distribution ARN
- 授予
s3:GetObject
- 允许
应用策略后,请求流程成功:
- CloudFront → S3
- 浏览器收到 HTTP/2 200,
x-cache: Miss from cloudfront
## Hello from S3 + CloudFront!
这证明 CloudFront 正在前端代理请求,S3 为源站,访问控制已正确配置,HTTPS 正常工作。
What I Learned
Conceptual
- 对象存储与服务器托管的区别。
- CDN 与源站的职责分工。
- CloudFront 存在的原因。
- 为什么 S3 bucket 不应公开。
- 403 错误 不是 网络问题。
AWS‑specific
- S3 website endpoint 与 REST endpoint 的区别。
- OAC(现代)与 OAI(旧版)的区别。
- 使用 OAC 时必须有 bucket policy。
- 许多 CloudFront 错误实际上来源于 S3 权限。
DevOps reality
- AWS UI 隐藏了关键步骤(例如,附加 bucket policy)。
- 错误信息在技术上是正确的,但往往帮助不大。
- 故障排查主要是追踪权限。
- 大部分时间都浪费在缺少一条策略声明上。