服务器遭遇SYN Flood时,连接表被占满的本质是攻击者用大量不完整的TCP握手请求,把内核的半连接队列(SYN Queue)塞满,导致正常用户的新连接无法建立,服务直接瘫痪。
SYN Flood攻击原理是什么:连接表如何在几秒内被填满
先理解门卫大爷的工作方式:TCP三次握手
每个服务器都有个“门卫大爷”,也就是内核里的连接表,正常访客想进机房参观,必须走一套固定流程:先喊一声“你好,我想进来”(SYN包),门卫大爷记下访客名字,在登记本上画一笔(半连接状态),回一句“好的,你登记了”(SYN-ACK包),等着访客回一句“收到,我进来了”(ACK包),只有这套流程走完,访客才真正进门,登记本上那个“半笔”才会划掉。
这个登记本就是内核里的半连接队列,技术术语叫SYN Queue,所有正在走流程但没走完的连接,都暂时挂在这里,队列容量由 net.ipv4.tcp_max_syn_backlog 参数控制,常见默认值在128到1024之间,具体看系统发行版和内存配置。
攻击者是怎么刷爆登记本的
SYN Flood的攻击者根本不想进门,他雇了一堆“机器人访客”,每个人只喊“你好我想进来”,门卫大爷记下名字、回一句“好的你登记了”,然后就没了下文。
正常情况下,访客会在几秒内回复ACK,大爷就把名字划掉,但攻击者制造的半连接,故意不回ACK包,同时还不断伪造新的源IP地址继续喊“你好”,内核有一个定时器,半连接条目默认得等60秒(tcp_synack_retries 控制重试次数)才会超时清理。
一个真实例子能帮你直观感受:
- 队列容量:512(常见配置)
- 攻击速率:每秒10000个伪造SYN包
- 队列填满时间:约0.05秒
也就是说,从攻击发起那一刻起,登记本在眨眼间就写满了。
填满之后会发生什么
登记本满了,门卫大爷再遇到新访客,只能摆手说“没地方记了,你走吧”,这时候发生了什么:
ss -t命令查看,成千上万个连接卡在SYN_RECV状态- 新到达的SYN包被直接丢弃,
listen队列溢出计数持续上涨 - 攻击者的SYN包还占用了内核socket内存,
slab内存分配随之飙升 - 系统CPU忙于构造SYN-ACK包和校验伪造的源IP地址,占用大幅升高
行业共识认为,SYN Flood之所以难防御,正是因为它利用的是TCP协议本身的机制,攻击成本极低一个伪造源IP的SYN包,就能让服务器消耗远高于攻击者的资源去回应。

连接表被占满后,服务器到底经历了什么
从网卡到应用层的连环崩溃
-
网卡层面:大量伪造的SYN包涌入,网卡中断频繁触发,处理这些数据包消耗掉第一轮CPU资源。
-
内核协议栈:每个SYN包都需要经过IP校验、路由查找、TCP状态机初始化,内核为每个半连接分配
sock结构体,这些内存不是释放的,得等超时才会回收。 -
应用层表现:nginx或Tomcat的端口监听正常,
netstat -tlnp也能看到端口在监听,但新请求连不进来,用户访问直接超时,curl卡在“无法与服务器建立连接”阶段,页面转圈。 -
隐藏陷阱:当半连接队列满时,Linux内核会尝试用
tcp_syncookies兜底,给每个SYN包计算一个Cookie,但Cookie校验本身也消耗CPU,大流量下反而加剧CPU过载,形成恶性循环。
真实运维场景中如何用命令确认连接表被占满
你需要打开终端,依次执行下面的排查命令,看到以下输出就说明连接表确实被攻击了:
ss -t state syn-recv | wc -l
正常情况这个值一般是个位数或几十,攻击时能达到数万甚至数十万,再看另一个命令:
netstat -s | grep -i "SYNs to LISTEN"
如果看到 SYNs to LISTEN sockets dropped 这个计数在持续快速跳增,说明半连接队列已溢出,大量SYN包被内核丢弃。
再用 tcpdump 抓包看特征:
tcpdump -i eth0 -n "tcp port 80 and tcp[tcpflags] & tcp-syn != 0"
攻击流量往往源IP极其分散,且发出的SYN包不带窗口缩放选项,TTL值高度一致,这正是脚本工具的典型特征。
服务器连接表被占满怎么办:日常运维能做的三件事
第一步:打开syncookies开关防系统崩溃
这是应急的第一道救命稻草,让内核在队列满时用Cookie来验证连接合法性:
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
同时可以适当调大半连接队列的上限:
echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog
注意,syncookies能“消化”掉不完整的握手请求,但代价是每个SYN包都需要CPU计算Cookie,攻击流量太大时,CPU照样会被拖垮,它延长了服务器存活时间,但治标不治本。
第二步:用iptables限速拦住明显的攻击包

如果看到某个IP发的SYN包异常密集,可以手动加规则:
iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 20 -j DROP
或者用hashlimit限制单位时间内SYN包速率:
iptables -A INPUT -p tcp --syn -m hashlimit --hashlimit-above 10/second --hashlimit-burst 20 --hashlimit-name synlimit -j DROP
这类规则对固定源IP的攻击有直接效果,但对伪造源IP的分布式攻击,规则很快就会失效,反而因为多了iptables判断逻辑消耗额外性能。
第三步:评估是否要上高防清洗
ping 不通了,ssh 也连不上,或者连接表持续占满超过5分钟,说明本地手段已经扛不住,继续改内核参数没有任何意义,这时候该联系云服务商,启用DDoS高防IP或流量清洗服务,把攻击流量引到上游清洗节点,只放行干净流量回源。
行业共识认为,高防方案的选型取决于业务规模,小站点用服务商自带的基础DDoS防护就够了;电商、游戏这类对延迟敏感的业务,最好选择BGP高防线路。
SYN Flood防御方案对比:从本地硬扛到云端清洗
下面表格是一份本地和云端两种不同维度方案的对比:
| 方案类型 | 具体手段 | 攻击流量接入前效果 | 流量特别大时表现 | 大致成本范围 |
|---|---|---|---|---|
| 本地内核参数调优 | 调大backlog、开syncookies | 能撑住小规模扫描性攻击 | 队列照满,CPU耗尽 | 零成本 |
| 本机iptables限速 | 限制单IP SYN速率 | 对固定IP攻击有奇效 | 伪造IP则规则失效 | 零成本 |
| 云服务商基础防护 | 流量牵引至清洗集群 | 防御10Gbps以下攻击 | 超出阈值会封禁IP | 按带宽付费,几十到几百元/月 |
| 高防IP/独立清洗 | 完全分离攻击流量 | 可防御数百Gbps攻击 | 需额外购买,价格较高 | 按业务量计费,几千到数万元/月 |
国内服务器防御SYN Flood的常见误区
很多站长有个错误观念:认为加个防火墙就能万事大吉,云服务器自带的云防火墙和本机iptables有本质区别云防火墙可以配合负载均衡做连接数调度,它拦截逻辑更复杂;而本机iptables必须先把攻击流量全部接收上来,才能做出丢弃决定,这个过程本身消耗的带宽和CPU就已经让服务器不堪重负了。
还有的人过于依赖调大

tcp_max_syn_backlog,把队列调成65535,看似解决了溢出问题,但每个半连接条目都要占用内存,几十万条目直接把内存吃光,内核内存回收机制触发后,整个系统开始卡死,队列不是越大越好,给多少容量就得付出多少内存代价。
选高防方案时应该注意什么
如果你决定上高防,业内专家指出,挑选服务商时需要考察三个问题。
第一,清洗节点的带宽是否充足,很多厂商标称“防御100G”,但实际清洗机房的出口带宽不足,攻击一上来,整个链路直接瘫掉,防御成了一纸空文。
第二,有没有源站IP保护机制,高防IP对用户访问其实多了一层代理转发,攻击者如果顺藤摸瓜查出源站真实IP,绕过高防直连源站,那高防就形同虚设,正规厂商会提供源站IP白名单或者回源链路加密方案。
第三,清洗规则是否透明可调,有些清洗策略为了防止误杀,会把“SYN_RECV率过高”的源直接拉黑,但正常业务本身的SYN包速率就不低,容易被误伤,你最好找一个支持自定义阈值和规则的方案。
Q&A:服务器连接表被SYN Flood占满的常见疑问
怎么区分正常的超高并发请求和SYN Flood攻击
正常请求会迅速完成三次握手,SYN包之后的ACK包紧跟而来,连接状态从 SYN_RECV 迅速转为 ESTABLISHED,握手失败率极低,攻击流量的特征完全不同,大量连接停留在 SYN_RECV 不动,源IP具有明显的伪造痕迹分布过于均匀、地理位置跨度极大、TTL值高度一致,看 netstat -s 里 SYNs to LISTEN dropped 是否持续暴涨,是更准确的判断方法。
tcp_syncookies开启后,SYN Flood就完全解决了吗
不能。tcp_syncookies 的本质是不依赖半连接队列就能完成握手验证,相当于把门卫大爷的“登记本”换成了“进门暗号”,但暗号生成需要密码学运算,攻击流量巨大时,服务器的CPU资源会被Cookie计算持续消耗,同时攻击流量依然占满了入口带宽,合法请求进入不了机房,它保证的是操作系统不因内存耗尽而崩溃,不保证业务可用。
被SYN Flood打瘫痪后,恢复服务通常要多久
这完全取决于攻击是否还在继续,如果攻击已停止,内核的半连接队列会在超时定时器触发后自动清理(通常是几十秒到两三分钟),业务自行恢复,如果攻击持续,本地防御基本无法恢复,启用高防清洗后通常在5到15分钟内完成流量切换和业务恢复,具体速度取决于DNS解析记录TTL和云厂商的调度策略。