Amazon S3:同时使用 DNS 别名存储桶 + HTTPS

Amazon S3: using DNS alias to bucket + HTTPS at the same time

我想在法兰克福区域创建一个 S3 存储桶,并使用 URL 访问文件:https://files.stample.co/filename

所以我同时需要 HTTPS 和自定义 DNS 别名 (CNAME)。

据我了解,亚马逊有URLhttps://*.s3.amazonaws.com的通配符证书。

HTTPS/SSL

所以这个通配符将:

所以我的理解和其他 Whosebug posts 确认的是,如果我想让 SSL 工作,我必须使用不带点的存储桶名称,否则带有通配符的 Amazon 证书将与存储桶域不匹配.

使用 DNS 别名/CNAME

在此 S3 documentation 下,Customizing Amazon S3 URLs with CNAMEs 部分:

Depending on your needs, you might not want "s3.amazonaws.com" to appear on your website or service. For example, if you host your website images on Amazon S3, you might prefer http://images.johnsmith.net/ instead of http://johnsmith-images.s3.amazonaws.com/.

The bucket name must be the same as the CNAME. So http://images.johnsmith.net/filename would be the same as http://images.johnsmith.net.s3.amazonaws.com/filename if a CNAME were created to map images.johnsmith.net to images.johnsmith.net.s3.amazonaws.com.

这似乎是出于技术原因,否则亚马逊无法知道我们尝试定位的存储桶:

Because Amazon S3 sees only the original host name www.example.com and is unaware of the CNAME mapping used to resolve the request, the CNAME and the bucket name must be the same.

所以我在这里的理解是,要使 CNAME 起作用,我们必须在存储桶名称中使用点。

两者一起?

如果我在存储桶名称中使用点:

如果我不在存储桶名称中使用点:

我已经测试了这两种情况,但无法使 SSL 和 CNAME 一起正常工作。

我该怎么做才能使两者都起作用?在我看来,我想要实现的目标并不是很花哨...

您可以同时执行这两种操作,具体取决于您的意思,但这需要改变您的方法并了解某些 S3 内部结构,或者了解您尝试的内容为何无法预期上班。

首先,澄清一下,当我说您可以同时执行这两项操作时,我假设您不希望创建一个名为 "example.com" 的存储桶,然后能够以 https://example.com 的身份访问该存储桶.

如果这是您想要或期望的,那么您就错过了 SSL 的一些基础知识。

对于提供 SSL 的 Web 服务器,它必须具有由受信任的证书颁发机构签署的 SSL 证书。此证书不仅包含用于加密的 public 密钥,还包含对其有效的主机名,并且不适用于其他主机名。 SSL 不仅提供加密,还保证您访问的网站确实是您认为的网站。对于 s3,证书中的主机名是 *.s3.amazonaws.com 和一些区域变体,我将在下面解释。主机名匹配规则要求 * 不匹配 任何带点的东西,所以 *.s3.amazonaws.com 匹配 example-bucket.s3.amazonaws.com (没有点与 *) 对齐的主机名组件,但它不匹配 example.com.s3.amazonaws.com,因为 * 不匹配 example.com,因为它包含一个点。这些规则是由浏览器强加的,这不是 S3 中的限制。

现在,如果您尝试使用 https://example.com 访问您的存储桶,S3 本身将无法启用此功能,因为 example.com 本身甚至无法 远程 类似于 S3 的 SSL 证书上的主机名,即 *.s3.amazonaws.com。您不仅需要从已签署用于 "example.com," 的证书颁发机构购买 SSL 证书,还需要将其安装在 Web 服务器上……在本例中为 S3……而 S3 不支持这个。

但是,Amazon CloudFront 可以。您可以将 CloudFront 分配配置为存储桶的前端,并在 CloudFront 上安装您自己的 SSL 证书,以这种方式通过 HTTPS 访问存储桶。在此配置中,您的存储桶名称是什么并不重要——它甚至不必与您的域名相匹配,因为您可以将 CloudFront 配置为使用您想要的任何存储桶。浏览器通过 CloudFront 获取内容,后者又从存储桶中提取内容。

现在......假设这不是你要问的......假设你不希望你自己的域在 SSL 中使用亚马逊的证书......你可以配置一个带点名的存储桶,允许您创建一个 CNAME 来托管您的 "example.com" 内容...并且仍然可以使用 HTTPS 访问存储桶。但是,由于上述原因,您无法通过 SSL 使用 CNAME 访问它...因为您的主机名与 S3 的 SSL 证书上的主机名不匹配。

但是,如果您想通过 SSL 访问名称中带点的存储桶,您可以使用配置存储桶的区域端点执行此操作。

us-west-2 区域中的 "example.com" 存储桶将通过将存储桶名称放在第一部分(如果是路径而不是主机名的开头)来寻址...像这样:

https://s3-us-west-2.amazonaws.com/example.com/path/to/file.jpg

每个 S3 区域至少有一个 regional endpoint 以这种方式工作。对于 "US-Standard" 区域,端点是 "s3.amazonaws.com",在地理上路由到弗吉尼亚州的主站点或俄勒冈州的镜像站点,"s3-external-1.amazonaws.com" 仅路由到弗吉尼亚州,或 "s3-external-2.amazonaws.com"这在很大程度上没有记录,但路由到俄勒冈州的镜像。

因此,可以通过 HTTPS 访问名称中带点的存储桶中的资源,但您必须知道存储桶的区域...尽管您不能简单地使用 https://your-cname.example.com 访问它,因为SSL 的一般工作方式。

目前看来仅使用 S3 是不可能的,但使用 CloudFront 是可能的,因为它支持自定义证书。

CloudFront 不是很贵,在某些情况下甚至比 S3 还便宜。它在使用 SNI 时免费支持自定义证书(但它不被 < IE7、< Chrome6、< Firefox 2.0 等旧浏览器支持)

CloudFront 指南

我举个例子,你想用https://files.mydomain.com指向一个名为mydomain-files的S3 bucket(bucket的名字不重要,可以包含点)。

需要自定义证书

根据"Michael - sqlbot" anwser,需要使用自定义证书。我最初的假设是使用 CNAME 将允许在使用我的自定义域时使用 Amazon S3 通配符证书,但这是错误的:自定义证书是绝对必需的,并且可以仅使用 CloudFront 进行设置,而不是 S3。

获取免费证书

您可以使用任何您想要的证书提供商,但在这里我选择 StartSSL (StartCom),它提供免费的 SSL 证书(但仅限于一个子域和 1 年)。

  • 验证您对域的所有权 mydomain.com
  • 使用域创建证书 files.mydomain.com
  • 下载证书(files.crt)和私钥(files.key,使用您的自定义密码加密):它们是 PEM 格式
  • 解密私钥:openssl rsa -in files.key -out files.key
  • 使用来自 here 的 StartSSL 文件生成证书链:cat sub.class1.server.ca.pem ca.pem >> chain.crt

将证书上传到 AWS

  • 安装AWS CLI上传证书(注意密钥必须是未加密的,证书是PEM格式,CloudFront需要证书链)。您必须选择一个名称和路径(选择您想要的但路径应以 /cloudfront/
  • 将您的证书上传到 AWS 以供 Cloudfront 使用,如记录的那样 hereaws iam upload-server-certificate --server-certificate-name CUSTOM_CERTIFICATE_NAME --certificate-body file://files.crt --private-key file://files.key --certificate-chain file://chain.crt --path /cloudfront/CUSTOM_PATH/

配置 CloudFront

  • 创建新的 Web 分发
  • 使用 CNAME:files.mydomain.com
  • Select "Custom SSL certificate" 单选按钮和 select 您的证书(CUSTOM_CERTIFICATE_NAME 您在上传时选择)
  • Select 您的 S3 存储桶作为 CloudFront 分发来源
  • 验证并等待部署完成:您应该使用 url 访问您的存储桶文件,例如 https://xyzxyzxyz.cloudfront.net/file

配置 DNS

  • 打开您的 mydomain.com DNS 配置
  • 添加 CNAME:files IN CNAME xyzxyzxyz.cloudfront.net
  • 等待 DNS 传播(请参阅 DNS TTL)(如果有新的 DNS 条目,可能会很快)

结束

您现在应该可以使用 https://files.mydomain.com/file 访问您的文件了。该证书将是您为 files.mydomain.com 生成的自定义证书,因此一切正常。