首先,我搜索了网站上的类似主题,并阅读了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吗?根据{{3}},答案似乎是肯定的:
例如,如果您有一台服务器,您可以保存所有文档 在线,通常可以通过docs.example.com访问。您 也可能想通过documents.example.com访问它。一种方法 使这成为可能是添加指向的CNAME记录 documents.example.com到docs.example.com。当有人访问时 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),如果这些规则没有得到执行,那我怎么能确定我得到了什么?
因此,我认为可能会查询父域,直到root是获得FQDN的最可靠方式。但是我该怎么做呢?甚至可以在不使用PTR
的情况下获取FQDN(因为它不是可靠的)
6)DNS查询是否可以倒退?
通常查询IP是缓存/递归服务器请求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,它是如何工作的?
答案 0 :(得分:2)
"主机名"是一个定义不明确的术语,在许多不同的语境中用来表示许多不同的东西,粗略地说,除了作为可以被视为主机的东西的某种名称之外没有任何共同之处。试图对待所有被称为"主机名"同样的事情,甚至是某种定义明确的事情,只会导致沮丧和困惑。
完全限定的域名(FQDN)是一个特定于DNS的术语,可以追溯到RFC 1035,这意味着DNS域名完全拼写出所有组件标签(而不是域名会留下一些隐含的标签)通过上下文)。
"主机名"之间的唯一关系对于某些用于" hostname"的FQDN,它的值应该是FQDN。
答案 1 :(得分:2)
无论术语FQDN的语义如何,我们都必须看到 Python的socket.getfqdn()
做什么。
socket.getfqdn([name])
返回name的完全限定域名。如果省略名称或 空,它被解释为本地主机。要完全找到 限定名称,检查
gethostbyaddr()
返回的主机名, 然后是主机的别名(如果有)。第一个名字 包括一个期间被选中。如果没有完全合格的域名 可用,返回gethostname()
返回的主机名。socket.gethostbyaddr(ip_address)
返回主机名所在的三元组
(hostname, aliaslist, ipaddrlist)
响应给定ip_address的主要主机名,别名列表是 一个(可能是空的)备用主机名列表 地址和ipaddrlist是相同的IPv4 / v6地址列表 同一主机上的接口(最有可能只包含一个) 地址)。
换句话说,getfqdn()
首先查找反向 PTR
记录,无论A
或CNAME
记录指向哪个记录第一名。它会查找完全限定的域名(FQDN)并简单地为您提供第一个合适的域名,即以.
结尾的第一个, root 。 / p>
因此,FQDN : sa-in-f93.1e100.net
来自IP PTR
的{{1}}记录。
74.125.200.93
此处,具有域93.200.125.74.in-addr.arpa. 86400 IN PTR sa-in-f93.1e100.net.
的此主机名www
的FQDN实际上是按定义youtube.com
,包括点。同样,www.youtube.com.
不是FQDN,因为它实际上应该是sa-in-f93.1e100.net
:
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.
如何设计来确定给定名称的FQDN。
另一方面,规范名称 socket.getfqdn()
记录应该按设计(RFC 1035, 3.2.2)指向规范名称,但它通常用于它只是一个< em> alias ,因为它就像一个人一样。此外,CNAME
记录应该(RFC 1912, 2.1)给出相同的结果,因为它应该代表给定IP的规范名称。
如果只遵守了这一点,PTR
使用的方法就完全合适了。在此,socket.getfqdn()
没有相应的CNAME youtube-ui.l.google.com.
记录(PTR
使此假设成为假。
答案 2 :(得分:1)
1)它很复杂,其结果取决于系统名称解析设置,使用的库和上下文。在典型的Linux安装中,hostname是与主机关联的规范名称,可以是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
在CNAME
的DNS响应(“C”代表规范)中有youtube-ui.l.google.com
,因此您的库调用返回的“主机名”是规范名称,根据DNS。
使用DNS对IP地址进行反向查询是通过在PTR
78.193.58.216.in-addr.arpa
记录来进行的
$ 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时会因主机而异。通常的做法是在IP地址和名称之间设置固定的1对1映射,以用于此类用途,即使它们不代表主机对名称的含义。
另一个例子(使用/ 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,但是最有意义的是返回一个PQ。此的结果不能且不应可互换使用。
3):www.youtube.com
中的CNAME
是youtube-ui.l.google.com.
4)对于HTTP 1.1协议,您的客户端会在请求中告知服务器中URL服务器中的服务器名称,如果服务器获取了一个名称,它不会期望它可以拒绝它。 Youtube期望被称为www.youtube.com
,如果您连接到该请求并通过任何其他名称调用它,则处理此请求的服务器将返回404错误。