TCP连接建立中的异常

描述

    建连接时SYN超时问题

  如果 server 端因为某种情况没有收到 client 回来的 ACK,那么,这个连接处还处于一个未建立的状态。于是,server端如果在一定时间内没有收到,则 server 端的 TCP 会重发 SYN_ACK。

  在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了。如果第五次重传之后,还未收到客户端的 ACK,server 端的 TCP 才会把断开这个连接。

  关于SYN Flood攻击

  攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的 SYN 接收队列(未连接队列),使得服务器不能为正常用户服务。

  避免方式

  设置 tcp_syncookies = 1。当 SYN 队列满了后,TCP 会通过源地址端口、目标地址端口和时间戳打造出一个特别的 Sequence Number 发回去(又叫cookie)。

  如果是攻击者则不会有响应,如果是正常连接,则会把这个 SYN Cookie 发回来,然后服务端可以通过 cookie 建连接。

  设置 netdev_max_backlog 的值,确定链接队列的大小。当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。

  通过设置 netdev_max_backlog 的值,确定 SYN_RCVD 状态连接的最大个数。

  通过设置 tcp_abort_on_overflow 的值。当超出处理能时,对新的 SYN 直接回报 RST,丢弃连接。

  断开连接中的异常

  TIME_WAIT数量太多

  从上面的描述可以知道,TIME_WAIT 是个很重要的状态,但是如果在大并发的短链接下,TIME_WAIT 就会太多。TIME_WAIT过多会占用大量的内存资源和端口资源。

  优化法一:tcp_tw_reuse

  设置tcp_tw_reuse = 1,则可以复用处于 TIME_WAIT 的 socket 为新的连接所用。

  有一点需要注意的是,tcp_tw_reuse 功能只能用客户端(连接发起方),因为开启了该功能,在调用 connect() 函数时,内核会随机找一个 time_wait 状态超过 1 秒的连接给新的连接复用。

  使用 tcp_timestamps = 1 选项,还有一个前提,需要打开对 TCP 时间戳的支持,即这个时间戳的字段是在 TCP 头部的「选项」里,用于记录 TCP 发送方的当前时间戳和从对端接收到的最新时间戳。

  由于引入了时间戳,我们在前面提到的 2MSL 问题就不复存在了,因为重复的数据包会因为时间戳过期被自然丢弃。

  优化法二:tcp_max_tw_buckets

  这个值默认为 18000,当系统中处于 TIME_WAIT 的连接一旦超过这个值时,系统就会将后面的 TIME_WAIT 连接状态重置。

  这个方法过于暴力,而且治标不治本,带来的问题远比解决的问题多,不推荐使用。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分