为啥托管静态网站时 Amazon S3 存储桶名称必须与网站名称相同

Posted

技术标签:

【中文标题】为啥托管静态网站时 Amazon S3 存储桶名称必须与网站名称相同【英文标题】:Why Amazon S3 bucket name must be the same as website name when hosting a static website为什么托管静态网站时 Amazon S3 存储桶名称必须与网站名称相同 【发布时间】:2014-11-11 02:17:17 【问题描述】:

我想在 S3 上托管一个静态网站,即abcd.com。它需要一个与 abcd.com 相同的存储桶名称。

然后我发现abcd.com已经被其他人占用了。

这就是我的问题,为什么存储桶名称必须与网站名称相同?因为有 Route 53 将网站映射到存储桶端点,所以这个限制似乎没有必要。

这有什么原因吗?

【问题讨论】:

【参考方案1】:

简短的回答是,“亚马逊就是这样设计的。”

如果存储桶名称与域名不同,S3 如何知道使用哪个存储桶来处理给定域的请求?

您不能说“Route 53”,因为 S3 是在 Route 53 之前创建的,即使您没有将 Route 53 用于 DNS,S3 中的网站托管也可以正常工作。

同样,它不能作为存储桶上的配置选项,因为这只会产生一系列新问题 - 如果域的前任所有者仍然使用您的域配置他们的存储桶,那么您将完全拥有现在和你一样的问题。

您仍然可以在 S3 上托管您的网站,但如果存储桶名称不匹​​配,您需要在同一区域的 EC2 中使用反向代理服务器,以重写每个请求中的主机标头以匹配存储桶名称,或者,您可以使用 CloudFront 来完成类似的目的,因为存储桶名称不需要匹配——CloudFront 也会重写 Host 标头。

【讨论】:

我要补充一点,为了让 CloudFront 方法能够工作,Cache Based on Selected Request Headers 不能设置为 All 呃……存储桶名称在 URL 中……但它仍然需要与转发给它的域命名相同吗?那没有意义。 S3 提供的 URL 类似于:<bucketName>.s3-website-us-west-2.amazonaws.com,但我无法将 www.foo.com 重定向到它而不会收到 Code: NoSuchBucket 错误。 S3 分配的终端节点包含存储桶名称,但即使没有,您无法将 CNAME 设置从 foo.com 转发到 joeschmoe.s3.amazon.com 的技术原因是什么(或其他)没有让 AWS 感到困惑?转发必须发生,然后 AWS 决定使用原始主机来识别存储桶,而不是使用它分配的实际 url。如果我错了,请纠正我,但 dns 不会将请求路由到 s3 分配的 url,而不是 aws 查看与其关联的存储桶,它会尝试查找与源名称相同的存储桶(如果没有) '不匹配。 技术原因是原始主机名(即在浏览器地址栏中键入的主机名)是 HTTP 请求中唯一可用的权限信息。没有保留 DNS 解析链,因此 Web 服务器不知道您是如何通过级联 CNAME 等获得它的。如果您在 Web 浏览器中配置 www.example.com CNAME www.google.com,然后转到 www.example.com,您将连接到 Google 拥有的网络服务器,但您不会看到 www.google.com 的内容。你会从 Google 服务器收到一个错误,因为它没有任何东西可以显示 www.example.com Michael 的最后一条评论 - sqlbot 应该是所提问题的答案。【参考方案2】:

这有一个非常简单的原因:当亚马逊从您的浏览器获取请求时,可用的主要信息是 URL 中的域,这还不足以弄清楚。

假设您的站点是example.com,但使用了该存储桶名称,因此您创建了存储桶my-example。然后你会得到一个类似http://my-example.s3-website.us-east-1.amazonaws.com/ 的URL。这将在您的浏览器中正常工作,因为它会解析到某个 AWS Web 服务器,该服务器会查看 Host HTTP header,提取您的存储桶名称,并获取您的存储桶内容。

现在假设您向 Route53 添加了一些东西以使 example.com 工作。您可以添加 A 记录,让您的浏览器将 example.com 直接转换为某些 AWS S3 网络服务器的 IP 地址。或者您可以输入一个 CNAME,它从 example.com 指向完整的 my-example 主机名。无论哪种方式,您的浏览器都会查找 IP 地址,联系 Amazon 网络服务器,然后发送一个 Host 标头,上面写着 example.com。因此,如果这不是存储桶名称,它不知道该怎么做。

诚然,它可能会更进一步。毕竟,当您设置存储桶以提供网站服务时,您告诉它的主机名。所以乍一看,如果它也使用它似乎会很好。但是,这也不能真正解决您的问题,因为设置 example.com 存储桶的人很可能已经将其设置为托管。

解决此问题的最佳方法似乎是 Cloudfront,它可以将域名与任意存储桶相关联。

【讨论】:

“无论哪种方式,您的浏览器都会查找 IP 地址,联系 Amazon 网络服务器,然后发送一个 Host 标头,上面写着 example.com” - 所以,如果网络服务器实际上有一个名为- example.com 由其他人拥有并设置为托管,用户会返回 example.com 托管的网站吗?还是 AWS 根据 FQDN 检查主机标头?当然,我指的是你的具体示例场景 问得好,阿布舍克。 HTTP 请求中唯一的内容是 Host 标头,因此,如果用户在浏览器中键入“example.com”,亚马逊将提供该服务,即使后台有 CNAME。尝试使用 Wireshark 捕获一些 HTTP 请求,您将了解幕后情况。 感谢@William Pietri。 &我认为这与您在“但是,这也不能真正解决您的问题,因为 ....”中解释的行为相同 - 正确吗?【参考方案3】:

我认为这就是 AWS 设计的方式,仅此而已:Check this

我已经为我公司的网站做了这个,效果很好!

创建一个 S3 存储桶并将其配置为托管网站

Amazon S3 让您可以在任意位置存储和检索数据 互联网。要组织您的数据,您需要创建存储桶并上传您的 使用 AWS 管理控制台将数据传输到存储桶。您可以使用 S3 在存储桶中托管静态网站。以下程序 说明如何创建存储桶并将其配置为网站托管。

创建 S3 存储桶并将其配置为托管网站

打开 Amazon S3 控制台https://console.aws.amazon.com/s3/。 选择创建存储桶。 输入以下值: 存储桶名称 - 输入您的域名,例如 example.com。 区域 - 选择最接近大多数用户的区域。 记下您选择的区域;在此过程的稍后部分您将需要此信息。 选择下一步。 在“配置选项”页面上,选择“下一步”接受默认值。 在设置权限页面上,取消选中阻止所有公共访问复选框,然后选择下一步。

注意 控制台会显示一条关于对存储桶的公开访问的消息。在此过程的稍后部分,您将添加一个限制对存储桶的访问的存储桶策略。

在 Review 页面上,选择 Create bucket。 在 S3 存储桶列表中,选择您刚刚创建的存储桶的名称。 选择“属性”选项卡。 选择静态网站托管。 选择使用此存储桶托管网站。 对于索引文档,输入包含您网站主页的文件的名称。

注意 您将创建一个 html 文件,然后在此过程中将其上传到您的存储桶。

选择保存。 选择“权限”选项卡。 选择存储桶策略。

复制以下存储桶策略并将其粘贴到文本编辑器中。此策略授予 Internet 上的每个人 ("Principal":"*") 获取与您的域名 ("arn:aws:s3:::your-domain-name/*") 关联的 S3 存储桶中的文件 ("Action":["s3:GetObject"]) 的权限:


   "Version":"2012-10-17",
   "Statement":[
      "Sid":"AddPerm",
      "Effect":"Allow",
      "Principal":"*",
      "Action":[
         "s3:GetObject"
      ],
      "Resource":[
         "arn:aws:s3:::your-domain-name/*"
      ]
    ]

在存储桶策略中,将值 your-domain-name 替换为您的域名,例如 example.com。此值必须与存储桶的名称匹配。 选择保存。

创建另一个 S3 存储桶为 www.your-domain-name

在上述过程中,您为您的域名创建了一个存储桶,例如 example.com。这允许您的用户使用您的域名(例如 example.com)访问您的网站。

如果您还希望您的用户能够使用 www.your-domain-name(例如 www.example.com)来访问您的示例网站,您可以创建第二个 S3 存储桶。然后,您将第二个存储桶配置为将流量路由到第一个存储桶。

注意 网站通常会将您的域名重定向到 www.your-domain-name,例如,从 example.com 重定向到 www.example.com。由于 S3 的工作方式,您必须设置相反方向的重定向,从 www.example.com 到 example.com。

为 www.your-domain-name 创建 S3 存储桶

选择创建存储桶。 输入以下值: 存储桶名称 - 输入 www.your-domain-name。例如,如果您注册了域名 example.com,请输入 www.example.com。 区域 - 选择您在其中创建第一个存储桶的同一区域。 选择下一步。 在“配置选项”页面上,选择“下一步”接受默认值。 在“设置权限”页面上,选择“下一步”接受默认值。 在 Review 页面上,选择 Create bucket。 在 S3 存储桶列表中,选择您刚刚创建的存储桶的名称。 选择“属性”选项卡。 选择静态网站托管。 选择重定向请求。 输入以下值: 目标存储桶或域 输入要将请求重定向到的存储桶的名称。这是您在创建 S3 存储桶并将其配置为托管网站过程中创建的存储桶的名称。 协议 - 输入 http。您将请求重定向到配置为网站终端节点的 S3 存储桶,而 Amazon S3 不支持网站终端节点的 HTTPS 连接。 选择保存。

【讨论】:

以上是关于为啥托管静态网站时 Amazon S3 存储桶名称必须与网站名称相同的主要内容,如果未能解决你的问题,请参考以下文章

Amazon s3 静态 Web 托管缓存

静态网站托管中子域的 AWS S3 存储桶重定向与 DNS CNAME

在 CloudFront/S3 中托管 Angular 应用程序 *无需* S3 静态网站托管

将 Amazon S3 存储桶和 Cloudfront 与 SSL Wordpress 站点一起使用不会提供静态文件

使用 cloudflare 将 CNAME 分配给我在亚马逊 S3 中的静态网站存储桶

从静态网页上传 csv 文件到 S3 存储桶