路由53别名DNS记录:别名目标名称不在目标区域内 [英] Route 53 alias DNS record: the alias target name does not lie within the target zone

查看:92
本文介绍了路由53别名DNS记录:别名目标名称不在目标区域内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为通过路由53购买的域设置别名.该别名将指向我的站点中具有以下URL的页面:

http://example.com/website/:id

我的api使用以下参数设置了hostedZone:

  var params = {
    CallerReference: req.body.projectId,
    Name: req.body.domain, 
    HostedZoneConfig: {
      Comment: `the zone created on ${today} for ${req.body.domain}`,
      PrivateZone: false
    }
  };

下一步,我将使用以下参数设置DNS记录:

var params = {
   ChangeBatch: {
    Changes: [
       {
      Action: "CREATE",
      ResourceRecordSet: {
       AliasTarget: {
        DNSName: `http://example.com/website/${req.body.projectId}`,
        EvaluateTargetHealth: false,
        HostedZoneId:  hostedZone.HostedZone.Id
       },
       Name: "example.com",
       Type: "A"
      }
     }
    ],
   },
   HostedZoneId: hostedZone.HostedZone.Id
  };

我得到一个错误,我的别名目标名称不在目标区域内.我缺少哪一步来正确设置它?

解决方案

DNS没有用于处理路径的机制,因此此处尝试的操作在DNS中是不可能的.但这似乎是解决另一个问题的尝试.

有没有一种方法可以路由到通用s3存储桶,而不是具有匹配名称的存储桶?

不...是的.

S3依赖于浏览器认为主机名的含义(如传入的Host标头所示),以便将请求发送到正确的存储桶.

因此,当单独使用S3时,如果DNS条目指向存储桶,则存储桶名称必须与主机名完全匹配.

对于不同的行为,例如http://bucket.example.com指向名为example-bucket的存储桶,您需要反向代理来处理标头重写,以便在浏览器指定Host: bucket.example.com时,S3接收到带有Host: example-bucket.s3.amazonaws.com的请求./p>

CloudFront提供了这种反向代理功能.

在配置CloudFront分配时,您可以指定一个原始域名(指向存储桶)和一个备用域名,它们指定您希望CloudFront对浏览器的期望. CloudFront会在运行中重写请求,以使S3看到的内容与浏览器发送的内容有所不同.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/MigrateS3ToCloudFront.html

如该页面所述,S3和CloudFront的定价结构使得单独使用S3或使用S3 + CloudFront之间的成本差异实际上可以以任何一种方式出现-两者结合使用的成本实际上要略低一些,具体取决于在存储桶位置,查看器位置,对象大小和缓存命中率(假设您未禁用CloudFront缓存)上.

如果您希望从example-bucket中以website/1/的根路径为https://website-1.example.com提供服务,您也可以这样做,但这会有些棘手.

您可以通过在CloudFront的Origin配置中设置Origin Path来一次性地静态执行此操作,因为此字段表示路径前缀,该前缀将在每个请求发送到Origin之前添加到该请求.

或者您可以使用带Lambda @ Edge触发器的CloudFront动态修改它.这就是可能的样子.

 '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-1.amazonaws.com';

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);
};
 

以上是我在官方上写并发布的示例AWS论坛.它仅可与S3网站托管功能一起使用(不适用于REST端点),因为这是必需的,以便使用转发的头白名单将主机头公开给Lambda @ Edge.

它从传入的主机名中获取前缀,并将其重写为路径前缀,同时将所有请求发送到同一存储桶.

请注意,您将需要在Origin Response触发器中使用一个补充功能来处理响应,并检查HTTP 30x重定向.由于我们正在做路径前缀,因此需要在反向路径上执行相反的操作,以使Location标头的路径正确锚定.

或者只为您的每个站点创建一个CloudFront分配-AWS不会为分配本身收费,仅会为其处理的请求收费.可以通过自动化轻松创建发行版-使用aws-cli或CloudFormation编写脚本.每个帐户的CloudFront分配的默认限制为200,但AWS支持将根据要求增加此限制.

I'm trying to set up an alias for a domain that is purchased through route 53. The alias is going to point to a page in my site with a URL like this:

http://example.com/website/:id

My api sets up a hostedZone with the following params:

  var params = {
    CallerReference: req.body.projectId,
    Name: req.body.domain, 
    HostedZoneConfig: {
      Comment: `the zone created on ${today} for ${req.body.domain}`,
      PrivateZone: false
    }
  };

In the next step, I'm setting up a DNS record with the following params:

var params = {
   ChangeBatch: {
    Changes: [
       {
      Action: "CREATE",
      ResourceRecordSet: {
       AliasTarget: {
        DNSName: `http://example.com/website/${req.body.projectId}`,
        EvaluateTargetHealth: false,
        HostedZoneId:  hostedZone.HostedZone.Id
       },
       Name: "example.com",
       Type: "A"
      }
     }
    ],
   },
   HostedZoneId: hostedZone.HostedZone.Id
  };

I get an error that my alias target name doesn't lie within the target zone. What step am I missing to set this up properly?

解决方案

DNS has no mechanism for handling paths, so what's being attempted here is something not possible in DNS. But it seems this was an attempt to solve a different problem.

Is there a way to route to a generic s3 bucket instead of a bucket with a matching name?

No... and yes.

S3 relies on what the browser thinks the hostname should be, as signified by the incoming Host header, in order to send the request to the correct bucket.

Thus when S3 is used by itself, if a DNS entry points to a bucket, the bucket name must exactly match the hostname.

For different behavior, such as http://bucket.example.com pointing to a bucket named example-bucket, you need a reverse proxy to handle header rewriting so that when the browser specifies Host: bucket.example.com, S3 receives a request with Host: example-bucket.s3.amazonaws.com.

CloudFront provides such a reverse proxy capability.

When configuring a CloudFront distribution, you specify an Origin Domain Name (pointing to the bucket) and an Alternate Domain Name, which specifies what you want CloudFront to expect from the browser. CloudFront rewrites the request in-flight so that what S3 sees differs from what the browser sends.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/MigrateS3ToCloudFront.html

As noted on that page, the pricing structures of S3 and CloudFront are such that the cost difference between using S3 by itself or S3 + CloudFront can actually go either way -- it can actually cost slightly less to use both together, depending on the bucket location, the viewer location, the size of the objects, and the cache hit ratio (assuming you don't disable the CloudFront cache).

If you want https://website-1.example.com to be served from your example-bucket with a root path of website/1/ you can do that, too, but it gets a little trickier.

You can do this on a one-off, static basis by setting the Origin Path on the Origin configuration in CloudFront, since this field represents a path prefix that will be prepended onto each request before it's sent to the origin.

Or you can modify it dynamically using CloudFront with a Lambda@Edge trigger. Here's what that might look like.

'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-1.amazonaws.com';

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);
};

The above is an example I wrote and posted on the official AWS forum. It only works with the S3 web site hosting feature (not the REST endpoints) becauae this is required in order for the host header to be exposed to Lambda@Edge using the forwarded header whitelist.

It takes the prefix from the incoming hostname and rewrites it into a path prefix, while sending all requests to the same bucket.

Note that you will need a complementary function in an Origin Response trigger for handling responses, checking for HTTP 30x redirects. Because of the path prefixing we're doing, the opposite will need to be done on the reverse path, so that the Location header's path will be correctly anchored.

Or just create a single CloudFront distribution for each of your sites -- AWS doesn't charge for the distribution itself, only for the requests it handles. Distributions can be easily created through automation -- scripting with aws-cli, or CloudFormation. The default limit on CloudFront distributions per account is 200, but AWS Support will increase this on request.

这篇关于路由53别名DNS记录:别名目标名称不在目标区域内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆