【问题标题】:Serverless proxy of custom domain (with sub domain) to S3 endpoint自定义域(带子域)到 S3 端点的无服务器代理
【发布时间】:2017-07-03 20:10:10
【问题描述】:

我有什么

我有一个名为 example-dev.com 的 S3 存储桶配置为用于网络托管。

我的 S3 存储桶有几个名为 client-site.combig-project.com 的子文件夹。所以在 S3 上,访问 client-site.com 的开发主页的 URL 是 example-dev.com.s3-website-us-east-1.amazonaws.com/client-site.com/index.html。这会影响到大约十几个站点,并且站点列表会随着客户的进出而定期更改。

我想要做什么

我正在尝试将该原始 S3 URL 映射到我的 example-dev.com 自定义域的子域。我要:

client-site.com.example-dev.com/index.html

在以下位置提供文件

example-dev.com.s3-website-us-east-1.amazonaws.com/client-site.com/index.html

我会使用 DNS 进行映射,但每个站点都有一个子文件夹,并且这些文件夹会定期更改。

如果可能的话,我想使用无服务器架构来做到这一点。我有一个版本,在节点服务器上使用 http-proxy 可以正常工作,但我想看看是否有可能没有一个VPS。我想我打算使用 API Gateway 和/或 Lambda,但我正在努力解决 API Gateway 问题,我不知道 Lambda 是否能够像 http-proxy 一样重新映射请求。

感谢任何帮助,非常感谢!

【问题讨论】:

    标签: amazon-s3 proxy aws-lambda aws-api-gateway serverless-framework


    【解决方案1】:

    除非我遗漏了什么,否则听起来您并不需要 API Gateway 来解决这个问题。

    听起来您需要进入 DNS 并创建一个名为 client-site.com.example-dev.com 的 CNAME 条目,并将其直接指向 S3 存储桶。在这种情况下,您必须为每个“子文件夹”创建一个 S3 存储桶。我不知道这是否可以改变。

    但这一切都可以通过 DNS 完成,而不是仅仅为了映射请求路径而购买任何类型的代理。

    【讨论】:

    • 谢谢,在大多数情况下这是一个非常有效的解决方案,这也是我在我的个人网站上所做的。在我的情况下,我正在处理的客户端站点经常更改,因此我让服务器动态地重新映射它们,而不是不断地创建和删除 DNS 记录。我已经更新了我的问题以澄清这一点。
    【解决方案2】:

    这应该可以使用 CloudFront 和 Lambda@Edge 后面的 S3,一旦它超出预览版(或者如果您可以进入预览版,但如果他们仍在接受预览请求,则需要等待),因为您可以读取 HTTP 标头并在运行中修改请求 URI——将主机标头的一部分添加到路径中。

    不过,目前@JackKohn-AWS 的解决方案可以通过一级简化来实现:您不必为每个站点编辑 DNS。

    您可以在 Route 53 中为 *.example.com 创建一个通配符 CNAME,直接指向 s3-website-[region].amazonaws.com。然后,您需要做的就是在该区域创建存储桶,以您要创建的测试站点命名,例如client.example.org.example.com - 因为在您创建 Route 53 通配符后,DNS 已经为该区域中以 .example.com 结尾的任何有效存储桶名称设置。

    这是因为 S3 中的一个实现细节而起作用—— 您使用的实际 CNAME 目标实际上不必是控制台中显示的存储桶的网站端点——它只需是区域网站托管端点的基本名称。解析路径对哪个存储桶为请求提供服务没有任何作用。只要它到达正确的区域端点,Host 标头就会标识存储桶。

    这不是您要求的,因为它是每个客户端站点一个存储桶,但是一旦使用通配符 CNAME 配置 DNS,您创建的具有匹配名称的任何存储桶都已连接以进行解析。


    这在 API Gateway 中应该不是不可能的,但它似乎超出了那里的预期用途。响应正文的有效负载限制为 10 MB。

    【讨论】:

    • 这是一个非常聪明的解决方案,感谢分享。我一定会关注 Lambda@Edge
    • 好的,所以我很好奇,不得不尝试看看是否可以让 API Gateway 来执行此操作。初步结果很有希望:curl -v https://ca5example.execute-api.us-east-2.amazonaws.com/test/pics/funny/cat.png 从我的存储桶返回 expected 错误,表明我已成功将标准主机名重新映射为路径前缀(减去 API“阶段”名称 /test,您可以省略自定义域):Code: NoSuchKeyMessage: The specified key does not exist.Key: ca5example.execute-api.us-east-2.amazonaws.com/pics/funny/cat.png。所以确实有可能做到这一点。
    • 奇怪的是,控制台会让我相信它不会工作。当我包含 Host 标头时,Endpoint URL 旁边会出现一个橙色三角形,我已将其映射到方法请求中,并在集成请求中创建为具有相同名称的路径参数。 The endpoint you have entered contains parameters that are not defined in the resource path. Parameters are case sensitive. 但是......到目前为止它确实有效。
    【解决方案3】:

    一种解决方案是在主机 ec2 上安装 nginx,并使用 proxypass 将请求代理到 s3 内容。这样您就可以使用友好的 url client-site.com.example-dev.com 继续访问内容。您的 DNS 记录现在必须指向主机 ec2 机器,该机器将使用 nginx 根据访问的 url 将请求路由到适当的后端 s3 内容。

    你也可以为不同的客户端设置多个监听器

    安装 nginx

    yum nginx install
    

    Nginx 配置应包含:

    server {
            listen 80;
            server_name client-site.com.example-dev.com;
    
            location / {
                    proxy_pass http://example-dev.com.s3-website-us-east-1.amazonaws.com/client-site.com/index.html;
                    proxy_set_header Host $http_host;
                    proxy_set_header  X-Real-IP  $remote_addr;
            }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-27
      • 1970-01-01
      • 2018-09-02
      • 2019-08-29
      • 2011-06-29
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多