主机名和完全限定域名(FQDN)之间的区别

4

首先,我在网站上搜索了类似的主题,并阅读了RFC 1535和FQDN wiki,它们似乎没有回答这个问题。

让我以www.youtube.com为例。我使用的Python脚本:

import socket

for host in ["www.youtube.com"]:
    print(host)
    try:
        hostname, aliases, addresses = socket.gethostbyname_ex(host)
        fqdn = socket.getfqdn(host)
        print("  Aliases : ", aliases)
        print(" Hostname : ", hostname)
        print("     FQDN : ", fqdn)
        print("Addresses : ", addresses)
    except socket.error as msg:
        print("%15s : ERROR: %s" % (host, msg))

输出:

  Aliases :  www.youtube.com
 Hostname :  youtube-ui.l.google.com
     FQDN :  sa-in-f93.1e100.net
Addresses :  ['74.125.200.93', '74.125.200.190', '74.125.200.136', '74.125.200.91']

1) 主机名和FQDN之间的关系是什么?

根据网站http://kb.iu.edu/d/aiu(以及其他许多网站):对于邮件服务器“mymail.somecollege.edu”,主机名为“mymail”,域为“somecollege.edu”,将它们组合起来形成FQDN。但是,很明显这并不适用于www.youtube.com。那么,FQDN到底是什么,所有这些名称之间的关系是什么?

2) 当我反向查找IP 74.125.200.93时,主机名变成了sa-in-f93.1e100.net。为什么反向查找会将FQDN作为主机名呢?这些名称是否可以互换?

socket.gethostbyaddr('74.125.200.93')

 Hostname :  sa-in-f93.1e100.net
  Aliases :  []
Addresses :  ['74.125.200.93']

3)“Aliases : www.youtube.com”是否也被称为CNAME?根据http://support.dnsimple.com/articles/cname-record/的解释,答案似乎是肯定的:

例如,如果您有一个保存所有文档的服务器,并且该服务器通常通过docs.example.com访问,您也可能希望通过documents.example.com访问该服务器。使这成为可能的一种方法是添加一个指向docs.example.com的CNAME记录。当有人访问documents.example.com时,他们将看到与docs.example.com完全相同的内容。

4)如果上述说法正确,为什么我无法使用“youtube-ui.l.google.com”或“sa-in-f93.1e100.net”访问YouTube呢?下面是直接访问主机名和FQDN后的结果:

Google

404. That’s an error.

The requested URL / was not found on this server. That’s all we know.

编辑#1

很抱歉回复慢了,我仍在阅读那些RFC文档,并且有一些新问题:

再次以www.youtube.com为例。

5)FQDN是如何生成的?每次调用socket.getfqdn()host -t PTR时,它是否会查询父域直到根(动态生成)?还是只是PTR记录?(似乎查询FQDN依赖于反向查找)。如果它是PTR记录,那么我怎么确定它是FQDN,实际上它可以是FQDN,CNAME,别名,主机名或某些其他名称,如果区域DNS管理员想要这样设置。就像David和Esa Jokinen指出的那样(RFC 1912,2.1),如果不执行这些规则,那么我怎么确定我得到了什么?

因此,我认为查询父域直到根是获取FQDN最可靠的方法。但是我该如何做到这一点?是否可能在不使用PTR(因为它不可靠)的情况下获取FQDN?

6)DNS查询是否可以倒退进行?

通常,IP的查询是缓存/递归服务器询问根,然后是TLD,然后是子域,直到它获得IP。是否可能反向进行此操作?获取IP,然后以某种方式获取子域,然后是TLD,然后是根,然后我就获得了FQDN?

7)FQDN和IP不应该是一对一映射吗?

当我运行时,这是我得到的:

host 216.58.193.78

输出:

78.193.58.216.in-addr.arpa domain name pointer sea15s07-in-f78.1e100.net.
78.193.58.216.in-addr.arpa domain name pointer sea15s07-in-f14.1e100.net.

一个IP映射到两个FQDN,这是怎么回事呢?一台机器有两个FQDN,它是如何工作的呢?

你正在从Python的Socket API开始倒推,试图学习DNS术语,但在这个过程中变得非常困惑。实际上,你要求我们帮助解释socket API调用如何映射到DNS相关术语,这需要我们引用Python的文档-这是一个与主题无关的编程问题。(例如StackOverflow)此外,#4与Google在该IP地址上运行的Web服务器如何处理Web浏览器发送的不同“Hostname”标头有关。一旦将名称映射到IP地址或反向DNS(反之亦然),DNS的作用就结束了。 - Andrew B
@Alnitak,你有兴趣在Stack Overflow上处理这个问题吗?如果没有Python文档的参考,我将无法解析它,以便解释这些调用实际上正在做什么,因此我认为这个问题非常适合在SO上讨论。 - Andrew B
@AndrewB 我刚刚更新了StackOverflow上的帖子,使它们现在完全一样。感谢任何地方提供的帮助。 - oNion
3个回答

2
"主机名"是一个模糊的术语,在许多不同的上下文中使用,意思各不相同,大致上除了作为某种可以被视为主机名称的东西之外,没有任何共同点。试图将所有被称为"主机名"的东西视为相同的东西,甚至是某种明确定义的东西,只会导致挫败和混淆。
完全限定域名(FQDN)是一个DNS特定的术语,追溯到RFC 1035,意思是一个DNS域名,它用所有的组件标签完全拼写出来(与通过上下文留下一些标签暗示的域名相对)。
"主机名"和FQDN之间唯一的关系是,在某些使用"主机名"的情况下,它的值应该是一个FQDN。

2
无论 FQDN 术语的语义如何,我们必须看看 Python 的 socket.getfqdn() 做了什么。
socket.getfqdn([name])

Return a fully qualified domain name for name. If name is omitted or empty, it is interpreted as the local host. To find the fully qualified name, the hostname returned by gethostbyaddr() is checked, followed by aliases for the host, if available. The first name which includes a period is selected. In case no fully qualified domain name is available, the hostname as returned by gethostname() is returned.

socket.gethostbyaddr(ip_address)

Return a triple (hostname, aliaslist, ipaddrlist) where hostname is the primary host name responding to the given ip_address, aliaslist is a (possibly empty) list of alternative host names for the same address, and ipaddrlist is a list of IPv4/v6 addresses for the same interface on the same host (most likely containing only a single address).

换句话说,getfqdn() 首先查找反向 PTR 记录,而不管最初指向它的 ACNAME 记录是什么。它寻找一个完全合格的域名(FQDN),并简单地给出第一个合适的域名,即以 .,即根结尾的第一个域名。
因此,FQDN: sa-in-f93.1e100.net 来自 IP 74.125.200.93PTR 记录。
93.200.125.74.in-addr.arpa. 86400 IN    PTR     sa-in-f93.1e100.net.

这里,主机名为www,域名为youtube.com的FQDN实际上是定义为www.youtube.com.,包括句点。同样,sa-in-f93.1e100.net不是一个FQDN,因为它实际上应该是sa-in-f93.1e100.net.

  • sa-in-f93作为1e100的子域名
  • sa-in-f93.1e100作为net的子域名
  • sa-in-f93.1e100.net作为根域名的子域名,即.

选择sa-in-f93.1e100.net.而不是www.youtube.com.仅仅是基于socket.getfqdn()设计如何确定给定名称的FQDN的方式。

另一方面,CNAME 记录的规范名称应该指向规范名称(RFC 1035, 3.2.2),但它通常被用作别名,因为它的工作方式就像别名一样。此外,PTR 记录应该(RFC 1912, 2.1)给出相同的结果,因为它应该代表给定 IP 的规范名称。
如果只遵循这个规则,那么 socket.getfqdn() 方法使用的方式将是完全适当的。然而,CNAME youtube-ui.l.google.com. 没有相应的 PTR 记录(93.200.125.74.in-addr.arpa. IN PTR youtube-ui.l.google.com.),使得这个假设不成立。

1

1) 这是一项复杂的任务,其结果取决于系统名称解析设置、使用的库和上下文。在典型的Linux安装中,主机名是与主机关联的规范名称,可以是FQDN或短名称,但应该可以通过任一方式进行解析(如果正确设置)。如果使用类似NIS的东西,则主机名只能是短名称而不是FQDN。

您的示例(使用DNS):

$host www.youtube.com
www.youtube.com is an alias for youtube-ui.l.google.com.
youtube-ui.l.google.com has address 216.58.193.78

"www.youtube.com"在DNS响应中有一个"CNAME"("C"代表规范)指向"youtube-ui.l.google.com",因此您的库调用返回的"主机名"是DNS中的规范名称。使用DNS对IP地址进行反向查询时,通过在"78.193.58.216.in-addr.arpa"上请求"PTR"记录来完成。"
$ host -t PTR 78.193.58.216.in-addr.arpa
78.193.58.216.in-addr.arpa domain name pointer sea15s07-in-f78.1e100.net.

请注意,它指向的名称与我们之前获得的“主机名”不同。这是由于拥有该IP地址的ISP设置方式不同,并且在使用DNS时会因主机而异。即使它们不代表主机名称,也很常见地为此类用途设置固定的1对1映射IP地址和名称。
另一个例子(使用/etc/hosts):
#example hostfile
1.2.3.4 hosta hosta.example.net myothername.example.net
4.3.2.1 hostb.example.net hostb anothername

当使用您的代码但将 "www.youtube.com" 更改为 "hosta","hostb" 时,我们会得到:
hosta
('  Aliases : ', ['hosta.example.net', 'myothername.example.net'])
(' Hostname : ', 'hosta')
('     FQDN : ', 'hosta.example.net')
('Addresses : ', ['1.2.3.4'])
hostb
('  Aliases : ', ['hostb', 'anothername'])
(' Hostname : ', 'hostb.example.net')
('     FQDN : ', 'hostb.example.net')
('Addresses : ', ['4.3.2.1'])

在主机文件中,“hostname”是IP地址后面的第一个名称。别名是它之后的所有内容。FQDN是带有点的第一个名称。
同样,这可能因系统和库而异。
2)反向查找在DNS中为您提供了一个PTR,可以是任何东西。如果想要,它可以返回localhost。没有要求PTR是FQDN,但最好返回一个。从这个结果中不能和不应该互换使用。
3)是的,在DNS中,www.youtube.com是youtube-ui.l.google.com的CNAME。
4)对于HTTP 1.1协议,客户端在请求中告诉服务器URL栏中的服务器名称,如果服务器得到它不期望的名称,它可以拒绝它。Youtube希望被称为www.youtube.com,处理此请求的服务器如果您以任何其他名称连接并调用它,则返回404错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接