amazon-web-services - Route 53 别名 DNS 记录 : the alias target name does not lie within the target zone

标签 amazon-web-services dns amazon-route53

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

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

我的 api 使用以下参数设置托管区域:

  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 中是不可能的。但这似乎是为了解决不同的问题。

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

不……是的。

S3 依赖于浏览器认为主机名应该是什么(如传入的 Host header 所示),以便将请求发送到正确的存储桶。

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

对于不同的行为,例如http://bucket.example.com指向名为example-bucket的存储桶,您需要一个反向代理来处理 header 重写这样,当浏览器指定 Host:bucket.example.com 时,S3 会收到带有 Host:example-bucket.s3.amazonaws.com 的请求。

CloudFront 提供了这样的反向代理功能。

配置 CloudFront 分配时,您可以指定源域名(指向存储桶)和备用域名,后者指定您希望 CloudFront 从浏览器获得的内容。 CloudFront 会在运行中重写请求,以便 S3 看到的内容与浏览器发送的内容不同。

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

正如该页所述,S3 和 CloudFront 的定价结构使得单独使用 S3 或 S3 + CloudFront 之间的成本差异实际上可以是任意一种——实际上,同时使用两者的成本会稍微低一些,具体取决于存储桶位置、查看器位置、对象大小和缓存命中率(假设您没有禁用 CloudFront 缓存)。

如果您希望从根路径为 website/1 的 example-bucket 提供 https://website-1.example.com/ 你也可以这样做,但是有点棘手。

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

或者您可以使用 CloudFront 和 Lambda@Edge 触发器动态修改它。看起来可能是这样的。

'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 official AWS forum 上的示例。它仅适用于 S3 网站托管功能(不适用于 REST 端点),因为这是使用转发 header 白名单将主机 header 公开给 Lambda@Edge 所必需的。

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

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

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

关于amazon-web-services - Route 53 别名 DNS 记录 : the alias target name does not lie within the target zone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49472636/

相关文章:

hadoop - 在 Amazon EC2 上将 HDFS 与 Apache Spark 结合使用

javascript - 如何将 subdomain.site.com 和 www.site.com 解析为域名

nginx - 在 Amazon 为 EC2 实例创建具有故障转移功能的 UDP 负载均衡器

amazon-web-services - aws 基于 IP 的路由 - Route53

node.js - 使用 AWS 上的无服务器框架发送响应 header

amazon-web-services - 是否可以将 Amazon 的 EIP 从标准范围迁移/移动到 VPC 范围?

java - Apache tomcat 域 localhost 或其他 :8080 , 如何找到?

ruby - EncryptedDataBagItem.load 产生 'cannot convert nil into String'

amazon-route53 - "no matching Route53Zone found": Terraform's Route53 data source is not recognizing the hosted zone name

json - 在cloudformation json模板中添加PublicSubnet/PrivateSubnet的正确方法?