如何使用 CloudFront 为 Amazon S3 上托管的静态网站提供服务?

上次更新日期:2020 年 10 月 6 日

我想在 Amazon Simple Storage Service (Amazon S3) 存储桶中托管静态网站。然后,我想通过 Amazon CloudFront 分配为我的网站服务。该如何操作?

简短描述

要为 Amazon S3 上托管的静态网站提供服务,您可以使用以下某项配置部署 CloudFront 分配:

  • 使用 REST API 终端节点作为源,通过源访问身份 (OAI) 限制访问权限
  • 使用网站终端节点作为源,允许匿名(公开)访问
  • 使用网站终端节点作为源,通过 Referer 标头限制访问权限
  • 使用 AWS CloudFormation 将 REST API 终端节点部署为源,并通过 OAI 和指向 CloudFront 的自定义域限制访问权限

有关两个终端节点类型的更多信息,请参阅网站终端节点和 REST API 终端节点之间的主要差异

解决方法

按照以下步骤,配置具有要用作源的 S3 终端节点类型的 CloudFront 分配:

使用 REST API 终端节点作为源,并通过 OAI 限制访问权限

  1. 使用 Amazon S3 控制台创建存储桶上传网站文件
    注意:若采用此配置,则无需在存储桶上启用静态网站托管。此配置使用存储桶的 REST API 终端节点,而不是静态网站托管功能中的网站终端节点。 
  2. 创建 CloudFront Web 分配。除了您的使用案例需要的分配设置外,另请输入以下内容:
    源域名部分,选择您创建的存储桶。
    对于限制存储桶访问,请选择
    对于源访问身份,请选择创建新身份
    备注部分可以保留默认值。您还可以为 OAI 输入自定义标签。
    对于授予存储桶读取权限,请选择是,更新存储桶策略
  3. 如果您不想为您的网站使用 SSL (HTTPS),请继续执行下一步。要为您的网站使用 SSL,在 SSL 证书部分,您可以选择默认 CloudFront 证书自定义 SSL 证书。您也可以选择使用 ACM 请求或导入证书以申请新证书。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  4. 选择创建分配
  5. 为您的域更新 DNS 记录,以将您网站的别名记录指向 CloudFront 分配的域名。您可以在 CloudFront 控制台中查找您的分配的域名,其格式类似于 d1234abcd.cloudfront.net
  6. 等候 DNS 更改完成传播且先前的 DNS 条目过期。
    注意:先前的 DNS 值过期所需的时间取决于托管区域中设置的 TTL 值,以及您的本地解析程序是否使用这些 TTL 值。 

使用网站终端节点作为源,允许匿名(公开)访问

注意:此配置允许公开读取您网站的存储桶。有关更多信息,请参阅设置网站访问权限

  1. 使用 Amazon S3 控制台创建存储桶并启用存储桶上的静态网站托管
  2. 静态网站托管对话框中复制您的存储桶的终端节点(去掉前导 http://)。格式类似于 AWSDOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com。后面的某个步骤需要这种格式的终端节点。
  3. 向您已创建的存储桶添加允许公开读取权限的存储桶策略
  4. 创建 CloudFront Web 分配。除了您的使用案例需要的分配设置外,另请输入以下内容:
    源域名部分,输入您在步骤 2 中复制的终端节点。
  5. 如果您不想为您的网站使用 SSL (HTTPS),请继续执行下一步。要为您的网站使用 SSL,在 SSL 证书部分,您可以选择默认 CloudFront 证书自定义 SSL 证书。您也可以选择使用 ACM 请求或导入证书以申请新证书。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  6. 选择创建分配
  7. 为您的域更新 DNS 记录,以将您网站的别名记录指向 CloudFront 分配的域名。您可以在 CloudFront 控制台中查找您的分配的域名,其格式类似于 d1234abcd.cloudfront.net
  8. 等候 DNS 更改完成传播且先前的 DNS 条目过期。
    注意:先前的 DNS 值过期所需的时间取决于托管区域中设置的 TTL 值,以及您的本地解析程序是否使用这些 TTL 值。 

使用网站终端节点作为源,通过 Referer 标头限制访问权限

注意:此配置通过以下方法限制访问权限:在分配上设置自定义 Referer 标头,然后使用存储桶策略来仅向具有自定义 Referer 标头的请求授予访问权限。请务必评估此设置允许的访问权限是否符合您的使用案例的要求。

  1. 使用 Amazon S3 控制台创建存储桶并启用存储桶上的静态网站托管
  2. 静态网站托管对话框中复制您的存储桶的终端节点(去掉前导 http://)。格式类似于 AWSDOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com。后面的某个步骤需要这种格式的终端节点。
  3. 创建 CloudFront Web 分配。除了您的使用案例需要的分配设置外,另请输入以下内容:
    源域名部分,输入您在步骤 2 中复制的终端节点。
    标头名称下的源自定义标头部分,输入 Referer。在下,输入您希望转发给源(S3 存储桶)的自定义标头。要限制对源的访问,您可以输入只有您知道的随机值或密钥。
  4. 如果您不想为您的网站使用 SSL (HTTPS),请继续执行下一步。要为您的网站使用 SSL,在 SSL 证书部分,您可以选择默认 CloudFront 证书自定义 SSL 证书。您也可以选择使用 ACM 请求或导入证书以申请新证书。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  5. 选择创建分配
  6. Amazon S3 控制台打开您网站的存储桶。然后,添加存储桶策略在请求包含自定义 Referer 标头的情况下允许 s3:GetObject,该标头即您在第 3 步中指定的标头。
    注意:要阻止不包含自定义 Referer 标头的请求的访问权限,请在存储桶策略中使用显式拒绝语句。
  7. 为您的域更新 DNS 记录,以将您网站的别名记录指向 CloudFront 分配的域名。您可以在 CloudFront 控制台中查找您的分配的域名,其格式类似于 d1234abcd.cloudfront.net
  8. 等候 DNS 更改完成传播且先前的 DNS 条目过期。
    注意:先前的 DNS 值过期所需的时间取决于托管区域中设置的 TTL 值,以及您的本地解析程序是否使用这些 TTL 值。 

使用 CloudFormation 将 REST API 终端节点部署为源,并通过 OAI 和指向 CloudFront 的自定义域限制访问权限

使用此解决方案,您的网站:

  • 已部署 CloudFormation
  • 已在 Amazon S3 上托管
  • 已由 CloudFront 分发
  • 使用 AWS Certificate Manager (ACM) 颁发的 SSL/TLS 证书
  • 使用 Lambda@Edge 为每个服务器响应添加安全标头

有关部署此解决方案的说明,请参阅 GitHub 网站上的 Amazon CloudFront 安全静态网站