如何克服根域CNAME限制?

时间:2009-03-17 21:05:14

标签: networking dns rfc cname

我们正在为客户托管许多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

有什么想法吗?

8 个答案:

答案 0 :(得分:55)

这个问题经常出现的原因是因为,正如你所提到的,在某个地方某个人被认为是重要的人写道,RFC声明在他们面前没有子域名的域名是无效的。但是,如果您仔细阅读RFC,您会发现这并不完全符合它的说法。实际上,RFC 1912表示:

  

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

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

  • 在DNSimple的ALIAS
  • DNS Made Easy的ANAME
  • easyDNS上的ANAME
  • CloudFlare的CNAME

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

ALIAS或ANAME或@ example.domain.com。

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

我强烈不同意仅由"业余管理员"做出的声明。或者这样的想法。这很简单"名称及其服务需要做什么?"处理,然后调整您的DNS配置以满足这些愿望;如果您的主要服务是网络和电子邮件,我不会'看到为什么放弃CNAME for good的任何有效原因都会有问题。毕竟,谁更喜欢@ subdomain.domain.org而不是@ domain.org?谁需要" www"如果您已经使用协议本身设置了?假设使用根域名无效,这是不合逻辑的。

答案 1 :(得分:47)

CNAME的根记录在技术上并不是针对RFC的,但确实有一些限制意味着它是一种不推荐的做法。

通常,您的根记录会有多个条目。比方说,3代表你的名字服务器,然后代表一个IP地址。

根据RFC:

  

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

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

  

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

参考文献:

答案 2 :(得分: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

答案 3 :(得分:3)

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

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

运行以下命令以获取示例: curl -v eclecticengineers.com

答案 4 :(得分:3)

您必须在外部域的末尾添加句点,因此它不认为您的意思是customer1.mycompanydomain.com.localdomain;

所以只需改变:

customer1.com IN CNAME customer1.mycompanydomain.com

customer1.com IN CNAME customer1.mycompanydomain.com.

答案 5 :(得分:2)

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

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

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

  • 同时提供DNS托管服务,让您的客户随身携带他们的域名,以便您能够更新A记录,

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

答案 6 :(得分:-1)

我看到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左右。

答案 7 :(得分:-3)

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