当大量客户端同时发起连接请求时,服务器若无法在短时间内处理完这些请求,会导致全连接队列(accept queue)或半连接队列(syn queue)迅速填满。例如,电商促销期间大量用户同时下单,服务器处理能力不足会使backlog队列溢出,新的连接请求被拒绝。
攻击者通过发送大量伪造的SYN包(不完成三次握手),耗尽服务器的半连接队列资源(由net.ipv4.tcp_max_syn_backlog参数定义)。此时,正常用户的SYN请求无法进入队列,导致连接失败。可通过dmesg命令查看“TCP: drop open request from”等日志确认。
关键内核参数设置不合理会直接影响backlog处理能力:
net.core.somaxconn:定义全连接队列的最大长度,默认值通常较小(如128),高并发下易溢出;net.ipv4.tcp_max_syn_backlog:定义半连接队列的最大长度,默认值(如1024)可能不足以应对突发流量;net.core.netdev_max_backlog:定义网卡驱动层接收缓冲区的最大长度,若设置过小,数据包无法及时传递给内核协议栈。服务器处理每个连接的效率不足(如业务逻辑复杂、数据库查询慢、IO阻塞),导致全连接队列中的连接无法及时被accept()函数取走。例如,一个PHP脚本处理请求耗时5秒,即使backlog设置为1024,也会很快填满。
Linux内核通过nf_conntrack模块跟踪每个网络连接的状态(如TCP的三次握手)。若连接数过多(如超过nf_conntrack_max参数的限制),新连接的数据包会被丢弃,导致backlog队列无法正常处理。可通过cat /proc/sys/net/netfilter/nf_conntrack_count查看当前连接跟踪数。
网卡驱动层的接收缓冲区(Ring Buffer)用于临时存储接收到的数据包。若数据包到达速率超过内核处理速率,Ring Buffer会被填满,导致数据包丢失,进而使backlog队列无法接收新连接。可通过ethtool -g eth0查看Ring Buffer大小。
部分应用程序(如Nginx、Apache)的listen函数参数设置不当,导致backlog队列大小不符合实际需求。例如,Nginx默认的backlog值为511,高并发下需要调整为更大的值(如2048)。