tcp_syncookies=1是溢出保护开关,仅在tcp_max_syn_backlog队列满时启用syncookie机制,不改变正常连接流程,非常驻处理方式。

能缓解,但“不消耗资源”是误解——syncookies 本质是把内存开销转成 CPU 计算开销,且只在队列满时才触发。它不是万能开关,而是兜底机制。
tcp_syncookies=1 是什么,不是什么
它不是常驻的连接处理方式,而是一个“溢出保护开关”:只有当 net.ipv4.tcp_max_syn_backlog 队列满了,内核才会启用 syncookie 流程。在此之前,所有正常 SYN 请求仍走传统半连接队列,照常分配内存、维护状态。
- 设为
1:自动启用(推荐),队列未满时不生效,无额外开销;队列满时用加密哈希生成SYN+ACK序列号,不存状态 - 设为
2:强制全程启用,哪怕队列空闲也绕过队列——这会禁用 SACK 和窗口缩放,对高丢包链路(如跨境、弱 Wi-Fi)吞吐有可测影响 - 设为
0:关闭,完全依赖队列硬扛,攻击一来就卡死
为什么调大 tcp_max_syn_backlog 没用
因为一旦 tcp_syncookies=1 生效,tcp_max_syn_backlog 就被内核忽略——你再把它设成 10000,syncookie 模式下也不看这个值。很多教程还教人盲目调大它,纯属白忙。
- 真正该调的是
net.core.somaxconn(监听 socket 队列上限)和net.core.netdev_max_backlog(网卡软中断收包队列),它们影响的是更上游的流量接纳能力 -
tcp_max_syn_backlog只在 syncookie 关闭或未触发时起作用;开启后它的唯一价值是“决定 syncookie 何时启动”,而非“能撑多少连接”
必须配套的两个动作
单独开 tcp_syncookies 效果有限,攻击者发得够快,照样压垮 CPU 或耗尽带宽。必须加两层协同防护:
- 用
iptables在进内核前限速:建自定义链拦截高频 SYN,例如iptables -A syn-flood -m limit --limit 50/s --limit-burst 10 -j RETURN,避免无效包走到 TCP 栈 - 调低
net.ipv4.tcp_synack_retries到2或3:默认是5,意味着单个伪造 SYN 最多占用服务器约 63 秒(指数退避:1s, 3s, 7s, 15s, 31s);设为2后只剩 1s + 3s = 4 秒,资源释放快得多
容易被忽略的副作用
syncookies 不是免费午餐,几个实际运行中会撞上的点:
- 它和
tcp_tw_reuse不冲突,可以共存;但启用后,tcp_sack(选择性确认)会被禁用——这不是 bug,是原始设计限制;Linux 4.10+ 内核虽支持时间戳携带 SACK 信息,但需确认发行版是否启用该补丁 - 某些云厂商 LB(如阿里云 SLB、腾讯 CLB)在四层透传模式下,可能因修改了源 IP 或时间戳导致 cookie 验证失败,表现为部分真实用户偶发连接超时
-
tcp_syncookies=1下,ss -s输出里的SYNs to LISTEN sockets ignored计数会上升——这是正常现象,说明 syncookie 正在工作,别误以为是丢包











