大家好!今年早些时候,当我在写《??DNS 是如何工作的???》时,有人问我——为什么人们有时会在域名末尾加一个点?例如,如果你通过运行digexample.com来查询example.com的IP,你将看到这样的内容:$digexample.comexample.com.5678INA93.184.216.34Executed在dig命令之后,example.com有一个.-变成example.com.!发生了什么?一些DNS工具还需要在传递给它的域名后加一个.:如果你在使用miekg/dns时传递它example.com,它会报错://tryingtosendthismessagewillreturnanerrorm:=new(dns.Msg)m.SetQuestion("example.com",dns.TypeA)最初我以为我知道这个问题的答案(“好吧,末尾的点表示域名完全受限?”)。没错——完全限定域名(FQDN)就是以.结尾的域名!但为什么末尾的点有用且重要?在DNS请求/响应中,没有“.”。在域名的末尾。我曾经(错误地)认为“为什么末尾有一个点?”的答案。可能是“在DNS请求/响应中,域名有一个.,因此我们将其放入以匹配您的计算机实际发送/接收的内容”。但事实并非如此!当计算机发送DNS请求/响应时,域名末尾没有点。实际上,域名中没有点。域名被编码为一系列长度/字符串对。比如域名example.com就是被编码成这13个字节。7example3com0的编码内容完全没有点。ASCII域名(如example.com)被各种DNS软件转换为DNS请求/响应中使用的格式。今天我们要讨论一个将域名转换为DNS响应的地方:区域文件。这”。”在区域文件中域名的末尾有些人管理域名DNS记录的方式是创建一个称为“区域文件”的文本文件,然后配置一些DNS服务器软件(例如nsd或bind)来提供区域文件中指定的DNS记录。以下是example.com的示例区域文件:orange300INA1.2.3.4fruit300INCNAMEorangegrape3000INCNAMEexample.com。在此文件中,任何不以.结尾的区域(例如orange)都会自动后跟.example.com。所以orange成为orange.example.com的缩写。DNS服务器从其配置中知道这是一个example.com区域文件,因此它知道自动将example.com附加到所有不以点结尾的名称。我想这里的想法只是为了保存几个字符——如果要输入全名,区域文件将如下所示:orange.example.com。300INA1.2.3.4fruit.example.com。300INCNAMEorange.example。com.grape.example.com。3000INCNAMEexample.com。确实有更多的角色。您也可以在没有区域文件的情况下使用DNS虽然官方DNSRFC(RFC1035)定义了区域文件格式,但您也可以在没有区域文件的情况下使用DNS。例如,AWSRoute53不使用区域文件来存储DNS记录!您可以通过Web界面或API创建记录,我猜他们使用某种数据库而不是一堆文本文件来存储记录。但是,Route53(与许多其他DNS工具一样)确实支持导入和导出区域文件,如果您切换DNS提供商,该功能可能会有用。这”。”在dig命令输出的末尾现在让我们讨论dig命令的输出:$digexample.com;<<>>DiG9.18.1-1ubuntu1.1-Ubuntu<<>>+allexample.com;;全局选项:+cmd;;得到答案:;;->>HEADER<<-操作码:QUERY,状态:NOERROR,id:10712;;标志:qrrdra;查询:1,答案:1,权限:0,附加:1;;选择伪部分:;EDNS:版本:0,标志:;UDP:65494;;问题部分:;example.com。在一个;;答案部分:example.com。81239INA93.184.216.34一件奇怪的事是几乎每一行都以;;开头,这是怎么回事?;是区域文件中的注释字符!我想之所以dig输出这么奇怪,可能是因为当你把这些内容粘贴到zone文件中时,不加修改就可以直接使用了。这就是为什么example.com有一个.最后-区域文件要求域名末尾有点(否则它们将被解释为相对于区域)。所以dig也做同样的事情。我真的希望dig有一个+human选项以更人性化的方式打印出这些信息,但现在我懒得费心去实际贡献代码来做这件事(而且我不擅长C),所以我只能在我的博客上抱怨它:笑脸:“。”在curl命令输出的末尾让我们看另一个带有.最后:卷曲!我家里有一台名为grapefruit的电脑,上面运行着一个网络服务器。当我执行curlgrapefruit时,它输出:$curlgrapefruit
...这很好用!但是如果我在域名后面加一个.呢?报错:$curlgrapefruit.curl:(6)Couldnotresolvehost:grapefruit.发生了什么?为了理解,我们需要先了解搜索域:首先看一下搜索域当我执行curlgrapefrult时,它是如何转换成DNS请求的?您可能会认为我的计算机会向域名grapefruit发送请求,对吧?但事实并非如此。让我们使用tcpdump来准确查看正在查询的域。$sudotcpdump-i任何端口53[...]A?葡萄柚.lan.(32)其实是对grapefruit.lan的请求。。为什么?解释一下:curl调用函数getaddrinfo查询柚子getaddrinfo查询我电脑/etc/resolv.conf中的文件/etc/resolv.conf。conf里面有两行:nameserver127.0.0.53searchlan因为有一行searchlan,所以getaddrinfo在grapefruit的最后加了一个lan,去查询grapefruit.lan什么时候用的search域?现在我们知道了一些奇怪的事情:当我们查询一个域时,有时会在末尾附加一个额外的东西(比如lan)。但这什么时候发生?如果我们在域名的末尾加上一个.,那么这个时候就不会使用搜索域了。如果域名中间包含.(如example.com),则默认不会使用搜索域。但是可以通过修改配置来改变处理逻辑(更详细的说明在ndots)我们现在知道curlgrapefruit的原因了。和curlgrapefruit有不同的结果——因为一个查询是grapefruit.,而另一个查询是grapefruit.lan.。我的计算机如何知道要使用哪个搜索域?当我连接到路由器时,它通过DHCP告诉我它的搜索域是lan——这就是它为我的计算机分配IP的方式。那么为什么要在域名末尾加一个点呢?现在我们已经了解了区域文件和搜索域,这就是我认为人们在域名末尾加点的原因:有两种情况,域名被修改,而其他内容被添加到末尾。在example.com的区域文件中,grapefruit将在我的本地网络上转换为grapefruit.example.com(我的计算机已经配置为使用搜索域lan)),Grapefruit被转换为Grapefruit.lan所以,因为在某些情况下,域名实际上可能会转换为其他名称,人们只需在末尾添加一个.这意味着“这是域名,您不需要在末尾添加任何内容,仅此而已对它”。否则会造成混乱。“仅此而已”的技术术语是**完全合格的域名,简称“FQDN”。所以google.com。是完全限定的域名,而google.com不是。我总是要提醒自己为什么这样做,因为我很少使用区域文件和搜索域,所以我经常觉得——“当然我指的是google.com而不是google.com.something。否则!为什么我会是别的意思吗?那太傻了!”但是有些人确实使用区域文件和搜索域(例如Kubernetes使用搜索域!),所以最后的.很有用,它可以让人确切地知道不应该添加其他东西。什么时候是“。”加在最后?这里有一些关于何时添加“。”的快速说明。在域名末尾:需要添加:配置DNS时配置DNS时,使用完全限定的域名从来都不是坏事。您不必:非完全限定域名通常工作得很好,但我从未遇到过不接受完全限定域名的DNS软件。一些DNS软件要求这样:现在我用于jvns.ca的DNS服务器允许我在域名末尾添加.(例如在CNAME记录中),如果我不这样做,它会说在我输入的内容末尾添加.jvns.ca。我不同意这个设计决定,但这没什么大不了的,我只是在最后放了一个。。无需添加:令人困惑的是,在浏览器中,添加一个.在域名的末尾不能正常工作。例如,如果我在浏览器中输入https://twitter.com.,它会抛出一个错误。它将返回404。我认为这里发生的是它将HTTPHost标头设置为Host:twitter.com,而另一端的Web服务器期望Host:twitter.com。同样,https://jvns.ca.出于某种原因返回了SSL错误。我认为相对域过去更常见的最后一件事:我认为“相对”域(如葡萄柚,当我指的是我家的另一台计算机时grapefruit.lan)曾经更常用,因为DNS是在大学或其他大型机构中开发的拥有庞大内部网络的机构。使用像example.com这样的“绝对”域名在当今的Internet上似乎更为普遍。