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

上次更新日期:2022 年 11 月 3 日

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

简短描述

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

  • 使用 REST API 端点作为源,通过来源访问控制(OAC)或来源访问身份(OAI)限制访问
    注意:最佳实践是使用来源访问控制(OAC)限制访问。来源访问身份(OAI)是此过程的旧方法。
  • 使用网站端点作为源,允许匿名(公开)访问
  • 使用网站端点作为源,通过 Referer 标头限制访问
  • 使用 CloudFormation 将静态网站端点部署为源,并自定义指向 CloudFront 的域

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

解决方法

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

使用 REST API 端点作为源,并通过 OAC 或 OAI(旧版)限制访问

  1. 使用 Amazon S3 console(Amazon S3 控制台)create a bucket(创建存储桶)并 upload your website files(上传网站文件)。
    注意:如果采用此配置,则无需在存储桶上启用静态网站托管。此配置使用存储桶的 REST API 端点,而不是静态网站托管功能中的网站端点。
  2. 创建 CloudFront Web 分配。除了使用案例所需的分配设置外,使用以下方法之一限制对 Amazon S3 源的访问。最佳实践是使用 OAC。使用 OAI 是一项旧版设置。

    创建分配时,使用以下设置通过 OAC 限制访问:
    Origin Domain(源域)字段中,输入您的 Amazon S3 存储桶名称。
    Origin access(来源访问)下,选择 Origin access control settings (recommended)(来源访问控制设置(推荐))。
    Origin access control(来源访问控制)下拉列表中,选择 OAC 名称并选择 Create control setting(创建控制设置)。
    在对话框中,命名您的控制设置 最佳实践是保留默认设置 Sign requests (recommended)(签署请求(推荐))。然后,选择 Create(创建)。
    CloudFront 为您提供策略语句,便于授予 OAC 权限以在创建分配后访问 Amazon S3 存储桶。选择 Copy Policy(复制策略)并将策略粘贴到您的 S3 存储桶策略配置中。

    -或者-

    创建分配时,使用以下设置通过 OAI 限制访问:
    Origin Domain(源域)字段中,输入您的 Amazon S3 存储桶名称。
    Origin access(来源访问)下,选择旧访问身份。
    Origin access identity(来源访问身份)下拉列表中,选择来源访问身份名称。然后,选择 Create new OAI(创建新 OAI)。
    在对话框中,命名您的新来源访问身份,然后选择 Create(创建)。
    对于存储桶策略,选择Yes(是),更新存储桶策略
  3. 创建分配时,最佳实践是为您的网站使用 SSL (HTTPS)。要搭配使用自定义域与 HTTPS,请选择自定义 SSL 证书。 您可以选择 Request certificate(请求证书)以请求新的证书。如果您未使用自定义域,则仍可在分配中使用 HTTPS 与 cloudfront.net 域名。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  4. 更新域的 DNS 记录,以便将网站的 CNAME 指向 CloudFront 分配的域名。您可以在 CloudFront 控制台中查找您的分配的域名,其格式类似于 d1234abcd.cloudfront.net
  5. 等候 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(静态网站托管)对话框中,复制您存储桶的 Endpoint(端点),但不要复制先导符 http://。格式类似于 DOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com。您将后面的步骤中用到此格式的终端节点。
  3. 向您已创建的存储桶添加允许公开读取访问的存储桶策略
    注意:对于此配置,必须关闭 S3 存储桶的阻止公开访问设置。如果您的使用案例需要启用阻止公共访问设置,请将 REST API 端点作为源。然后,通过来源访问控制(OAC)或来源访问身份(OAI)限制访问。
  4. 创建 CloudFront Web 分配。除了您的使用案例需要的分配设置外,另请输入以下内容:
    对于 Origin domain(源域)部分,输入您在第 2 步中复制的端点。
    注意:不要从下拉列表中选择存储桶。下拉列表仅包括此配置中未使用的 S3 存储桶 REST API 端点。
  5. 创建分配时,最佳实践是为您的网站使用 SSL (HTTPS)。要搭配使用自定义域与 HTTPS,请选择自定义 SSL 证书。 您可以选择 Request certificate(请求证书)以请求新的证书。如果您未使用自定义域,则仍可在分配中使用 HTTPS 与 cloudfront.net 域名。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  6. 更新域的 DNS 记录,以便将网站的 CNAME 指向 CloudFront 分配的域名。您可以在 CloudFront 控制台中查找您的分配的域名,其格式类似于 d1234abcd.cloudfront.net
  7. 等候 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(静态网站托管)对话框中,复制您存储桶的 Endpoint(端点),但不要复制先导符 http://。格式类似于 DOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com。您将后面的步骤中用到此格式的终端节点。
  3. 创建 CloudFront Web 分配。除了您的使用案例需要的分配设置外,另请输入以下内容:
    对于 Origin domain(源域)部分,输入您在第 2 步中复制的端点。
    注意:不要从下拉列表中选择存储桶。下拉列表仅包括此配置中未使用的 S3 存储桶 REST API 端点。
    Add custom header(添加自定义标头)下,选择 Add header(添加标头)。
    对于 Header name(标头名称),输入 Referer
    Value(值)部分,输入您想要转发至源(S3 存储桶)的自定义标头值。要限制对源的访问,请输入只有您知道的随机值或密钥值。
  4. 创建分配时,最佳实践是为您的网站使用 SSL (HTTPS)。要搭配使用自定义域与 HTTPS,请选择自定义 SSL 证书。 您可以选择 Request certificate(请求证书)以请求新的证书。如果您未使用自定义域,则仍可在分配中使用 HTTPS 与 cloudfront.net 域名。
    重要提示:如果您为分配输入了备用域名 (CNAME),则 CNAME 必须与您选择的 SSL 证书匹配。要排查 SSL 证书的问题,请参阅如何排查与在我的 CloudFront 分配上使用自定义 SSL 证书有关的问题?
  5. Amazon S3 控制台打开您网站的存储桶。然后,添加存储桶策略在请求包含自定义 Referer 标头的情况下允许 s3:GetObject,该标头即您在第 3 步中指定的标头。对于此配置,必须禁用 S3 存储桶的阻止公开访问设置。Amazon S3 将会考虑授予 Referer 限制的匿名访问权限为公开的存储桶策略。如果您的使用案例需要启用阻止公开访问设置,则请将 REST API 端点作为源。然后,通过来源访问控制(OAC)或来源访问身份(OAI)限制访问。
    注意:要阻止不包含自定义 Referer 标头的任何请求的访问,请在存储桶策略中使用显式拒绝语句。
  6. 更新域的 DNS 记录,以便将网站的 CNAME 指向 CloudFront 分配的域名。您可以在 CloudFront 控制台中查找您的分配的域名,其格式类似于 d1234abcd.cloudfront.net
  7. 等候 DNS 更改完成传播且先前的 DNS 条目过期。
    注意:先前的 DNS 值过期所需的时长取决于托管区域中设置的 TTL 值。这还取决于您的本地解析程序是否使用这些 TTL 值。

使用 CloudFormation 将静态网站端点部署为源,并自定义指向 CloudFront 的域

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

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

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