SYN Flood会让服务器持续等待握手完成,核心原因是攻击者只发送SYN包而不回应服务器的SYN-ACK,导致服务器为每个“半开连接”分配内存并反复重传,直到半连接队列被占满,正常用户无法建立连接。
SYN Flood攻击原理和防御方法:先看懂三次握手怎么被利用
TCP建立连接要完成三次握手,这个过程像打电话确认双方都能听见,客户端先喊一声“SYN”,服务器回一句“SYN-ACK”,客户端再回一句“ACK”,连接才算建立,SYN Flood专挑第二步下手。
攻击者只发SYN,不回ACK
攻击者用脚本批量发送SYN包,源IP地址往往伪造或不真实,服务器收到SYN后,会立刻分配一个半连接条目,把连接状态记为SYN-RCVD,然后回SYN-ACK,正常客户端应该马上回ACK,但攻击者根本不回,服务器就傻傻等着,还隔一段时间重发SYN-ACK,默认重传多次。
- 第一次重传:约1秒后
- 第二次重传:约2秒后
- 第三次重传:约4秒后
- 继续指数退避,直到达到上限
也就是说,一个伪造SYN能让服务器等上几十秒甚至更久,大量伪造SYN同时涌入,半连接资源很快耗尽。
行业共识认为,单纯靠服务器内核调优只能缓解小规模攻击,大规模攻击需要在入口处清洗流量。
防御思路分三层
防御SYN Flood可以从内核参数、网络设备、云防护三个层面入手。
- 内核层:开启SYN Cookie、调大半连接队列、缩短重传次数
- 网络层:防火墙限速、丢弃异常SYN包
- 云防护层:接入高防IP或高防服务器,在流量到达源站前过滤
服务器半连接队列满了会怎样?资源被“半开握手”拖垮
服务器为半开连接准备了一个队列,通常叫半连接队列,这个队列的长度由内核参数net.ipv4.tcp_max_syn_backlog和应用程序的listen() backlog共同决定,队列没满时,新SYN可以进入;队列一满,后续SYN包会被直接丢弃。
半连接队列满的具体表现
假设你运营一个部署在华东节点的电商网站,促销前突然接到用户反馈页面打不开,登录服务器执行ss -s一看,SYN-RECV状态的连接数飙到几万条,而正常ESTAB连接几乎没有增长,再执行
netstat -nat | grep SYN_RECV | wc -l,数字持续上涨,这就是典型的SYN Flood,此刻服务器并没有宕机,CPU也不一定很高,但新用户就是连不上,原因就是半连接队列被那些“只握手不进门”的SYN包占满了。
当半连接队列被打满,正常用户会遇到这些情况:
- 客户端显示连接超时,浏览器一直转圈
- 服务器SSH登录卡在输入用户名阶段
- 已有连接不受影响,但新连接几乎无法建立
ss -s命令能看到大量SYN-RECV状态连接- 内核日志可能出现
possible SYN flooding提示
可以用下面这张表对比正常握手和SYN Flood攻击下的半连接状态:
| 场景 | 半连接队列占用 | 客户端行为 | 服务器资源消耗 |
|---|---|---|---|
| 正常访问 | 短暂占用后释放 | 回复ACK完成握手 | 每连接占用小 |
| SYN Flood | 长时间堆积不释放 | 不回复ACK | 内存和CPU持续消耗 |
为什么等待时间这么长
服务器不是没想过主动断开可疑连接,问题在于,TCP协议设计时优先保证可靠传输,默认认为网络丢包是常态,不能因为一次没收到ACK就立刻断开,所以服务器会重传SYN-ACK,重传次数由net.ipv4.tcp_synack_retries控制,默认值通常是5次,叠加指数退避,总等待时间可能超过一分钟,攻击者正好利用这个“老好人”设定。
syn flood攻击怎么解决?内核参数与高防服务实操
解决SYN Flood不能靠单一手段,需要结合服务器配置和外部防护,下面按从轻到重的顺序列出可操作步骤。
Linux内核参数调优
在Linux服务器上,可以通过sysctl命令调整几个关键参数。
net.ipv4.tcp_syncookies=1:开启SYN Cookie,队列满时不再分配完整半连接资源,而是用算法验证客户端net.ipv4.tcp_max_syn_backlog=8192:适当增大半连接队列长度net.ipv4.tcp_synack_retries=2:减少SYN-ACK重传次数,缩短等待时间net.ipv4.tcp_abort_on_overflow=1:队列溢出时直接重置连接
执行命令示例:
sysctl -w net.ipv4.tcp_syncookies=1 sysctl -w net.ipv4.tcp_max_syn_backlog=8192 sysctl -w net.ipv4.tcp_synack_retries=2 sysctl -w net.ipv4.tcp_abort_on_overflow=1
改完后执行sysctl -p让配置生效,这些参数能提高服务器对SYN Flood的抵抗能力,但面对大流量攻击,仅靠内核调优仍然不够。
开启SYN Cookie后,队列满时服务器不再分配半连接对象,而是根据SYN包信息计算一个Cookie放入SYN-ACK序号,客户端回ACK时校验Cookie合法才分配资源,这样即使攻击者不回ACK,服务器也不留任何状态。
高防服务器能防syn flood吗?分场景看效果
高防服务器通常部署在清洗中心后面,流量先经过清洗设备,把SYN Flood、UDP Flood等攻击流量过滤掉,再把正常流量转发到源站,对于多数情况下的SYN Flood攻击,高防服务器确实能有效防护,但要注意两点:
- 高防服务器的防护能力取决于套餐带宽和清洗阈值,攻击流量超过阈值时仍可能透传
- 如果源站IP暴露,攻击者直接打源站,高防就失去作用
所以使用高防服务器时,应隐藏源站真实IP,只允许清洗节点回源,另外高防服务器价格通常比普通服务器高出一截,因为清洗带宽和防护能力不同,选择时不要只看标价,要确认是否包含SYN Flood防护,以及实际清洗阈值是多少。
SYN Flood与CC攻击的区别:一个堵握手队列,一个耗业务资源
很多人把SYN Flood和CC攻击混为一谈,其实它们作用在不同层面。业内专家指出,SYN Flood属于网络层攻击,目标是耗尽TCP半连接资源;CC攻击属于应用层攻击,目标是耗尽服务器的CPU、内存或数据库连接。
| 对比项 | SYN Flood | CC攻击 |
|---|---|---|
| 攻击层级 | 传输层/网络层 | 应用层 |
| 目标资源 | 半连接队列 | 页面处理能力 |
| 数据包特征 | 大量SYN包 | 大量完整HTTP请求 |
| 防御难度 | 较容易识别 | 更难识别,请求看起来正常 |
| 典型表现 | 新连接无法建立 | 网站打开极慢或502 |
理解这个区别可以帮运维快速判断攻击类型,如果服务器上
ss -s显示大量SYN-RECV,基本是SYN Flood;如果连接正常但CPU打满、网站响应慢,多半是CC攻击。
为什么服务器不能立刻断开可疑握手
有人会问,服务器为什么不直接断开长时间不回复ACK的连接?原因在TCP协议栈的实现逻辑。
TCP协议栈的“先相信再验证”
TCP设计目标是可靠传输,它没法在收到SYN的一瞬间判断对方是真人还是攻击脚本,如果贸然断开,在网络质量差的场景下,正常用户也会频繁连接失败,所以协议栈选择先分配资源再等待确认,这个机制被SYN Flood利用。
重传机制把等待时间拉得更长
服务器发出SYN-ACK后,会启动重传定时器,重传间隔按指数退避算法增长,比如1秒、2秒、4秒、8秒、16秒,重传次数由tcp_synack_retries决定,总等待时间可能达到几十秒,攻击者用极低成本制造一个SYN包,服务器却要付出几十秒的资源占用,攻防成本严重不对等。
SYN Flood之所以能让服务器持续等待握手完成,根子在于TCP三次握手的第一步就分配资源,加上重传机制默认宽松,攻击者可以用极低成本占满半连接队列,解决办法也很明确:调优内核参数缩短等待、开启SYN Cookie、接入专业防护隐藏源站,理解这个机制,才能真正防住这类“敲门不进门”的攻击。
Q&A
为什么SYN Flood会让服务器持续等待握手完成?
因为服务器收到SYN后必须回复SYN-ACK并等待ACK,等待期间会占用半连接队列资源,攻击者故意不回ACK,服务器还会按重传机制反复发送SYN-ACK,等待时间被拉长到几十秒,大量这样的半开连接堆积,队列就会耗尽。
syn flood攻击怎么解决最简单有效?
最简单有效的办法是接入高防IP或高防服务器,把攻击流量挡在源站外面,同时在源站开启tcp_syncookies=1,减少tcp_synack_retries值,可以避免小规模攻击直接打满半连接队列。
高防服务器能防syn flood吗?
能防,但有前提,高防服务器通过流量清洗设备识别并丢弃SYN Flood攻击包,只放行正常流量,如果源站真实IP没有暴露,攻击流量被引导到高防节点,防护效果较好,若源站IP泄露,攻击者绕过清洗直接打源站,高防就形同虚设。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/637483.html





