如何克服根域CNAME的限制?


116

我们为客户托管了许多Web应用程序。显而易见,他们希望使用自己的域来引用这些应用程序,通常,他们希望键入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

有任何想法吗?


我不明白为什么“ CNAME中的customer1.com customer1.mycompanydomain.com”无效。我相信它应该起作用。您能否解释该解决方案的问题所在?
sleske

3
是的,请阅读以下问答。根据DNS RFC无效。 stackoverflow.com/questions/655235/...
地理

2
我不明白问题的标题。其中涉及“根”(。)?
bortzmeyer

2
他指的是区域的根,而不是“根”
Alnitak

2
好吧,这不是通常的DNS词汇。“顶点”不是正确的词吗?还是Lisp程序员的“顶级”?:-)
bortzmeyer

Answers:


63

正如您提到的那样,仍然经常出现此问题的原因是,正如您提到的那样,某处某人以某种重要的方式写道,RFC声明在其前面没有子域的域名无效。但是,如果仔细阅读RFC,您会发现这与表述不完全相同。实际上,RFC 1912指出:

不要太过喜欢CNAME。重命名主机时使用它们,但要摆脱它们(并通知您的用户)。

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

  • DNSimple的ALIAS
  • DNS的ANAME轻松实现
  • easyDNS的ANAME
  • CloudFlare的CNAME

对于每个提供商,设置都类似:将您的顶点域的ALIAS或ANAME条目指向example.domain.com,就像处理CNAME记录一样。取决于DNS提供程序,一个空值或@ Name值标识区域顶点。

ALIAS或ANAME或@ example.domain.com。

如果您的DNS提供程序不支持这种记录类型,并且您无法切换到支持这种记录类型的记录,则需要使用子域重定向,这并不难,具体取决于需要执行此操作的协议或服务器软件。

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


1
这个特殊的答案对我很有帮助,因为我想将根域指向CDN。大多数CDN必然是FQDN,因为它可以在不同的位置或时间解析为不同的IP。我使用DNS Made Easy,并且能够使用ANAME记录类型。
鲁比克斯2015年

3
我完全同意。想要从“裸”域名托管网站是一件常见且合乎逻辑的事情。它使用更少的字符,看起来更好,等等。url自己的协议标识符(www)是url的残余部分,即使一开始是必需的(不是)。
Ed Bishop

3
ANAME很不错,或者您也可以将所有非www都www替换为www。通过免费的301重定向服务 198.251.86.133
Jacob Evans

51

CNAME根记录在技术上并不违反RFC,但确实有局限性,因此不建议这样做。

通常,您的根记录将具有多个条目。假设3个代表您的名称服务器,然后1个代表IP地址。

根据RFC:

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

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

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

参考文献:


17
但是,为什么没有其他记录可以与CNAME共存。这仅仅是RFC作者添加的限制,还是出于技术原因?如果没有技术原因,那么可以很容易地提出一个扩展RFC。
2013年

因此,如果它对我有用(使用CNAME作为根记录,该域的其他子域仍在工作),这意味着我很幸运,我的提供商的DNS实施不会忽略附加记录,它可以吗?而且这也意味着只要DNS服务器像这样处理它,我就不必担心客户端方面的任何问题?
didi_X8 2014年

这是试图回答另一个问题“为什么在顶点处不允许使用CNAME”,而实际的问题是“如何克服此限制”。-1。
rustyx '16


从技术上讲,CNAME根记录不是针对RFC的, 您将需要解释它是否不符合RFC1034第3.6.2节的规定:如果节点上存在CNAME RR,则不应该存在其他数据。这样可以确保规范名称及其别名的数据不能不同。。当然,“根”(即顶点正是在这种背景下)早已NSSOA记录,因此不能有CNAME记录。
Patrick Mevzek '18年

4

我不知道他们如何摆脱它,或者它们可能带来什么负面影响,但是我正在使用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
Patrick Mevzek,

3

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

至于如何应对IP地址的更改,我认为没有完美的解决方案。一些想法是:

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

  • 还提供DNS托管服务,并让您的客户与您托管他们的域,以便您可以更新A记录,

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


3

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

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

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


3

您必须在外部域的末尾加上句号,以免您的意思不是customer1.mycompanydomain.com.localdomain;

因此,只需更改:

customer1.com IN CNAME customer1.mycompanydomain.com

customer1.com IN CNAME customer1.mycompanydomain.com.

对我来说(BIND 9.8.2),如果记录是针对domain的customer1.com,则可以使用...但是被解释为为subdomain指定CNAMe customer1.com.customer1.com。如果我在第一个项目上添加一个点,则该记录将被正确解释,但不再起作用。我在这里看不到任何解决方案。
Jussi Hirvi '19

-2

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

将非www站点重定向到Apache中的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 Web服务器无关。
SamTzu

-7

感谢sipwiz和MrEvil。我们开发了一个PHP脚本,该脚本将解析用户输入的URL并将其粘贴www到其顶部。(例如,如果客户输入kiragiannis.com,那么它将重定向到www.kiragiannis.com)。因此,我们的客户指出了他们的根源(例如customer1.comA记录了Web重定向器的位置),然后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}");
?>

10
实际上,这并不能回答69k +人来此线程寻找的问题。问题更多是关于DNS,与PHP无关。
马特·克拉克

1
问题是关于DNS。与PHP编码无关。
SamTzu

就像其名称所示,HTTP_HOST是主机名,而不是URL。因此,将没有任何http://要删除的东西,也不会/$urlPagePath总是空的)。cf httpd.apache.org/docs/2.4/expr.html。由于代码试图摆脱子域的方式,因此对于诸如必须整体考虑的www.example.co.uk地方,它也不起作用co.uk。它还不处理HTTPS。最后使用PHP进行HTTP重定向,使任何Web服务器都可以在配置中完成它,这太复杂了。简而言之,这肯定不是该问题的有效答案。
Patrick Mevzek '18年

如果该规则适用于所有主机,则应作为apache配置完成
Svetoslav Marinov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.