我的网站允许用户上传文件。我们使用典型的 Javascript+POST+Signature 将它们直接上传到 S3。这种方法效果很好,但有些本地网络反对 CORS 请求 - 用户有一个可以连接的主机白名单。
我很想为uploads.baconserker.com
我的 S3 存储桶提供一个 CNAME 别名来解决这个问题。但这违反了 SSL(证书名称与 s3 主机名不匹配)。我相信这种情况需要 SNI,而 Cloudfront 提供了 SNI。但是,我的用例实际上并不涉及 Cloudfront 或边缘缓存。是否可以直接为存储桶 https 端点设置 SNI?或者通过其他方法将上传通过我自己的主机名直接发送到 s3?
答案1
我认为这种情况需要 SNI,并且 Cloudfront 提供 SNI。但是,我的用例实际上并不涉及 Cloudfront 或边缘缓存。
公平地说,但这是官方的解决方案。S3 不直接支持 SSL 和自定义域。
另外,考虑一下:
CloudFront 不仅仅是一个 CDN。它还是一个 SSL 卸载器、主机:标头重写器、路径前置器、地理定位器、地理限制器、安全内容网关、http 到 https 重定向器、错误页面定制器、根页面替换器、Web 应用程序防火墙、源标头注入器、动态内容 gzipper、基于路径的多源 http 请求路由器、查看器平台标识符、DDoS 缓解器、区域顶点别名目标……所以不要太纠结于“CDN”或将一项服务堆叠在另一项服务前面的事实——CloudFront 的设计在很大程度上是为了补充 S3。它们各自专注于存储和交付的某些方面。
你可能会觉得我是 AWS 的秘密宣传者,但事实并非如此。我和 AWS 没有任何关系。我只是喜欢实用的工具,而 CloudFront 就像一把瑞士军刀,拥有许多与“CDN”基本无关的便捷功能。
因此 CloudFront 是一个可行的解决方案。它允许您使用自己的域名和 SSL 证书(您购买的证书或 ACM 提供的免费证书),和它可选择将域名与存储桶名称分离,因此存储桶名称不再需要与域匹配。
此外,如果您的整个站点都在 CloudFront 上,则您不一定需要uploads.
在主机名上 - 整个站点可以位于一个主机名后面,因为 CloudFront 允许您通过路径模式有选择地路由到不同的后端。
CloudFront 还将倾向于优化上传速度,因为客户端将连接到附近的边缘,并且客户端和存储桶之间的其余路径将位于 AWS 的托管网络上,而不是公共互联网上。
然而,您提到了“主机白名单”问题。CloudFront 有数万个 IP 地址,因此解决方案的这一部分仍然有些欠缺。它们是公开信息,但这是一个很大的列表。
不过,它比 S3 的情况要好,因为 AWS 不会像 CloudFront 那样单独发布 S3 的地址范围。
但是,如果您真的不想使用 CloudFront 路线,请在 EC2 中一个小型 t2.micro 实例上安装 HAProxy,该实例具有弹性 IP,与存储桶位于同一区域。将其配置为 S3 的反向代理,在那里安装您的证书,并将您的主机名指向它,然后配置代理以将标Host:
头重写回存储桶名称。
这意味着你有一个静态 IP和您的虚荣域。只要实例与存储桶位于同一区域,唯一的成本就应该是实例的成本,因为您不需要为同一区域内的 EC2 和 S3 之间的带宽付费。
自从 CloudFront 提供 SNI 之前我就一直这样做了(尽管当时实例是m1
),原因基本相同……不过最近我又多了一个这样做的理由。HAProxy 1.6 中的 Lua 解释器可用于操纵 S3 XML 错误响应通过注入对 XSL 样式表的引用,以便浏览器使它们变得漂亮。