如何克服根域 CNAME 限制?

Posted

技术标签:

【中文标题】如何克服根域 CNAME 限制?【英文标题】:How to overcome root domain CNAME restrictions? 【发布时间】:2010-10-13 22:47:34 【问题描述】:

我们正在为我们的客户托管许多网络应用程序。很明显,他们希望使用自己的域来引用这些应用程序,通常他们希望任何输入 http://www.customer1.examplehttp://customer1.example 的用户都可以访问他们的 Web 应用程序。

我们面临的情况是,我们需要在不久的将来灵活地更改 IP 地址。而且我们不想依赖客户对其域进行 A 记录更改。所以我们认为使用CNAME 记录会起作用,但我们发现CNAME 记录不适用于根域。

基本上:

customer1.example IN CNAME customer1.mycompanydomain.example //this is invalid as the RFC
www.customer1.example IN CNAME customer1.mycompanydomain.example //this is valid and will work

我们希望能够更改customer1.mycompanydomain.exampleA 记录的IP 地址,我们的客户将遵循我们可以控制的此记录。

在我们的 DNS 中,它看起来像:

customer1.mycompanydomain.example IN A 192.0.2.1

有什么想法吗?

【问题讨论】:

我不明白为什么“customer1.com IN CNAME customer1.mycompanydomain.com”无效。我相信它应该工作。您能解释一下该解决方案的问题所在吗? 是的,请阅读以下问答。根据 DNS RFC,它是无效的。 ***.com/questions/655235/… 我不明白问题的标题。涉及的“根”(.)在哪里? 他是指区域的根,而不是“根” 那么,这不是通常的 DNS 词汇。 “顶点”不是正确的词吗?还是 Lisp 程序员的“***”? :-) 【参考方案1】:

这个问题仍然经常出现的原因是,正如您所提到的,某处被认为重要的人写道,RFC 声明在它们前面没有子域的域名是无效的。然而,如果你仔细阅读 RFC,你会发现这并不是它所说的那样。事实上,RFC 1912 表示:

不要过度使用 CNAME。在重命名主机时使用它们,但计划删除它们(并通知您的用户)。

一些 DNS 主机提供了一种使用自定义记录类型在区域顶点(根域级别,对于裸域名)获取类似 CNAME 的功能的方法。此类记录包括,例如:

DNSimple 中的别名 轻松实现 DNS 中的 ANAME easyDNS 上的 ANAME CloudFlare 的 CNAME

对于每个提供商,设置都相似:将您的***域的 ALIAS 或 ANAME 条目指向 example.domain.com,就像使用 CNAME 记录一样。 根据 DNS 提供商,空值或 @Name 值标识区域顶点。

ALIAS 或 ANAME 或 @example.domain.com。

如果您的 DNS 提供商不支持这种记录类型,并且您无法切换到支持的那种,您将需要使用子域重定向,这并不难,具体取决于需要的协议或服务器软件去做吧。

我强烈不同意仅由“业余管理员”或此类想法完成的说法。这是一个简单的“名称及其服务需要做什么?”交易,然后调整您的 DNS 配置以满足这些愿望;如果您的主要服务是 Web 和电子邮件,我看不出任何有效的理由说明永久删除 CNAME 会有问题。毕竟,谁会喜欢 @subdomain.domain.org 而不是 @domain.org ?如果您已经设置好协议本身,谁需要“www”?假设使用根域名无效是不合逻辑的。

【讨论】:

这个特定的答案对我非常有帮助,因为我想将根级域指向 CDN。大多数 CDN 必然是 FQDN,因为它可以在不同的位置或时间解析到不同的 IP。我使用 DNS Made Easy,并且能够使用 ANAME 记录类型。 我完全同意。想要从“裸”域名托管网站是一件常见且合乎逻辑的事情。它使用更少的字符,看起来更好等。如果一开始甚至需要(不是),url 自己的协议标识符(www)是 url 的残留部分。 ANAME 很好,或者您可以将所有非 www 的所有 301 设置为 www。通过免费的 301 重定向服务198.251.86.133【参考方案2】:

从技术上讲,对根记录进行 CNAME 并不违反 RFC,但确实有限制,这意味着不建议这样做。

通常您的根记录会有多个条目。比如说,3 个用于您的名称服务器,然后一个用于 IP 地址。

根据 RFC:

如果节点上存在 CNAME RR,则不应有其他数据 存在;

根据 IETF 的“常见 DNS 操作和配置错误”文档:

经验不足的管理员通常会尝试这样做 让您的域名也成为主机的方法。但是,DNS 像 BIND 这样的服务器会看到 CNAME 并拒绝添加任何其他 该名称的资源。由于不允许其他记录 与 CNAME 共存时,NS 条目将被忽略。因此所有的 podunk.xx 域中的主机也会被忽略!

参考资料:

https://www.rfc-editor.org/rfc/rfc1912 section '2.4 CNAME Records' http://www.faqs.org/rfcs/rfc1034.html '3.6.2.别名和规范名称'

【讨论】:

但是为什么不允许其他记录与 CNAME 共存。这只是 RFC 的作者添加的限制还是有技术原因?如果没有技术原因,那么可以很容易地想出一个扩展 RFC。 所以,如果它对我有用(使用 CNAME 作为根记录,该域的其他子域仍然有效),这意味着我很幸运,我的提供商 DNS 实施不会忽略额外的记录它可以吗?这也意味着我不需要担心客户端的任何问题,只要 DNS 服务器这样处理它? 这是试图回答另一个问题,“为什么 CNAME 不允许在顶点”,而实际问题是“如何克服这个限制”。 -1. 原因见serverfault.com/questions/613829/… CNAME'ing 根记录在技术上不违反 RFC 您需要解释它如何不违反 RFC1034 第 3.6.2 节:如果 CNAME RR 是存在于节点上,不应存在其他数据;这可确保规范名称及其别名的数据不能不同。。当然,“根”(在这种情况下正好是顶点)已经有 NSSOA 记录,因此不能有 CNAME 记录。【参考方案3】:

我不知道他们是如何逃脱的,或者他们可能会产生什么负面影响,但我正在使用 Hover.com 来托管我的一些域,并且最近将我的域的顶点设置为CNAME 那里。他们的 DNS 编辑工具根本没有抱怨,我的域很高兴通过分配的 CNAME 解析。

这是 Dig 向我展示的该域(实际域被混淆为 mydomain.com):

; <<>> DiG 9.8.3-P1 <<>> mydomain.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2056
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;mydomain.com.          IN  A

;; ANSWER SECTION:
mydomain.com.       394 IN  CNAME   myapp.parseapp.com.
myapp.parseapp.com. 300 IN  CNAME   parseapp.com.
parseapp.com.       60  IN  A   54.243.93.102

【讨论】:

混淆,如果真的需要(DNS 是公共的......),应该使用 RFC2606 指南。以及用于 IP 地址的 RFC5737 或 3849【参考方案4】:

我的公司为许多客户做同样的事情,我们为他们托管一个网站,尽管在我们的例子中它是 xyz.company.com 而不是 www.company.com。我们确实让他们在 xyz.company.com 上设置 A 记录,以指向我们分配给他们的 IP 地址。

关于如何应对 I​​P 地址的变化,我认为没有完美的解决方案。一些想法是:

使用 NAT 或 IP 负载平衡器并为您的客户提供属于它的 IP 地址。如果 Web 服务器的 IP 地址需要更改,您可以在 NAT 或负载均衡器上进行更新,

还提供 DNS 托管服务,让您的客户与您一起托管他们的域,以便您能够更新 A 记录,

让您的客户将他们的 A 记录设置到一个主 Web 服务器,并对每个客户的 Web 请求使用 HTTP 重定向。

【讨论】:

【参考方案5】:

Sipwiz 是正确的,唯一正确的方法是 HTTP 和 DNS 混合方法。我的注册商是 Tucows 的转售商,他们提供根域转发作为免费增值服务。

如果您的域是 blah.com,他们会询问您要将域转发到哪里,然后您输入 www.blah.com。他们将 A 记录分配给他们的 apache 服务器并自动将 blah.com 添加为 DNS 虚拟主机。虚拟主机响应 HTTP 302 错误,将它们重定向到正确的 URL。它的脚本/设置很简单,可以由低端处理,否则会被报废硬件。

运行以下命令作为示例: curl -v eclecticengineers.com

【讨论】:

【参考方案6】:

您必须在外部域的末尾加上一个句点,这样它就不会认为您的意思是 customer1.mycompanydomain.com.localdomain;

所以只要改变:

customer1.com IN CNAME customer1.mycompanydomain.com

customer1.com IN CNAME customer1.mycompanydomain.com.

【讨论】:

对我来说 (BIND 9.8.2),如果记录是针对域 customer1.com,这可行...但被解释为为子域 customer1.com.customer1.com 指定 CNAMe。如果我在第一项上添加一个点,记录将被正确解释,但它不再起作用。我在这里找不到解决方案。【参考方案7】:

一种解决方案是为 www 子域创建 CNAME,然后将根域转发到您的 www 子域。第一步在DNS设置中完成,第二步在Forward Domain部分完成。

参考:https://www.tachyonstemplates.com/2018/google-domains-forward-root/。

【讨论】:

【参考方案8】:

我看到 readytocloud.com 托管在 Apache 2.2 上。

在 Apache 中有一种更简单、更有效的方式将非 www 站点重定向到 www 站点。

将以下重写规则添加到 Apache 配置(在虚拟主机内部或外部。没关系):

RewriteCond %HTTP_HOST ^readytocloud.com [NC]
RewriteRule ^/$ http://www.readytocloud.com/ [R=301,L]

或者,如果您想要从非 www 站点到 www 站点的 URL 的一对一映射,则以下重写规则:

RewriteCond %HTTP_HOST ^readytocloud.com [NC]
RewriteRule (.*) http://www.readytocloud.com$1 [R=301,L]

注意,需要加载 mod_rewrite 模块才能使其工作。幸运的是,readytocloud.com 在 CentOS 机器上运行,默认情况下会加载 mod_rewrite。

我们有一个运行 Apache 2.2 的客户端服务器,它有不到 3,000 个域和近 4,000 个重定向,但是,服务器上的负载徘徊在 0.10 - 0.20 左右。

【讨论】:

问题是关于 DNS 的。与 Apache 网络服务器无关。【参考方案9】:

感谢 sipwiz 和 MrEvil。我们开发了一个 php 脚本,它将解析用户输入的 URL 并将www 粘贴到它的顶部。 (例如,如果客户输入kiragiannis.com,那么它将重定向到www.kiragiannis.com)。所以我们的客户将他们的根(例如customer1.com 指向我们的网络重定向器所在的A 记录),然后将www CNAME 指向我们管理的真实A 记录。

下面的代码以防您对我们未来感兴趣。

<?php
$url = strtolower($_SERVER["HTTP_HOST"]);

if(strpos($url, "//") !== false)  // remove http://
  $url = substr($url, strpos($url, "//") + 2);


$urlPagePath = "";
if(strpos($url, "/") !== false)  // store post-domain page path to append later
  $urlPagePath = substr($url, strpos($url, "/"));
  $url = substr($url, 0, strpos($url,"/"));



$urlLast = substr($url, strrpos($url, "."));
$url = substr($url, 0, strrpos($url, "."));


if(strpos($url, ".") !== false)  // get rid of subdomain(s)
  $url = substr($url, strrpos($url, ".") + 1);



$url = "http://www." . $url . $urlLast . $urlPagePath;

header( "Location:$url");
?>

【讨论】:

这实际上并没有回答 69k+ 人来此线程寻找的问题。问题更多是关于 DNS,与 PHP 无关。 问题是关于 DNS。与 PHP 编码无关。 HTTP_HOST 是主机名,就像它的名字所暗示的那样,而不是 URL。因此不会有任何http:// 可以删除,也不会有/$urlPagePath 将始终为空)。参见httpd.apache.org/docs/2.4/expr.html。由于代码试图摆脱子域的方式,它也不适用于 www.example.co.uk 之类的东西,其中 co.uk 必须被视为一个整体。它也不处理 HTTPS。最后使用 PHP 只是做一个 HTTP 重定向,任何网络服务器都可以在配置中做到这一点,过于复杂。所以简而言之,这当然不应该是这个问题的有效答案。 如果这条规则应该适用于所有主机,那么它应该作为 apache 配置来完成

以上是关于如何克服根域 CNAME 限制?的主要内容,如果未能解决你的问题,请参考以下文章

django 模型:如何克服“通过”ManyToMany 选项限制

如何克服 Snowflake Varchar (16,777,216) 加载图像数据的限制

您如何克服 HTML 表单嵌套限制?

如何克服 Autodesk Forge Viewer 中的窗口选择限制?

Golang - 如何克服 bufio 的 Scan() 缓冲区限制?

如何克服 `PERCENTILE_CONT` 的参数应该是常量的限制?