基本网络故障排除

2022-02-15 15:14:09

关于存在和其他事情的重要性的观点,主要是我自己的观点。有很多可能的原因导致你无法连接到远程系统,不,它';它并不总是DNS。能够快速确定问题最可能的原因是什么(或者:谁能解决问题)是一项有用的技能,然而,我经常看到,即使是高级工程师也会浪费时间去追逐虚假的信号和转移注意力,因为通过更好地理解可能遇到的各种错误信息的具体含义,可以很快排除某些问题。

减少浪费时间的最佳方法是快速回答以下问题:";是DNS、网络还是应用程序" 为了帮助您更有效地回答这个问题并排除故障,请点击这里';这是对最常见的错误场景的快速解释,以及如何快速确定问题可能存在的位置,所有这些都基于一个奇怪的技巧:阅读和理解错误信息。

macos$ssh-foo。内特迈斯特。orgssh:无法解析主机名foo。内特迈斯特。org:nodename或servname提供,或不知道nornetbsd$ssh foo。内特迈斯特。orgssh:无法解析主机名foo。内特迈斯特。组织:没有与主机名关联的地址$

好极了。现在还不需要发出ping(8)、traceroute(8)和tcpdump(1)——这是一个简单的方法。它告诉你问题是什么:无法解决。也就是说,你甚至没有达到系统试图向远程端发送任何数据包的程度,因为它无法';不要翻译foo这个名字。内特迈斯特。组织成一个IP地址。(不同的工具,甚至同一工具在不同平台上的不同版本,可能会给出略有不同的错误消息,如上图所示。)

在这种情况下,你想知道为什么你可以';无法解析名称。首先,确保你不';这里没有输入错误:它';It’很容易意外地插入一个额外的字母或是一个域名。但是假设你确定你的名字是对的,你能查到什么?

$dig+短netmeister。组织nsns-181-a.gandi。网ns-143-b.甘地。网ns-179-c.甘地。净额美元[email protected]。网福。内特迈斯特。组织;;得到答案:->>;标题<<;-操作码:查询,状态:无错误,id:25060;;旗帜:qr-aa-rd;查询:1,答案:0,权限:1,附加:1;;警告:已请求递归,但不可用;;选择假节:;EDNS:版本:0,标志:;udp:1232$

NOERROR表示DNS服务器上没有错误';这意味着问题得到了正确的回答。好的,那么我们';Vee建立了那个foo。内特迈斯特。组织SimpleDoesn和#39;在DNS中不存在,所以你的旅程结束了。那';是的,那';s it:修复DNS条目或向任何拥有该域的人进行访问。

[email protected]。网福。内特迈斯特。组织[时间流逝];;连接超时;无法联系到任何服务器$

这是否意味着问题出在授权名称服务器上?不一定!它';可能是';只有你的系统能';不要与NS对话,但您的configuredresolver(例如,from/etc/resolv.conf)可以。例如,如果网络管理员阻止发送到除ConfiguredResolver之外的主机的DNStraffic,则可能会出现这种情况。

注意:在这种情况下,您也可以访问二级域名授权服务器(本例中为netmeister.org),但您的名称';您试图解析的域位于具有不同授权名称服务器的子域下:

[email protected]。网酒吧dns。内特迈斯特。组织;;得到答案:->>;标题<<;-操作码:查询,状态:无错误,id:39531;;旗帜:qr-rd;查询:1,答案:0,权限:2,附加:3;;警告:已请求递归,但不可用;;选择假节:;EDNS:版本:0,标志:;udp:1232$dig+短dns。内特迈斯特。组织nspanix。内特迈斯特。org$dig+noall+answer@panix。内特迈斯特。组织酒吧。dns。内特迈斯特。组织[时间流逝];;连接超时;无法联系到任何服务器$

在不询问您的解析程序(我们知道解析程序无法解析名称,因为这是我们在这里开始旅程的方式)且不进行出站端口53 UDPCALL的情况下,您如何验证名称是否存在?这里有几个选项:

DNS不仅仅是端口53 UDP,您可以通过TCP简单地询问权威:

您可以尝试将DNSover HTTPs用于其中一个公共DoH解析器,例如Google';s或Cloudflare';s的DNS服务器。DIG(1)通过+HTTPS标志支持DOH SimeCARCH 2021,但是如果您的挖掘(1)比它更大,您还可以直接使用JSONAPI:

$curl-s';https://dns.google/resolve?name=foo.netmeister.org&类型=a';|jq';。回答';空$curl-s-H';接受:应用程序/dns json''https://cloudflare-dns.com/dns-query?name=foo.netmeister.org' | jq';。答案';无效的

这并不意味着';不允许您询问授权服务器,但它允许您确认至少其他一些名称服务器可以解决您遇到的主机名问题。

如果你知道一个支持DNSover TLS的公共解析器,那么你可以试试。存在不同的命令行工具,例如kdig(1)或dog(1),例如dig(1)从9.18.0版起就通过+tls标志支持DoT,但如果你想真正做到赤裸裸,你甚至可以使用stunnel(1):

$cat>/tmp/dot<&书信电报;EOF[dns]client=yesaccept=127.0.0.1:5353connect=8.8.8.8:853CAfile=/etc/ssl/cert.pemfrifychain=yescheckIP=8.8.8.8EOF$stunnel/tmp/[email protected] foo。内特迈斯特。组织

一些权威的名称服务器甚至可能直接支持Dot,因此您可能不需要使用像Google';这里有一个DNS服务器,它会给你一个权威的答案,但即使你问8.8.8.8,你也可以再次确认你的解析器所做的与其他解析器所做的一致(或不同)。

进一步考虑这个概念,您可能希望跨多个不同的公共解析器比较结果。幸好我正好有工具给你!您可以创建一个简单的HTTP GETrequest:

$curl-s';https://www.netmeister.org/puddy/?name=foo.netmeister.org&格式=json';|jq';。结果';{";2001:4860:4860::8888";{";CNAME";{";状态";:";无错误";}"AAAA";:{";状态";:";无错误";}"评论";:"谷歌公共域名系统""A";:{";状态";:";无错误";},[...]

$puddy-1 foo。内特迈斯特。org a aaaa2001:470:20::2(飓风电力)a:[未发现记录]AAAA:[未发现记录]2001:4860:4860::8888(谷歌)a:[未发现记录]AAAA:[未发现记录]2606:4700:4700:1001(Cloudflare)a:[未发现记录]AAAA:[未发现记录]2620:0:ccc::2(OpenDNS)a:[未发现记录]AAAA:[未发现记录]2620:fe::fe(Quad9)a:[未找到记录]AAAA:[未找到记录]$

...尽管这再次要求您能够在端口53上与不同的解析器对话。同时,这也为你提供了另一种检查其他人是否看到与你在本地系统上看到的结果相同的方法,这可能会有所帮助。

令人沮丧的一个常见原因是DNS查找与其他工具看到的行为之间存在明显差异。这通常可以追溯到对/etc/hosts所做的本地更改,并且会显示如下:

$host foo。内特迈斯特。好极了。内特迈斯特。找不到组织:3(NXDOMAIN)$ssh foo。内特迈斯特。orgsh:连接到主机foo。内特迈斯特。org端口22:连接拒绝者,更令人沮丧的是:$host bar。dns。内特迈斯特。奥格巴。dns。内特迈斯特。org的地址是198.51.100.1bar。dns。内特迈斯特。org的IPv6地址为2001:db8::c2de:2d22:5ca1:2727$ping6 bar。dns。内特迈斯特。Orgging6(56=40+8+8字节)2001:470:30:84:e276:63ff:fe72:3900-->;2001:db8::9a6f:ba98:b763:574eping6:sendmsg:网络无法访问6:Writed 2001:db8::9a6f:ba98:b763:574e 16个字符,ret=-1ping6:sendmsg:网络无法访问6:Writed 2001:db8::9a6f:ba98:b763:574e 16个字符,ret=-1^C---2001:db8::9a6f:ba98:b763:574e ping6统计信息---传输2个数据包,接收0个数据包,100.0%数据包丢失$grep bar。dns。内特迈斯特。org/etc/hosts 2001:db8::9a6f:ba98:b763:574e bar。dns。内特迈斯特。组织$

也就是说,在执行显式DNS查找(2001:db8::c2de:2d22:5ca1:2727)时观察一个地址(或没有地址),在运行使用常规gethostbyname(3)库函数的命令时观察另一个地址(2001:db8::9a6f:ba98:b763:574e),在大多数情况下,这些函数将首先尝试/etc/hosts。

如果你看到这一点,修复/etc/hosts,向做出更改的人大喊(可能是你自己),然后使该文件不可变(例如sudo chflagschg/etc/hosts或sudo chattr+i/etc/hosts)。

如果/etc/resolv中没有配置解析器,您可能会看到这一点。例如,conf。这又不同于(取决于操作系统和SSHversion):

...您可能会看到,如果没有配置的名称服务器是可访问的。这与叶塔干不同:

...如果您能够访问已配置的名称服务器,但该名称服务器不想与您交谈,例如,它';s配置为接受DNS查询,但对谁可以查询该区域有限制,因此返回状态:拒绝您的DNS查询。

此错误消息不言自明:连接被拒绝意味着您可以与主机对话,但端口22上没有任何内容。也就是说,在主机将名称解析为IP地址并发送TCP SYN数据包后,远程端用aTCP RST进行响应:

20:29:46.690536 IP 172.16.1.15.54702>;福。内特迈斯特。组织。ssh:Flags[S],seq 1750579353,win 65535,options[mss 1460,nop,wscale 6,nop,nop,TS val 674037520 ecr 0,sackOK,eol],长度020:29:46.701705 IP foo。内特迈斯特。组织。ssh>;172.16.1.15.54702:旗帜[R.],序号0,确认1750579354,胜利0,长度0

如果你';如果您确定端口和主机名正确,那么问题就出在远程端。但请注意,拒绝连接与。。。

虽然拒绝连接清楚地表明您可以到达远程端,但操作时间也同样清楚地表明您无法通过给定端口和协议与远程系统通信。tcpdump(1)将显示您的系统发送重复但未应答的数据包:

20:57:10.360287 IP 172.16.1.15.55111>;福。内特迈斯特。组织。ssh:Flags[S],seq 29973429620:57:11.361373 IP 172.16.1.15.55111>;福。内特迈斯特。组织。ssh:Flags[S],seq 29973429620:57:12.361702 IP 172.16.1.15.55111>;福。内特迈斯特。组织。ssh:Flags[S],seq 29973429620:57:13.362352 IP 172.16.1.15.55111>;福。内特迈斯特。组织。ssh:Flags[S],seq 2997342620:57:14.363566 IP 172.16.1.15.55111>;福。内特迈斯特。组织。ssh:Flags[S],seq 299734296。。。

再一次,只要你';如果确保端口和主机名正确,问题出在远程端。或者更确切地说,它是';It’它不在你这边——在你的系统和远程端之间的其他东西可能正在丢弃数据包。

最后,你可以带上你信任的朋友ping(8)和traceroute(8)。主持人有问题吗?ping(8)可能会告诉您,但请记住,ICMP可能会被阻止或删除,ping主机失败并不一定意味着它';它离线了。

traceroute(8)可能能够帮助您识别沿途流量被丢弃的位置,但在这里,也要注意可能被丢弃的问题、实际正在使用的UDP端口,等等。您可以通过尝试,例如traceroute-P tcp-P<;端口>;。

但是不能与远程主机通话也有不同的原因,例如。。。

主机名可以解析,但我们可以';不要跟IP地址说话:我们的系统没有';I don’我不知道如何把包裹送到远端。当所讨论的主机名解析为IPv6地址,但您的系统没有';我们没有IPv6连接。另一个原因可能只是一个错误的或丢失的路线,但不管怎样,这都是客户端的问题。在本例中,您可以解析主机,甚至可以在端口22上使用TCP与主机对话,但远程端决定关闭连接。这可能是因为在该主机的端口22上监听的任何内容都不会';我不会说宋承宪;通常情况下,如果存在某种代理或负载平衡,或者您只是使用了错误的端口,就会发生这种情况。

上面的例子是使用SSH给出的;其中许多协议或多或少地将1:1转换为其他基于TCP的协议,例如HTTP。当然,还有许多其他特定于应用程序的故障模式,不同的应用程序将错误消息传递给用户的程度不同。

但在调试应用程序之前,我们可以将不同的网络错误及其含义总结到这个流程图中(单击打开完整版本):

...至";是DNS、网络还是应用". 了解这其中的哪一个通常是解决更大问题的第一步。