【Linux】网络编程的调试工具以及连接失败的具体排查方法

目录

1.确认本地网络是否正常

1.1ping本地环回(127.0.0.1)

1.2ping内网ip

1.3查路由表

1.4查网卡

1.5ping网关ip

1.6ping公网IP

1.7ping域名

1.8汇总表

2.云安全组(虚拟防火墙)

2.1云安全组到底在哪里

2.2数据包完整路径

2.3观察云安全组

3.确认目标是否可达

3.1ping目标IP

[3.2traceroute 目标IP](#3.2traceroute 目标IP)

3.2.1traceroute/tracert底层

3.2.2测试结果

4.确认端口是否开放&服务是否在监听

4.1确认服务是否在监听

4.2telnet介绍

4.3telnet测试结果

5.中间是否有防火墙/云安全组拦截

6.抓包定位

7.定位问题,解决问题


不论客户端和服务器是相同的系统还是不同的系统,它们的TCP/IP网络协议栈是相同的,所以排查思路也大体一致,只不过不同的系统使用的工具可能有所区别,具体而言:

1.客户端本机网络是否正常。

2.客户端到服务器的网络是否可答。

3.服务器端口是否开放、服务是否在监听。

4.中间是否有防火墙,安全组拦截。

下面我将基于Linux系统配合相关调试工具讲解具体排查操作。

1.确认本地网络是否正常

1.1ping本地环回(127.0.0.1)

ping本地环回可以验证本机的TCP/IP协议栈是否正常工作,排除系统本身网络功能坏了这种底层问题。

127.0.0.1是本地环回地址,对应网卡lo(虚拟网卡)。数据包不会经过物理网卡,不查路由表,也不会出本机,而是在内核协议栈里直接绕回来。

ping本地环回可以验证一下项:

IP协议栈是否正常

ICMP协议是否正常

环回网卡lo是否up

本机网络的基础配置是否正常

一般来讲,现代Linux系统经过几十年的发展,内核代码十分稳定极少出现问题,如果本地环回ping不通,可以查网卡来进一步排查问题所在。

1.2ping内网ip

如果本地环回ping通了,说明本机的内核协议栈是没问题的,但不确定本机的物理网卡、IP配置、路由表是否正常,那么ping内网ip主要是来检测这三项的。

如果ping内网ip不通,需要具体查路由表和网卡是否正常了。

1.3查路由表

ip route可以查看本机的路由表。

主要看手动添加的有没有问题(proto static),proto dhcp、proto kernel分别是由dhcp协议自动生成和内核自动生成。

第一条:本机网卡eth0配置的内网ip是10.0.16.8,默认网关是10.0.16.1,如果目标IP不是一下条目中的任何一条,则把报文转发给网关,优先级100.

第二条:如果目标IP在10.0.16.0/22这个网段(本机所在的局域网),则直接由网卡转发,范围是整个链路,优先级100.

第三条:如果目标IP是10.0.16.1(网关)则直接由网卡转发,范围是整个链路,优先级100.

第四、五条:如果目标IP是183.60.82.98/183.60.83.19,则直接由网卡发送给网关,优先级100.

如果第二条缺失或者配错,那么ping内网ip可能ping不通。

1.4查网卡

命令ip addr可以查看本机的网卡信息。

lo是本机的第一张网卡,loopback代表本地环回(虚拟网卡),UP代表网卡已启用,lower_up代表物理链路已连接,ipv4地址为127.0.0.1/8。

eth0是本机的第二张网卡,网卡已启用,ipv4地址为10.0.16.8/22。

查网卡时主要看这些字段:

1.state和LOWER_UP,看网卡开没开,线通没通。

2.inet,看有没有ip,ip对不对。

3.mtu(最大传输单元),看有没有mtu不匹配的坑。

1.5ping网关ip

如果ping本地内网ip通了,就可以把排查重点放在网线,网关上。

ping网关可以验证本机的网络报文是否可以递答网关,可以检测以下功能:

网线/虚拟网卡的问题:网卡虽然显示UP,但底层链路可能断了。

VLAN/子网配置错误:比如交换机配置错误,导致本机和网关无法正常通信或者本机子网掩码配置错误导致网关和本机不在同一个网段。

网关设备故障:概率极低。

ARP协议:ARP协议能否获取到网关的MAC地址。

当然本机在ping网关ip时是不通的,因为我的Linux机器是腾讯云服务器,云平台网关为了不必要的安全暴露和资源消耗通常是禁ping的(不响应ICMP请求)。

当然为了验证网关是否真的禁ping,可以ping以下可以确认能ping通的公网IP地址,如果能ping通,说明网关确实禁ping。

当前ping通了一个公网IP,说明本机的报文可以送达网关并且网关可以将报文转发出去,间接证明网关禁ping。

1.6ping公网IP

当然ping公网IP同时可以验证:

默认路由,NAT,公网出口是否正常。

如果不通则以下选项可能有问题:

1.本机路由表的默认路由有问题。

2.NAT没配。

3.云安全组拦截了出站流量或者运营商网络故障。

1.7ping域名

ping域名,比如ping 百度的域名。

这一步可以验证DNS协议是否正常(DNS协议可以将域名解析成IP地址)。

如果通了,说明本机网络完全正常,不通说明DNS配置错误。

1.8汇总表

2.云安全组(虚拟防火墙)

在1.6中提到如果ping 公网IP不通可能是被云安全组拦截,那么云安全组是什么呢?

云安全组是云厂商提供的一种虚拟防火墙,用来控制云服务器的入站和出站流量。它工作在实例级别------每台云服务器都绑定一个或多个安全组,规则在云平台控制台统一配置。

它不在服务器上也不在网关上,它由云平台的底层虚拟化层实现,横亘在你的服务器网卡和虚拟网络之间。

打个比方:云安全组是云平台在虚拟化层给你装的"隐形防盗门",你在屋里看不到它,但它决定了谁能进谁能出。

2.1云安全组到底在哪里

云安全组不在服务器上,也不在网关上,所以通过云服务器无法配置云安全组(防止服务器被攻击,攻击者通过服务器关闭云安全组)。

但需要明确的是云安全组一定是十分靠近云服务器的,在出站时,数据包出了网卡就会被云安全组检测,入站时,数据包也是先被云安全组检测,随后才进网卡。

所以云安全组是绑定在网卡虚拟端口上的一组过滤规则,在数据包进入虚拟网络时生效。

2.2数据包完整路径

出站方向:

网卡->云安全组(出站规则)->虚拟交换机->虚拟路由器(网关)->公网网关/NAT->互联网

入站方向:

互联网->公网网关/NAT->虚拟路由器(网关)->虚拟交换机->云安全组(入站规则)->网卡

2.3观察云安全组

这是我的腾讯云安全组的入站规则,可以看到我的服务器是没有禁ping的,可以通过22号端口上的服务远程连接我这台云服务器。并且手动放开了8888号端口,这是我在日常学习时,部署web服务,服务端通常监听8888号端口,用于功能测试。

另外腾讯云安全组的出站规则默认允许所有流量,也就是允许自己使用所有协议访问所有IP的所有端口,因为是出站流量,所以风险较低。

3.确认目标是否可达

这一步的核心目的是:在确认本机网络正常之后,判断问题是不是出在本机到目标主机这段路径上。

在步骤1中我们验证了我的云服务器的网络是正常的,而我目前的windows电脑可以正常上网,显而易见,网络也是正常的。现在,我在我的云服务器上部署了一个简单的web服务,但通过我的windows主机访问不了目标网站,下面我们来一步一步排查问题所在。

3.1ping目标IP

这一步通了说明目标网络层可达,可以进一步验证端口。若不通,则:

1.本机的公网网关到目标主机这一段的网络不通。

2.目标主机或中间防火墙禁ping。

注意ping不通不代表目标不可达,因为很多服务器禁ping,所以ping不通时,要继续往下测端口。

在windows电脑上,我ping通了目标服务器的公网IP,说明当前机器的数据包可以到达目标服务器的网络层。

由此我们可以确认问题大概率出在端口,防火墙上。

3.2traceroute 目标IP

这一步可以验证:数据包经过哪些路由器,在哪一跳断了。

如果前几条就断了->本地网络/网关的问题。

如果中间某跳断了->中间网络的问题。

如果到了目标网络但最后不通->目标主机/防火墙问题。

3.2.1traceroute/tracert底层

traceroute是Linux下的网络调试工具,tracert是windows下的网络调试工具,但它们的功能是相同的,用于追踪数据包从本机到目标主机经过的完整路径(每一条路由器),用于定位网络在哪一跳断了。

底层原理:

利用IP报头的TTL(生存时间)字段,TTL从1开始递增,每经过一个路由器减1,TTL减到0时,路由器丢弃包并回复ICMP超时消息,发送方记录每一跳的IP往返时间。

一句话概括:通过逐步增加TTL,让路径上的每一跳路由器依次"自报家门"。

和ping的区别:

和ping最直接的区别是TTL不同,ping的TTL是固定的,而traceroute/tracert的TTL是从1递增的。

因为TTL的差异决定了它们的功能不同,ping测试目标是否可达,traceroute/tracert追踪完整路径。

另外ping采用ICMP协议,没有传输层的参与。windows下的tracert采用ICMP协议,Linux下的traceroute默认采用UDP(可以指定使用ICMP或TCP协议,需要带-I或-T选项,原理相同)。

traceroute有ICMP/UDP/TCP三种模式,由于ICMP数据包常常被拦截,所以TCP模式可以更准确的探测数据包能否送达目标机器。这个话题比较大,后续我会出一篇博客来专门讲这个话题:traceroute底层

3.2.2测试结果

这是在windows系统上tracert 我的云服务器IP,当我将云安全组设置拦截ICMP协议的报文后,可以看到最后一跳是第10跳(北京的腾讯云接入电信网络的边界路由器),但是最终没有打通我的云服务器。虽然没有打通,但是不代表网络报文不可达,我们的网络测试的目的就是看网络报文是否可达的,所以后续还需要进一步测试端口。

此外,可以看到第二跳的延迟很长,有两次超时和一次接近两秒的延迟,这说明该路由器所在的网络比较拥塞,而ICMP超时回复的优先级很低,所以会出现这种延迟飙高的情况。

而这是我放开云安全组对ICMP协议的拦截,测试结果如下,最终可以打通,网络报文可以递答。中间有几跳路由器显示超时,不代表网络报文在这里断了,只是它们"懒得回复ICMP超时"。

为了看到traceroute的测试结果,我在云服务器上追踪了谷歌的公网IP,结果显示追踪成功,一共13跳,中间的第10-11跳延迟较高,是因为跨境了,数据包会通过海底光缆,物理距离比较远,但在可接受的范围内。

中间出现了*不必慌张,链路没有断,只是路由器不想回复你。

4.确认端口是否开放&服务是否在监听

4.1确认服务是否在监听

通过netstat命令可以看到,我的web服务为aod,目前是LISTEN状态,并且监听0.0.0.0:8888。服务成功监听正确IP和正确端口。

并且云安全组放开了TCP/UDP协议对应的8888号端口,确保TCP三次握手的报文不会被云安全组拦截。

4.2telnet介绍

telnet实际上是一个应用层协议,它分为客户端和服务端,服务端监听23号端口。

通常客户端与服务端建立TCP连接,用户通过给客户端输入指令,然后服务端根据客户端输入的指令来控制运行服务端的机器执行指令从而达到远程控制的目的。

但远程操控的功能已经被SSH取代,因为telnet不加密,SSH加密。现今telnet服务端几乎很少用,大多数用telnet客户端和服务器的其他服务端建立TCP连接,从而达到测试目标服务是否监听对应端口的目的。

telnet客户端建立连接时的输出结果有三种:

Connected:端口开放,服务正常监听。

Connection refused:数据包到达了服务器,但服务器回复RST,说明服务没起或者监听了其他端口。

超时:数据包没到达服务器,说明数据包被防火墙/安全组拦截或者网络链路不通。

4.3telnet测试结果

这是请求8888号端口的测试结果,但这个结果到底有没有连通并不明显,其实这个结果是已经连通了,但是服务器又马上关闭了连接。

为了有更明显的对比,我们再继续测一下其他端口。

第一张图测试80号端口,结果是连接失败,虽然我的云安全组放行了80端口,但是服务器内部防火墙没有放行80端口,所以报文被防火墙拦截了。

第二张图测试22号端口并且已经成功连上,22号端口是SSH的服务器,用于远程操控的。

5.中间是否有防火墙/云安全组拦截

既然telnet测试结果不明显,我们再来看一下服务器内部防火墙的配置,看看到底有没有放行8888端口。

当我们查看防火墙的配置后,发现,服务器内部防火墙放行了tcp8888号端口(如果没方行,需要手动放行)。那么排查到这里,我们来回顾一下:

  • 客户端的报文可以递达服务端。
  • 服务器云安全组放行TCP/8888号端口。
  • 服务器内部防火墙放行TCP/8888号端口。
  • 目标服务已运行,并监听任意的IP来源和8888号端口。

排查到这里,其实我已经想不到有哪个环节可以拦截我的TCP报文了,理论上来讲,网络应该没有任何问题,服务器应该可以收到报文。

所以为了进一步确定8888号端口到底有没有收到报文,可以用tcpdump来进行抓包,如果确实抓到了,那就说明windows客户端的请求报文没有被拦截,确实被服务器收到了,如果没有抓到,就说明请求报文被网络链路中间某个环节拦截了。

6.抓包定位

  • 源:182.134.237.125:9313(这是我的 Windows 客户端公网 IP 和临时端口)。
  • 目的:10.0.16.8:8888(我的服务器)。
  • Flags S:这是 TCP SYN 包,表示客户端请求建立连接。
  • 含义:我的 Windows 客户端请求成功到达了服务器! 这是排查中最关键的一步。

结论:网络路径是通的,云安全组、VPC、防火墙、路由都没问题。

后面两行是剩下的两次握手,第二次是服务器发给客户端的SYN+ACK,第三次是客户端发给服务器的ACK。

最后两行代表:5秒后,服务器主动断开连接,向客户端发送FIN,客户端回复ACK。

7.定位问题,解决问题

通过抓包分析后,可以很明显得看出服务器收到了请求报文,并且可以成功建立连接。但是windows客户端浏览器依然加载不出对应的网页,那么问题很明显------应用层服务有问题!

其实在写这篇博客前,我也不知道问题在哪里,想着边找问题边写博客,顺便把网络问题排查的思路捋一遍,但排查到最后才发现其实网络没问题,是服务的问题,哈哈,有点尴尬~ 不过这一套排查思路还是十分有学习价值的。

因为这个web服务是一两年前写的一个简单的服务,代码总量在1.5k-2k之间,不算复杂,整体的架构我已经忘得差不多了,不过根据初步的观察,问题大概是:客户端发起网络请求,服务端可以收到,也可以建立连接,但是服务器收到客户端的请求后,没有把网页首页应答回去,或者首页缺失,所以浏览器上加载不出来网页,最终的现象就像客户端连不上服务器一样。

意识到是个小问题,且具体的功能都在,我也懒得去改代码了,于是直接让AI工具帮我找一下服务的具体问题,顺便帮我改一下就可以了~

最终解决问题,浏览器成功显示出首页。

希望我的排查经历对您的学习和工作有所帮助~

相关推荐
雪落漂泊1 小时前
Linux基础开发工具(一)软件包管理器与Vim编辑器篇
linux·运维·服务器
承渊政道1 小时前
CentOS 7单机部署Elasticsearch 7.17.29:从启动报错、CRUD验证到固定公网地址的完整过程
linux·elasticsearch·centos·内网穿透·cpolar·单机部署
ESDWAN1 小时前
海外股票网络环境优化与交易场景应用:从行情获取到交易系统稳定性设计
开发语言·网络·php
进击的荆棘1 小时前
Linux系统——库的原理与制作之ELF文件的形成与加载的过程(上)
linux·elf·动静态库
pt10431 小时前
Cisco设备网络安全系列-2:管理访问、控制平面与基础设施ACL防护
网络·安全
额额额对了1 小时前
Linux 内核定时器与 DHT11
linux·运维·服务器
天行健,君子而铎11 小时前
数据分类分级的范式转换:从规则匹配到场景化高准确率一键部署
网络·数据库·安全
别动我齐刘海11 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
玖石书13 小时前
Ubuntu 24.04 UFW 全命令攻略:从入门到端口开放实战
linux·运维·ubuntu