• 计算机网路学习-time_wait过多


    四次挥手

    在这里插入图片描述

    调试命令

    netstat -an|awk ‘/tcp/ {print $6}’|sort|uniq -c

    • netstat -an
      列出系统中所有处于活动状态的网络连接信息,包括 IP 地址、端口号、协议等。
      其中,第六列是tcp的状态。

      Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
      tcp4       0      0  192.168.1.9.64861      x.x.x.x.443     SYN_SENT
      tcp4       0      0  192.168.1.9.64847      x.x.x.x.443     ESTABLISHED
      tcp4       0      0  192.168.1.9.64838      x.x.x.x.443       ESTABLISHED
      tcp4       0      0  192.168.1.9.64789      x.x.x.x.443     ESTABLISHED
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • awk ‘/tcp/ {print $6}’
      按行进行匹配,筛选出包含 tcp 的行,只输出符合条件的结果
      过滤 TCP 类型的连接,然后输出连接状态字段。$6 表示第 6 列的字段,即连接状态

    • sort
      按连接状态($6)进行排序

    • uniq -c
      统计相同状态的连接数量,并输出一个计数值

    为什么会有 time_wait?

    • 防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)
    • 可靠的关闭TCP连接

    在主动关闭方发送的最后一个 ack(fin) ,可能丢失,这时被动方会重新发fin
    如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。
    所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。

    TIME_WAIT 并不会占用很大资源的,除非受到攻击。
    如果一方 send 或 recv 超时,就会直接进入 CLOSED 状态

    内核参数调整

    系统存在大量TIME_WAIT状态连接,调整内核参数

    // vim /etc/sysctl.conf
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1 // Linux 从4.12内核版本开始移除了 tcp_tw_recycle
    net.ipv4.tcp_fin_timeout = 30
    
    • 1
    • 2
    • 3
    • 4
    • 5

    tcp_syncookies

    背景

    当系统遇到 TCP SYN 攻击时,可以自动启用 SYN Cookies 机制,来保护系统免受 SYN 攻击
    TCP SYN 攻击是一种常见的网络攻击方式,它利用 TCP/IP 协议中的漏洞来发起攻击,从而使得目标系统无法正常工作。
    该攻击方式是通过向目标系统发送大量伪造的 SYN 请求,来占用系统资源(S端的Listen的backlog队列,半连接队列)
    迫使其陷入卡死的状态。
    SYN Cookie 是一种用于解决 TCP SYN 攻击的算法,它可以理解为一种在服务器端动态生成、维护与处理的 Cookie。其基本原理是通过对 TCP 连接握手的过程进行修改,避免向服务器端存储半开连接的信息,从而避免半开连接队列遭受 SYN Flood 攻击。

    解决

    当启用 net.ipv4.tcp_syncookies 参数时,内核会自动启用 SYN Cookies 技术,来处理频繁的 SYN 请求
    改变 TCP 握手步骤中的一些规则,来区分正常的请求和攻击请求,并丢弃恶意的请求,以保证系统的安全性和可用性。

    要启用 net.ipv4.tcp_syncookies 参数,可以使用如下命令(需要管理员权限)

    sysctl -w net.ipv4.tcp_syncookies=1
    
    • 1

    如果要禁用该参数,可以将 1 改为 0

    算法原理

    TCP建立连接时,双方起始报文序号是任意的。SYN cookies利用这一点,按照以下规则构造初始序列号

    (1)设:

    • t为一个缓慢增长的时间戳(典型实现是每64s递增一次)
    • m为客户端发送的SYN报文中的MSS选项值
    • s是连接的元组信息(源IP,目的IP,源端口,目的端口)和t经过密码学运算后的Hash值,即s = hash(sip,dip,sport,dport,t),s的结果取低 24 位

    (2)初始序列号n为:

    • 高 5 位为t mod 32
    • 接下来3位为m的编码值
    • 低 24 位为s

    (3)客户端收到此SYN+ACK报文后,回复ACK报文,且报文中ack = n + 1
    (4)服务端收到它时,将ack - 1就可以拿回当初发送的SYN+ACK报文中的序号

    • 服务器巧妙地通过这种方式间接保存了一部分SYN报文的信息

    (5)服务器需要对ack - 1这个序号进行检查:

    • 将高 5 位表示的t与当前之间比较,看其到达地时间是否能接受。
    • 根据t和连接元组重新计算s,看是否和低 24 一致,若不一致,说明这个报文是被伪造的。
    • 解码序号中隐藏的mss信息

    (6)连接建立

    收益

    如果攻击者没有正确响应服务端的 TCP ACK 报文,则无法得到正确的 Cookie。
    只有当攻击者在正确时间内对服务端的 ACK 报文进行响应时,才能成功建立连接,否则连接不会被建立
    从而保证了服务器不会因为未建立的连接消耗大量资源。

    为什么没有被纳入TCP标准?

    • MSS的编码只有3位,因此最多只能使用 8 种MSS值
    • 服务器必须拒绝客户端SYN报文中的其他只在SYN和SYN+ACK中协商的选项,原因是服务器没有地方可以保存这些选项,比如Wscale和SACK (影响了扩展功能的使用
    • 增加了密码学运算

    SYN协商中,需要协商啥?

    服务器在半连接队列中,保存此次请求的关键信息,包括请求的来源和目(五元组),以及TCP选项,如最大报文段长度MSS、时间戳timestamp、选择应答使能Sack、窗口缩放因子Wscale等等。
    当后续的ACK报文到达,三次握手完成,新的连接创建,这些信息可以会被复制到连接结构中,用来指导后续的报文收发。

    思考

    • 原来伟大的东西就是一个东西,没有善意和恶意,善意和恶意来源于它的使用方,比如TCP、比如炸药、比如一把刀
    • 一个东西足够伟大,以至于光明和黑暗都能通过它吸收能量

    tcp_fin_timeout

    控制 TCP 连接在正常关闭后保持在 FIN_WAIT2 状态的时间长度,即系统在发送 FIN 包并等待 ACK 包的超时时间

    在正常关闭 TCP 连接时,当Linux 内核需要确保所有的数据包和确认信息都被接收方成功接收,以便双方之间的连接彻底关闭,否则可能会导致连接状态的混乱或重传数据等问题。

    为了确保连接状态正常且不占用过多系统资源,内核需要在一定的时间间隔内等待连接的停止,并在一定时间内保持连接关闭状态,以便在该时间段内收到由远程的另一端发来的针对旧连接的数据包时能根据 RST 段重置连接,从而释放占用的系统资源

    tcp_fin_timeout 内核参数的默认值是 60 秒。可以通过以下命令来查看或修改该值:

    # 查询当前值
    sysctl net.ipv4.tcp_fin_timeout
    
    # 修改为 30 秒
    sudo sysctl -w net.ipv4.tcp_fin_timeout=30
    
    • 1
    • 2
    • 3
    • 4
    • 5

    设置太短可能会导致连接意外断开/连接超时
    设置过长则会占用过多系统资源,需要权衡

    注意:它不是2MSL

    tcp_tw_reuse

    启用或禁用TIME-WAIT状态下的 TCP 连接复用,即开启该参数后,可以重用处于 TIME-WAIT 状态的本地地址和端口号来建立新的 TCP 连接,从而节省连接资源。

    在正常的 TCP 协议交互中,当连接关闭时,内核通常会保持该连接在 TIME-WAIT 状态一段时间,这个时间通常是 2MSL(最大报文段生命周期)的长度,时长为 60 秒。在这段时间内,连接的所有报文都会被清除,连接的两端均无法再次使用该地址和端口号建立新的连接。

    通过开启 tcp_tw_reuse 参数,可以在 TIME-WAIT 状态下,通过操作内核参数允许一个新的连接使用已经被释放的本地地址和端口号,从而复用连接资源,避免因为大量 TIME-WAIT 状态连接的资源浪费导致系统性能下降,减少了系统网络资源的占用,增加了连接数的吞吐量。

    tcp_tw_recycle - kernel 4.12已移除

    开启或关闭 TCP 连接的 time-wait 快速回收机制。

    在正常交互过程中,当 TCP 连接关闭时,内核通常会保持该连接在 TIME-WAIT 状态一段时间,以确保连接的所有报文都被完全传输。这个时间通常是 2MSL(最大报文段生命周期)的长度,时长为 60 秒。在这段时间内,连接的所有报文都会被清除,连接的两端均无法再次使用该地址和端口号建立新的连接(服务端的IP和端口是公开的,这里特指客户端的IP和端口,尤其是客户端的端口)。

    通过开启 TCP 连接的 time-wait 快速回收机制,可以在连接关闭后尽快清除连接的状态信息,从而释放内存资源。

    tcp_tw_recycle 参数用于开启 TCP 连接 time-wait 快速回收机制,在部分情况下可以有效缩短 time-wait 时间,避免因大量 time-wait 状态的连接堆积而导致的系统性能下降问题。

    可以通过以下命令来查看或修改该参数的值:

    # 查询当前值
    sysctl net.ipv4.tcp_tw_recycle
    
    # 修改为 1(开启)
    sudo sysctl -w net.ipv4.tcp_tw_recycle=1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    该参数在某些情况下可能会导致连接问题或数据丢失。例如,在网络中存在较为复杂的路由和负载均衡器等设备,或者网络延迟较高时,开启该参数可能会导致连接无法正常建立或数据包丢失。

    参考文档

    https://blog.51cto.com/lookingdream/1902257
    https://segmentfault.com/a/1190000019292140
    https://www.xiaolincoding.com/network/3_tcp/tcp_interview.html#%E4%BB%80%E4%B9%88%E6%98%AF-syn-%E6%94%BB%E5%87%BB-%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D-syn-%E6%94%BB%E5%87%BB

    附录

    uniq

    uniq -c
    一种常用的 Linux/Unix 命令组合,用来对于某一个字符串列表进行计数并输出。
    uniq 命令作为计数器,统计相邻的相同字符串出现的次数
    -c 则表示输出每个字符串出现的次数

    cat /etc/passwd | awk -F’:’ ‘{print $1}’ | sort | uniq -c
    awk -F’:’ ‘{print $1}’ 命令用于取出 /etc/passwd 文件中的第一列,即用户名
    然后使用 sort 进行排序,并使用 uniq -c 统计各个用户在文件中的出现次数

  • 相关阅读:
    docker 安装本地starrocks测试环境
    实用新型专利的特点是什么
    yolov5 优化——mosaic相关
    Python 共享内存与 Qt c++ 程序进程之间通信
    前端练习--W3C导航条
    SpringBoot集成MyBatis(iBatis)
    react-navigation 6.x学习(2)
    函数题37习题10-7 十进制转换二进制《C语言程序设计(第4版)》题目集
    scratch旅行相册 电子学会图形化编程scratch等级考试一级真题和答案解析2022年6月
    【VMware虚拟机中ubuntu系列】—— 在虚拟机中使用本机摄像头的详细教程与常见问题分析及解决
  • 原文地址:https://blog.csdn.net/wangkai6666/article/details/132792521