从AWS中的通配符域提供大量静态站点

问题描述 投票:2回答:2

我在这里遇到了一个非常具体的问题,我们已经拥有并维护了一个系统,该系统涉及使用子域将人们路由到特定的应用程序。

在传统的服务器上,如下所示;我们有一个通配符子域,* .domain.com路由到nginx并提供一个文件夹

所以myapp.domain.com> nginx>提供myapp app文件夹> myapp文件夹包含一个静态网站

我试图以某种方式将其迁移到AWS,我基本上需要在AWS中做类似的事情,我玩弄了将每个静态应用程序放入s3桶然后在​​路由53中使用通配符域的想法,但我是不确定s3如何知道要提供哪个文件夹,因为该功能不是路由53的一部分

有人有什么建议吗?

感谢你的帮助

amazon-web-services amazon-s3 amazon-route53
2个回答
9
投票

CloudFront + Lambda @ Edge + S3可以做到“无服务器”。

Lambda @ Edge是一种CloudFront增强功能,它允许将请求和响应的属性表示和操作为简单的JavaScript对象。在检查缓存之前(“查看器请求”触发器)或在请求进入后端之前(“原始服务器”,在这种情况下为S3网站托管端点),可以在请求处理期间配置触发器以触发跟踪高速缓存未命中(“原始请求”触发器)...或在响应处理期间,在从原点接收响应之后但在考虑将其存储在CloudFront高速缓存(“原始响应”触发器)之前,或者在最终确定之前响应浏览器(“查看器响应”触发器)。响应触发器还可以检查原始请求对象。

以下片段是我在AWS论坛上最初的posted。它是一个Origin Request触发器,它将原始主机名与您的模式进行比较(例如,域必须与*.example.com匹配),如果匹配,则主机名前缀subdomain-here.example.com是从为子域命名的文件夹中提供的。

lol.example.com/cat.jpg        -> my-bucket/lol/cat.jpg
funny-pics.example.com/cat.jpg -> my-bucket/funny-pics/cat.jpg

通过这种方式,您可以从一个存储桶中提供来自任意数量的子域的静态内容。

为了访问原始传入的Host头,需要将CloudFront配置为whitelist the Host header for forwarding to the origin,即使Lambda函数执行的最终结果是在原始实际看到它之前修改该值。

代码实际上非常简单 - 以下大多数是解释性注释。

'use strict';

// if the end of incoming Host header matches this string, 
// strip this part and prepend the remaining characters onto the request path,
// along with a new leading slash (otherwise, the request will be handled
// with an unmodified path, at the root of the bucket)

const remove_suffix = '.example.com';

// provide the correct origin hostname here so that we send the correct 
// Host header to the S3 website endpoint

const origin_hostname = 'example-bucket.s3-website.us-east-2.amazonaws.com'; // see comments, below

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;
    const host_header = headers.host[0].value;

    if(host_header.endsWith(remove_suffix))
    {
        // prepend '/' + the subdomain onto the existing request path ("uri")
        request.uri = '/' + host_header.substring(0,host_header.length - remove_suffix.length) + request.uri;
    }

    // fix the host header so that S3 understands the request
    headers.host[0].value = origin_hostname;

    // return control to CloudFront with the modified request
    return callback(null,request);
};

请注意,来自S3的索引文档和重定向可能还需要Origin Response触发器来针对原始请求规范化Location标头。这取决于您使用的S3网站功能。但上面是一个说明一般想法的工作实例。

请注意,const origin_hostname需要设置为CloudFront原始设置中配置的存储桶端点主机名。在此示例中,存储桶位于us-east-2中,并且网站托管功能处于活动状态。


0
投票
  1. 创建Cloudfront分发
  2. 在cloudfront分发中添加所有Alternate CNAMEs记录
  3. 添加自定义源作为EC2服务器。
  4. 根据您的要求设置行为。
  5. 在服务器中配置nginx虚拟主机以路由到特定文件夹。
© www.soinside.com 2019 - 2024. All rights reserved.