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

上次更新日期:2021 年 1 月 5 日

我想在 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 输入自定义标签。
    对于授予存储桶读取权限,请选择 Yes, Update Bucket Policy(是,更新存储桶策略)。
  3. 最佳做法是为您的网站使用 SSL (HTTPS)。要设置 SSL,请为 SSL 证书选择 Default CloudFront Certificate(默认的 CloudFront 证书)以使用默认的 CloudFront DNS 名称。或者,选择 Custom SSL Certificate(自定义 SSL 证书)以使用您自己的自定义域。您可以选择 Request or Import a Certificate with ACM(使用 ACM 请求或导入证书)以请求新证书。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  4. 选择 Create Distribution(创建分配)。
  5. 更新域的 DNS 记录,以便将网站的 CNAME 指向 CloudFront 分配的域名。您可以在 CloudFront 控制台中查找您的分配的域名,其格式类似于 d1234abcd.cloudfront.net
  6. 等候 DNS 更改完成传播且先前的 DNS 条目过期。
    注意:先前的 DNS 值过期所需的时间取决于托管区域中设置的 TTL 值,以及您的本地解析程序是否使用这些 TTL 值。

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

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

注意:当您使用 Amazon S3 静态网站终端节点时,CloudFront 和 Amazon S3 之间的连接只能通过 HTTP 进行。要将 HTTPS 用于 CloudFront 和 Amazon S3 之间的连接,请为源配置 S3 REST API 终端节点。

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

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

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

注意:当您使用 Amazon S3 静态网站终端节点时,CloudFront 和 Amazon S3 之间的连接只能通过 HTTP 进行。要将 HTTPS 用于 CloudFront 和 Amazon S3 之间的连接,请为源配置 S3 REST API 终端节点。

  1. 使用 Amazon S3 控制台创建一个存储桶,然后为该存储桶启用静态网站托管功能
  2. Static website hosting(静态网站托管)对话框中,复制您的存储桶的终端节点,但不要复制先导符 http://。格式类似于 DOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com。您将后面的步骤中用到此格式的终端节点。
  3. 创建 CloudFront Web 分配。除了您的使用案例需要的分配设置外,另请输入以下内容:
    对于源域名,输入您在第 2 步复制的终端节点。
    标头名称下的源自定义标头部分,输入 Referer。在下,输入您希望转发给源(S3 存储桶)的自定义标头。要限制对源的访问,您可以输入只有您知道的随机值或密钥。
  4. 最佳做法是为您的网站使用 SSL (HTTPS)。要设置 SSL,请为 SSL 证书选择 Default CloudFront Certificate(默认的 CloudFront 证书)以使用默认的 CloudFront DNS 名称。或者,选择 Custom SSL Certificate(自定义 SSL 证书)以使用您自己的自定义域。您可以选择 Request or Import a Certificate with ACM(使用 ACM 请求或导入证书)以请求新证书。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  5. 选择 Create Distribution(创建分配)。
  6. Amazon S3 控制台打开您网站的存储桶。然后,添加存储桶策略在请求包含自定义 Referer 标头的情况下允许 s3:GetObject,该标头即您在第 3 步中指定的标头。
    注意:要阻止不包含自定义 Referer 标头的请求的访问权限,请在存储桶策略中使用显式拒绝语句。
  7. 更新域的 DNS 记录,以便将网站的 CNAME 指向 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 安全静态网站