首页 > 其他分享 >《网络排查案例课》

《网络排查案例课》

时间:2022-08-15 11:40:24浏览次数:41  
标签:案例 报文 端口 网络 tcp 排查 TCP 连接

《网络排查案例课》01 | 网络模型和工具:网络为什么要分层?

七层模型;四层 / 五层模型;五元组;四元组
===============================================
OSI 的七层模型,和 TCP/IP 的四层 / 五层模型
五元组:传输协议类型、源 IP、源端口、目的 IP、目的端口
四元组:源 IP、源端口、目的 IP、目的端口
七层模型;四层 / 五层模型;五元组;四元组

《网络排查案例课》02 | 抓包分析技术初探:你会用tcpdump和Wireshark吗?

《网络排查案例课》03 | 握手:TCP连接都是用TCP协议沟通的吗?

案例1:TCP 连接都是用 TCP 协议沟通的吗?(不是的,比如server端未监听某端口,那么会使用icmp type 3 返回端口不可达信息)
-----------------------------------------------------------------------
案例1:TCP 连接都是用 TCP 协议沟通的吗?(不是的,比如server端未监听某端口,那么会使用icmp type 3 返回端口不可达信息)
比如server端未监听某端口,那么会使用icmp type 3 返回端口不可达信息

server端要拒绝连接的话,会以下两种情形:
    1.静默丢包;
        客户端将会不明真相:a.静默丢包;b.去向丢包;c.回向丢包
    2.明确拒绝


$ sudo sysctl net.ipv4.tcp_syn_retries
net.ipv4.tcp_syn_retries = 6


Iptables -I INPUT -p tcp --dport 80 -j REJECT     #实验配置的这条规则
-A INPUT -p tcp -m tcp --dport 80 -j REJECT --reject-with icmp-port-unreachable     #自动补上了–reject-with icmp-port-unreachable
-A INPUT -p tcp -m tcp --dport 80 -j REJECT -–reject-with tcp-reset     #可以手动修改为tcp rst
案例1:TCP 连接都是用 TCP 协议沟通的吗?(不是的,比如server端未监听某端口,那么会使用icmp type 3 返回端口不可达信息)
案例2:Windows 服务器加域报 RPC service unavailable?;案例3:发送的数据还能超过接收窗口?
================================================================================
案例2:Windows 服务器加域报 RPC service unavailable?

使用netstat -antp 在客户端进行查看,发现客户端卡在SYN_SENT 状态,最终确认了使因为防火墙未放行端口,过滤了报文。

-----------------------------------------------------------------------
案例3:发送的数据还能超过接收窗口?

问题:wireshark中,Redis 服务告诉客户端它的接收窗口是 190 字节,但是客户端居然会发送 308 字节,大大超出了接收窗口
根因:抓包没有抓到3次握手的协商报文,wireshark无法对报文的窗口进行正确的解析

    TCP Options 的 Window Scale 字段只出现在TCP3次握手的协商阶段,它表示原始 Window 值的左移位数,最高可以左移 14 位。
    根因在于这次抓包没有抓到tcp协商过程,所以wireshark认为协商的窗口大写为65535字节;而实际的窗口大小应该是服务端通告的窗口190字节* Window Scale数值

    在分析抓包文件时,要注意是否连接的握手包被抓取到,没有握手包,这个 Window 值一般就不准。
案例2:Windows 服务器加域报 RPC service unavailable?;案例3:发送的数据还能超过接收窗口?
UDP 也有握手?(nc探测UDP端口,无响应则认为succeeded,该结果是不可信的!!!);服务器端的最大连接数
====================================================================================================================================
UDP 也有握手?
有些同学会有这个误解,可能是跟 nc 这个命令有关。
$ nc -v -w 2 47.94.129.219 22
Connection to 47.94.129.219 22 port [tcp/ssh] succeeded!
victor@victorebpf:~$ nc -v -w 2 47.94.129.219 -u 22
Connection to 47.94.129.219 22 port [udp/*] succeeded!      #UDP测试,显示successded
抓包发现UDP只有发包,那么nc怎么回显示succeeded呢?
    可能只是因为对端没有回复 ICMP port unreachable

当你下次用 nc 探测 UDP 端口,不通的结果是可信的,而能通(succeeded)的结果并不准确,只能作为参考!!!!!!

------------------------------------------------------------------------------------------------------------------------------------
服务器端最多65535个连接,确实是个误区,其实这个跟很多都有关系的,比如服务器端的CPU、内存、fd数以及连接的情况,fd数是前提。
一个连接会牵扯到服务端的接收缓冲区(net.ipv4.tcp_rmem)以及发送缓冲区(net.ipv4.tcp_wmem),一个空的TCP连接会消耗3.3KB左右的内存,如果发数据的话,一个连接占用的内存会更大。
所以理论上4GB的机器理论上支持的空TCP连接可以达到100W个。
此外数据经过内核协议栈的处理需要CPU,所以CPU的好坏也会影响连接数。
UDP 也有握手?(nc探测UDP端口,无响应则认为succeeded,该结果是不可信的!!!);服务器端的最大连接数

《网络排查案例课》04 | 挥手:Nginx日志报connection reset by peer是怎么回事?

突破应用层日志和网络报文的鸿沟:时间吻合;RST 行为吻合;URL 路径吻合。
--------------------------------------------------------------
在应用层和网络层之间搭建桥梁
    做网络排查的第一个要点:把应用层的信息,“翻译”成传输层和网络层的信息。

应用现象跟网络现象之间的鸿沟:你可能看得懂应用层的日志,但是不知道网络上具体发生了什么。
工具提示跟协议理解之间的鸿沟:你看得懂 Wireshark、tcpdump 这类工具的输出信息的含义,但就是无法真正地把它们跟你对协议的理解对应起来。
突破应用层日志和网络报文的鸿沟:时间吻合;RST 行为吻合;URL 路径吻合。
案例 1:connection reset by peer?;附赠nginx日志解读
===================================================================================================================
案例背景:
    客户反馈,他们的 Nginx 服务器上遇到了很多 connection reset by peer 的报错。
    客户的应用是一个普通的 Web 服务,架设在 Nginx 上,而他们的另外一组机器是作为客户端,去调用这个 Nginx 上面的 Web 服务。
    客户端---nginx---服务端

根因:client的POST,nginx已经回复HTTP 200;但client还是发送了RST 重置连接;问题回到了client侧,进一步排查的话,需要查看client侧的源码了

排查及分析思路:
    1.在客户端上进行抓包;
    2.使用wireshark进行RST报文的过滤,发现了大量的RST报文 "ip.addr eq 10.255.252.31 and tcp.flags.reset eq 1"
        任意选取了一个RST报文,发现该RST报文是次握手的第3个报文,所以实际上该tcp连接还未成功建立,那么应用层就还不知道该连接的存在,不会有该连接的日志了
        结论:该RST报文和nginx日志"connection reset by peer"无关
    3.继续更新wireshark过滤规则,锁定目标RST报文 "frame.time >="dec 01, 2015 15:49:48" and frame.time <="dec 01, 2015 15:49:49" and ip.addr eq 10.255.252.31 and tcp.flags.reset eq 1 and !(tcp.seq eq 1 or tcp.ack eq 1)"
        应用层日志和网络报文是存在鸿沟的,没有直接的关系,但是可以通过以下的方式进行判断
            锁定 TCP 流和某条日志的对应关系,主要三点原因:时间吻合;RST 行为吻合;URL 路径吻合。
    4.追踪该TCP流,发现client的POST,nginx已经回复HTTP 200;但client还是发送了RST 重置连接;问题回到了client侧,进一步排查的话,需要查看client侧的源码了

--------------------------------------------------------------------------------------
nginx日志
2015/12/01 15:49:48 [info] 20521#0: *55077498 recv() failed (104: Connection reset by peer) while sending to client, client: 10.255.252.31, server: manager.example.com, request: "POST /WebPageAlipay/weixin/notify_url.htm HTTP/1.1", upstream: "http:/10.4.36.207:8080/WebPageAlipay/weixin/notify_url.htm", host: "manager.example.com"
2015/12/01 15:49:54 [info] 20523#0: *55077722 recv() failed (104: Connection reset by peer) while sending to client, client: 10.255.252.31, server: manager.example.com, request: "POST /WebPageAlipay/app/notify_url.htm HTTP/1.1", upstream: "http:/10.4.36.207:8080/WebPageAlipay/app/notify_url.htm", host: "manager.example.com"
2015/12/01 15:49:54 [info] 20523#0: *55077710 recv() failed (104: Connection reset by peer) while sending to client, client: 10.255.252.31, server: manager.example.com, request: "POST /WebPageAlipay/app/notify_url.htm HTTP/1.1", upstream: "http:/10.4.36.207:8080/WebPageAlipay/app/notify_url.htm", host: "manager.example.com"
2015/12/01 15:49:58 [info] 20522#0: *55077946 recv() failed (104: Connection reset by peer) while sending to client, client: 10.255.252.31, server: manager.example.com, request: "POST /WebPageAlipay/app/notify_url.htm HTTP/1.1", upstream: "http:/10.4.36.207:8080/WebPageAlipay/app/notify_url.htm", host: "manager.example.com"
2015/12/01 15:49:58 [info] 20522#0: *55077965 recv() failed (104: Connection reset by peer) while sending to client, client: 10.255.252.31, server: manager.example.com, request: "POST /WebPageAlipay/app/notify_url.htm HTTP/1.1", upstream: "http:/10.4.36.207:8080/WebPageAlipay/app/notify_url.htm", host: "manager.example.com"

recv() failed:这里的 recv() 是一个系统调用,也就是 Linux 网络编程接口。它的作用呢,看字面就很容易理解,就是用来接收数据的。
104:这个数字也是跟系统调用有关的,它就是 recv() 调用出现异常时的一个状态码,这是操作系统给出的。在 Linux 系统里,104 对应的是 ECONNRESET,也正是一个 TCP 连接被 RST 报文异常关闭的情况。
upstream:在 Nginx 等反向代理软件的术语里,upstream 是指后端的服务器。
    客户端把请求发到 Nginx,Nginx 会把请求转发到 upstream,等后者回复 HTTP 响应后,Nginx 把这个响应回复给客户端。


在网络运维的视角上,我们更关注网络报文的流向,因为 HTTP 报文是从外部进来的,那么我们认为其上游(upstream)是客户端;
但是在应用的视角上,更关注的是数据的流向,一般来说 HTTP 数据是从内部往外发送的,那么在这种视角下,数据的上游(upstream)就是后端服务器了。
    Nginx、Envoy 都属于应用网关,所以在它们的术语里,upstream 指的是后端环节。这里没有对错之分,你只要知道并且遵照这个约定就好了。

--------------------------------------------------------------------------------------
2.使用wireshark进行RST报文的过滤,发现了大量的RST报文 "ip.addr eq 10.255.252.31 and tcp.flags.reset eq 1"
    任意选取了一个RST报文,发现该RST报文是次握手的第3个报文,所以实际上该tcp连接还未成功建立,那么应用层就还不知道该连接的存在,不会有该连接的日志了
    结论:该RST报文和nginx日志"connection reset by peer"无关


    客户端抓包
    ip.addr eq my_ip:过滤出源IP或者目的IP为my_ip的报文
    ip.src eq my_ip:过滤出源IP为my_ip的报文
    ip.dst eq my_ip:过滤出目的IP为my_ip的报文

    tcp.flags.reset eq 1

    ip.addr eq 10.255.252.31 and tcp.flags.reset eq 1
        在 Wirershark 窗口的右下角,就有符合过滤条件的RST报文个数,这里有 9122 个,占所有报文的 4%


    我们就要先了解应用程序是怎么跟内核的 TCP 协议栈交互的。一般来说,客户端发起连接,依次调用的是这几个系统调用:
        socket()
        connect()
    而服务端监听端口并提供服务,那么要依次调用的就是以下几个系统调用:
        socket()
        bind()
        listen()
        accept()


    抓包现象:client在3次握手的第3个包,直接回复了TCP RST,ACK

        服务端的用户空间程序要使用 TCP 连接,首先要获得上面最后一个接口,也就是 accept() 调用的返回。
        而 accept() 调用能成功返回的前提呢,是正常完成三次握手。
        这次失败的握手,也不会转化为一次有效的连接了,所以 Nginx 都不知道还存在过这么一次失败的握手。

        当然,在客户端日志里,是可以记录到这次握手失败的。这是因为,客户端是 TCP 连接的发起方,它调用 connect(),而 connect() 失败的话,其 ECONNRESET 返回码,还是可以通知给应用程序的。

        所以 3次握手的 RST,不是我们要找的那种“在连接建立后发生的 RST”。

--------------------------------------------------------------------------
3.更新wireshark过滤规则,锁定目标RST报文 "frame.time >="dec 01, 2015 15:49:48" and frame.time <="dec 01, 2015 15:49:49" and ip.addr eq 10.255.252.31 and tcp.flags.reset eq 1 and !(tcp.seq eq 1 or tcp.ack eq 1)"


frame.time >="dec 01, 2015 15:49:48" and frame.time <="dec 01, 2015 15:49:49" and ip.addr eq 10.255.252.31 and tcp.flags.reset eq 1 and !(tcp.seq eq 1 or tcp.ack eq 1)


应用层日志和网络报文是存在鸿沟的,没有直接的关系,但是可以通过以下的方式进行判断
    锁定 TCP 流和某条日志的对应关系,主要三点原因:时间吻合;RST 行为吻合;URL 路径吻合。

--------------------------------------------------------------------------
4.追踪该TCP流,发现client的POST,nginx已经回复HTTP 200;但client还是发送了RST 重置连接;问题回到了client侧,进一步排查的话,需要查看client侧的源码了

然后根据该RST报文找到了TCP会话,发现实际上nginx实际已经响应client的post请求,并回复了http 200;
    奇怪的是client却发送RST报文结束该连接



本案例通过规则最终锁定了与nginx错误日志匹配的数据包,追踪该TCP流,发现client的POST,nginx已经回复HTTP 200;但client还是发送了RST 重置连接;问题回到了client侧,进一步排查的话,需要查看client侧的源码了
避免这种 reset,需要客户端代码进行修复
    客户端用 RST 来断开连接并不妥当,需要从代码上找原因。比如客户端在 Receive Buffer 里还有数据未被读取的情况下,就调用了 close()。
        网络不稳定,或者防火墙来几个 RST,也都有可能导致类似的 connection reset by peer 的问题。
案例 1:connection reset by peer?;附赠nginx日志解读
案例 2:一个 FIN 就完成了 TCP 挥手?"ack搭车"
==========================================================================================
TCP 的挥手是任意一端都可以主动发起的。也就是说,挥手的发起权并不固定给客户端或者服务端。

仅仅只是展示了一个案例,看起来只有一个FIN
实际上另一个FIN是在POST请求中一起发出的。。。

同时因为ack搭车的关系,这个挥手只有3个报文

实际上 TCP 挥手可能不是表面上的四次报文,因为并包也就是 Piggybacking 的存在,它可能看起来是三次。
案例 2:一个 FIN 就完成了 TCP 挥手?"ack搭车"

 

 

 

 

 

 

 

 

 

 

 

 

 

1111

标签:案例,报文,端口,网络,tcp,排查,TCP,连接
From: https://www.cnblogs.com/AllenWoo/p/16587647.html

相关文章

  • HTTP_路径、HTTP_案例路径_绝地路径
    HTTP_路径路径的写法:路径的分类:相对路径:通过相对路径不可以确定唯一资源如:./index.thml不以/开头,以,开头路径规则:......
  • 验证码案例的代码实现和细节处理
    代码实现:login.jsp:<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>login</title><script>window.onload......
  • Respon_案例_重定向、Respon_案例1_重定向_特点
    Respon_案例_重定向案例:完成重定向服务器输出字符数据到浏览器服务器输出字节数据到浏览器验证码图解:   案例:@WebServlet(va......
  • Cookie特点&作用和Cookie案例
    Cookie的特点和作用:cookie存储数据在客户端浏览器浏览器对于单个cookie的大小有限制(4kb)以及对同一个域名下的总cookie数量也有限制(20个)作用:cookie一般用于存储......
  • session的特点以及验证码案例的需求和分析
    session的特点1、session用于存储一次会话的多次请求的数据,存在服务器端2、session可以存储任意类型,任意大小的数据session和Cookie的区别:1、session存储......
  • 案例-文件下载
    案例-文件下载文件下载需求页面显示超链接点击超链接弹出下载提示框完成图片文件下载   分析超连接指向的资源如果能够被浏览器解析则在浏览器中展示,如果......
  • jsp_快速入门和jsp案例_改造cookie案例
    JSP的内置对象在JSP页面中不需要获取创建,可以直接使用的对象jsp一共有9个内置对象RequestResponseout:字节输出流对象,可以将数据输出到页面上......
  • 服务端高性能网络IO编程模型简析
    服务端高性能网络IO编程模型简析一、客户端与服务器端多数网络应用可以分为客户端(client)和服务器端(server)模型,然后中间通过各种定义的协议来进行两端的通信。比如......
  • mtr网络丢包神器你搞定网络丢包,网络延迟!
    这款神器完美帮你搞定网络丢包,网络延迟!点击关注......
  • 服务器12种基本故障+排查方法
    服务器12种基本故障+排查方法入门小站 入门小站 2022-07-1022:12 发表于湖北收录于合集#Linux478个#windows14个#服务器5个加电类故障定义举例从上电(或......