目录:

TCP洪水攻击(SYN Flood)的诊断和处理

TCP/IP协议中backlog参数

TCP建立连接是要进行三次握手,但是否完成三次握手后,服务器就处理(accept)呢?

  backlog其实是一个连接队列,在Linux内核2.2之前,backlog大小包括半连接状态和全连接状态两种队列大小。

  半连接状态为:服务器处于Listen状态时收到客户端SYN报文时放入半连接队列中,即SYN queue(服务器端口状态为:SYN_RCVD)。

  全连接状态为:TCP的连接状态从服务器(SYN+ACK)响应客户端后,到客户端的ACK报文到达服务器之前,则一直保留在半连接状态中;当服务器接收到客户端的ACK报文后,该条目将从半连接队列搬到全连接队列尾部,即 accept queue (服务器端口状态为:ESTABLISHED)。

  在Linux内核2.2之后,分离为两个backlog来分别限制半连接(SYN_RCVD状态)队列大小和全连接(ESTABLISHED状态)队列大小。

  半连接队列:SYN queue 队列长度由 /proc/sys/net/ipv4/tcp_max_syn_backlog 指定,默认为2048。

  全连接队列:Accept queue 队列长度由 /proc/sys/net/core/somaxconn 和使用listen函数时传入的参数,二者取最小值。默认为128。

在Linux内核2.4.25之前,是写死在代码常量 SOMAXCONN ,在Linux内核2.4.25之后,在配置文件 /proc/sys/net/core/somaxconn 中直接修改,或者在 /etc/sysctl.conf 中配置 net.core.somaxconn = 128 。

  可以通过ss命令来显示

[root@localhost ~]# ss -l
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:http *:*
LISTEN 0 128 :::ssh :::*
LISTEN 0 128 *:ssh *:*
LISTEN 0 100 ::1:smtp :::*
LISTEN 0 100 127.0.0.1:smtp *:*

  在LISTEN状态,其中 Send-Q 即为Accept queue的最大值,Recv-Q 则表示Accept queue中等待被服务器accept()。

队列溢出

另外,客户端connect()返回不代表TCP连接建立成功,有可能此时accept queue 已满,系统会直接丢弃后续ACK请求;客户端误以为连接已建立,开始调用等待至超时;服务器则等待ACK超时,会重传SYN+ACK 给客户端,重传次数受限 net.ipv4.tcp_synack_retries ,默认为5,表示重发5次,每次等待30~40秒,即半连接默认时间大约为180秒,该参数可以在tcp被洪水攻击是临时启用这个参数。

注:accept queue溢出,即便SYN queue没有溢出,新连接请求的SYN也可能被drop。  

查看SYN queue 溢出

[root@localhost ~]# netstat -s | grep LISTEN
102324 SYNs to LISTEN sockets dropped

查看Accept queue 溢出

[root@localhost ~]# netstat -s | grep TCPBacklogDrop
TCPBacklogDrop: 2334

案例1

Nginx作为7层反向代理,客户端HTTP请求 – NGINX – 透明代理,透明代理接口存在大量慢请求;

思路

抓包,客户端同nginx通信,nginx立即返回ACK(1ms),但是3s后才返回响应数据;

Nginx同后端通信,发送SYN请求等待3s后端才响应;

结论

Backlog设置过小,导致accept queue溢出,SYN被丢弃导致3s重传;

将backlog从50增加到512,somaxconn=512;

案例2

Testserver随机生成RAR/ZIP文件,testclient访问testserver获取生成文件,所有调用采用block方式;

运行一段时间后程序永久阻塞,strace先生testclient阻塞在recvmsg;

思路

抓包观察3次握手协议,服务器返回SYN+ACK,客户端响应ACK,可服务器再次发送同样的SYN+ACK;

客户端响应的ACK丢包,而net.ipv4.tcp_synack_retries = 1;

结论

三次握手最后一步失败,server保持SYN_RECV状态等待接收ACK,client发送ACK状态变为ESTABLISHED,其认为connect()成功故接着调用recvmsg();

Syn+ack被设置为只重传一次,若这次重传仍失败,则客户端永久阻塞;

其他案例

Backlog过大,连接积压在accept queue,nginx由于连接超时而断开,PHP accept返回时连接已被客户端close,故报告PHP write Broken pipe;

Backlog过小,accept queue溢出,握手第3步的ACK被丢弃,但client认为连接成功并发送数据,造成所谓慢请求;

参考资料:

TCP SOCKET中backlog参数的用途是什么?

TCP/IP协议中backlog分析与设置以及TCP状态变化

TCP3次握手和backlog溢出

TCP queue 的一些问题

TCP洪水攻击(SYN Flood)的诊断和处理

TCP之三:TCP/IP协议中backlog参数(队列参数)的更多相关文章

  1. TCP/IP协议中backlog参数

    TCP建立连接是要进行三次握手,但是否完成三次握手后,服务器就处理(accept)呢? backlog其实是一个连接队列,在Linux内核2.2之前,backlog大小包括半连接状态和全连接状态两种队 ...

  2. 【转】TCP/IP协议中TCP和UDP的区别

    TCP协议与UDP协议的区别    首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信! ...

  3. TCP/IP 协议中的编址

    TCP/IP协议的互联网需要用到四个级别的地址:物理地址.逻辑地址.端口地址和特定应用地址 一.物理地址 物理地址称为链路地址,是由接点所在的局域网或广域网为该结点指定的地址. 这种地址的长度和格式随 ...

  4. 05ICMP协议与ARP协议(IP协议中重要协议)

    ICMP协议在网络层,应用:ping命令,tracert命令:追踪命令,用于静态路由. ICMP重定向 redirect

  5. TCP/IP 协议中的滑动窗口

    一个例子明白发送缓冲区.接受缓冲区.滑动窗口协议之间的关系. 在上面的几篇文章中简单介绍了上述几个概念在TCP网络编程中的关系,也对应了几个基本socket系统调用的几个行为,这里再列举一个例子,由于 ...

  6. [转]使用wireshark分析TCP/IP协议中TCP包头的格式

    本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述 TCP是面向连接的可靠传输协议,两个进程互发数 ...

  7. tcp/ip协议中的SYN, ACK的数值变化

    还需要论述一下seq.ack表示什么意思,应该以什么样的角度去理解这两个序列号. sequence number:表示的是我方(发送方)这边,这个packet的数据部分的第一位应该在整个data st ...

  8. TCP/IP协议中几个缩写词的含义 MSL、TTL和RTT 报文最大生存时间 跳数(即生存时间) cs往返时间 MSL要大于TTL知道为什么吗?

    MSL.TTL和RTT简介 1.MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃.因为 ...

  9. TCP/IP协议中的UDP与TCP的区别

    TCP面向连接,UDP面向非连接即发送数据前不需要建立链接TCP提供可靠的服务(数据传输),UDP无法保证,它没有TCP的接受确认.窗口等机制,因此也不需要交换控制信息:发生丢包也一概不负责.TCP面 ...

随机推荐

  1. js 计算时间

    var date1=new Date();  //开始时间   var date2=new Date();    //结束时间 var date3=date2.getTime()-date1.getT ...

  2. 【Html 学习笔记】第八节——表单实践

    列举一些实践的例子: 1.点击按钮后跳转: <html> <body> <form action="1.html"> First <inp ...

  3. 剑指offer--45.二叉树的深度

    时间限制:1秒 空间限制:32768K 热度指数:139716 题目描述 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. -- ...

  4. js 删除数组的指定元素

    //为数组对象增加相应的的方法,直接调用数组的removeByValue方法即可删除指定元素 Array.prototype.removeByValue = function (val) { for ...

  5. vue.js 源代码学习笔记 ----- $watcher

    /* @flow */ import { queueWatcher } from './scheduler' import Dep, { pushTarget, popTarget } from '. ...

  6. [Python] dict字典的浅复制与深复制

    Python中针对dict字典有两种复制: (1)浅复制:利用 copy() 或者 dict() :复制后对原dict的内部子对象(方括号[]内元素)进行操作时,由浅复制得到的dict会受该操作影响 ...

  7. ibatis 参数类型为map,map里面有list

    <select id="getChannelLayerList" parameterClass="java.util.HashMap"        re ...

  8. vc 实现一个 http Server

    实现 http 的协议解析 以及封装 , 对应不同的访问地址, 调用绑定的处理程序 , #include "stdafx.h" #include "lyocomm\web ...

  9. Ubuntu下使用openssl为apache2配置ssl

    安装apache2 sudo apt-get install apache2 安装openssl 一般系统自带,可以通过openssl version查看,如果没有, sudo apt-get ins ...

  10. appium-java,连接真机启动微信

    1.启动appium 2.设置信息 3.设置IP和端口 4.appium连接手机,微信中打开debugx5.qq.com,信息->TBS settings->是否打开TBS内核Insper ...