tcp_max_syn_backlog设为32768无效,因其仅为SYN队列软限制,实际容量取min(listen() backlog, somaxconn, tcp_max_syn_backlog);且SYN flood下请求远超队列容量,是否启用SYN cookies取决于tcp_syncookies值及内存压力,而非backlog大小。

tcp_max_syn_backlog 设为 32768 为什么没用
因为 tcp_max_syn_backlog 只控制「未完成三次握手的连接」在 SYN queue 中的最大数量,它不决定是否启用 SYN cookies,也不影响已启用 SYN cookies 后的行为。当队列满时,内核是否丢包、是否 fallback 到 SYN cookies,取决于 net.ipv4.tcp_syncookies 的值和当前内存压力,而不是 backlog 大小。
常见误判是:调大了 tcp_max_syn_backlog 就能扛住 SYN flood —— 实际上,SYN flood 下连接请求远超队列容量,大量请求根本进不了 queue,直接触发丢包或 SYN cookies 判定逻辑。
-
tcp_max_syn_backlog是软限制,受net.core.somaxconn和 listen() 的backlog参数共同约束(取三者最小值) - 即使设为 32768,若应用调用
listen(sockfd, 128),内核仍可能只分配 128 槽位 - 该值对内存占用有直接影响:每个 pending SYN 条目约占用 200–300 字节,32768 ≈ 6–10 MB 内存
tcp_syncookies=1 是必须开的,但要注意触发条件
开启 net.ipv4.tcp_syncookies = 1 是应对 SYN flood 的关键,但它不是“一直生效”,而是在特定条件下才激活:
- 仅当
SYN queue满 + 内核检测到low memory或net.ipv4.tcp_abort_on_overflow = 0时,才会对新 SYN 发送 cookie - 若
tcp_abort_on_overflow = 1,则直接丢包、不发 RST,客户端重试,反而加重攻击面 -
tcp_syncookies = 2表示“无条件启用”(绕过内存检查),但会禁用 TCP 扩展选项(如 SACK、Timestamps),影响性能和兼容性
推荐配置组合:net.ipv4.tcp_syncookies = 1net.ipv4.tcp_abort_on_overflow = 0net.core.somaxconn = 32768net.ipv4.tcp_max_syn_backlog = 32768
应用层 listen() 的 backlog 参数必须同步改
内核不会自动把 tcp_max_syn_backlog 映射到每个 socket;它只作为上限参考。真正起作用的是应用调用 listen() 时传入的 backlog 值,内核取 min(backlog, somaxconn, tcp_max_syn_backlog) 作为该 socket 的 SYN queue 容量。
- Go 默认
listen()backlog 是 128;Nginx 默认是 511;Java Netty 若未显式设置,可能用系统默认(常为 128) - 必须在代码或配置中显式加大:例如 Nginx 配置加
listen 80 backlog=32768;,Go 用net.ListenConfig{Control: ...}设置SOMAXCONN - 检查当前生效值:
ss -lnt | grep :80看 Recv-Q 列上限(即实际 queue size)
SYN cookies 不是银弹,真实瓶颈常在 conntrack 或网卡中断
开了 SYN cookies 后仍被压垮,大概率问题已溢出协议栈层面:
- conntrack 表满(
nf_conntrack_count接近nf_conntrack_max)会导致新建连接失败,错误日志里会出现"nf_conntrack: table full" - 单核 CPU 处理软中断(
softirq)瓶颈:SYN flood 产生大量NET_RX中断,若网卡未做 RSS/RPS,所有包都压到一个 CPU 核,top里能看到si%持续 90%+ - 云环境注意:某些厂商的 SLB 或安全组会在四层前过滤,导致你看到的 SYN 包数远少于真实攻击流量
真正抗住大规模 SYN flood,靠的不是调几个 sysctl,而是:网卡多队列分流 + conntrack 限速 + 前置防火墙规则(如 iptables -A INPUT -p tcp --syn -m limit --limit 100/sec --limit-burst 200 -j ACCEPT)+ 应用层快速 accept() 防止 queue 积压。










