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

differences between hostname and fully qualified domain name(FQDN)

首先我在网站上搜索了类似的主题,并阅读了 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/答案似乎是:

For example, if you have a server where you keep all of your documents online, it might normally be accessed through docs.example.com. You may also want to access it through documents.example.com. One way to make this possible is to add a CNAME record that points documents.example.com to docs.example.com. When someone visits documents.example.com they will see the exact same content as 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(因为它不是 relialbe)

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

通常查询 IP 是 cache/recursive 服务器询问 root,然后是 TLD,然后是子域,直到它获得 IP。有可能向后这样做吗?获得 IP,然后以某种方式获得子域,然后是 TLD,然后是 root,然后我获得了 FQDN?

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

这是我 运行

时得到的
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,如何运作?

"Hostname" 是一个定义不明确的术语,在许多不同的上下文中用来表示许多不同的事物,粗略地说,除了是某种可以被认为是主持人。试图将所有称为 "hostname" 的东西都视为同一事物,甚至是某种定义明确的事物,只会导致沮丧和困惑。

完全限定域名 (FQDN) 是可追溯到 RFC 1035 的特定于 DNS 的术语,意思是完整拼写出所有组件标签的 DNS 域名(相对于留下一些标签的域名)上下文暗示的标签)。

"hostname" 和 FQDN 之间的唯一关系是,对于 "hostname" 的某些用途,它的值应该是 FQDN。

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.comyoutube-ui.l.google.com 的 DNS 响应("C" 代表规范)中有一个 CNAME,所以 "hostname" return由您的图书馆调用编辑的是根据 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.

请注意,它指向的名称与我们之前获得的 "hostname" 不同。这是由于拥有 IP 地址的 ISP 如何设置,并且在使用 DNS 时会因主机而异。为这种用途在 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,它实际上可以是任何东西。如果需要,它可以 return localhost。不要求 PTR 必须是 FQDN,但对 return 这样的 PTR 最有意义。 不能的结果不应互换使用。

3) 在 DNS 中是 www.youtube.comyoutube-ui.l.google.com.

CNAME

4) 对于 HTTP 1.1 协议,您的客户端在请求中告诉服务器 URL 栏中的服务器名称,如果服务器得到一个它不期望的名称它可以拒绝它。 Youtube 预计被称为 www.youtube.com 并且处理此请求的服务器 return 如果您连接到它并使用任何其他名称调用它,则会出现 404 错误。

无论术语 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()先找reversePTR记录,不管A还是CNAME记录首先指出了它。它会寻找一个 完全限定的域名 (FQDN) 并简单地为您提供第一个合适的域名,即第一个以 . 结尾的域名,root.

因此,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.

此处,具有域 youtube.com 的主机名 www 的 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) point to the canonical name, but it's commonly used like it was just an alias, because it works like one. Also, the PTR record SHOULD (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.) 使这个假设错误。