ss -tn state syn-recv | wc -l可查当前半连接数,若持续高于几十,说明syn flood攻击或somaxconn/tcp_max_syn_backlog设置过小;需协同调整net.core.somaxconn、net.ipv4.tcp_max_syn_backlog和tcp_syncookies=1三个参数。

半连接数不是“查出来就完事”的指标,它直接暴露 SYN_RECV 状态是否堆积——一旦持续高于几十,基本说明服务正在被 SYN Flood 攻击,或 somaxconn/tcp_max_syn_backlog 设置过小导致队列溢出。
怎么用 ss 查看当前 SYN_RECV 连接数
这是最轻量、最可靠的方式,ss 直接读内核 socket 表,不依赖 /proc/net/tcp 解析,高并发下也稳定:
- 执行
ss -tn state syn-recv | wc -l得到当前半连接数量 - 若只想看某端口(比如 80)的半连接:
ss -tn state syn-recv sport :80 | wc -l - 注意别用
netstat -an | grep SYN_RECV—— 它在万级连接时可能卡住,且输出含 IPv6 地址格式干扰(如[::ffff:192.168.1.1]:80),容易漏统计
为什么 SYN_RECV 高 ≠ 一定被攻击
真实场景中,SYN_RECV 堆积更常源于服务端配置失配,而非恶意流量:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 应用层 accept() 调用太慢(如阻塞在日志写入、DB 查询),导致已完成三次握手的连接卡在全连接队列,进而压满半连接队列
-
tcp_max_syn_backlog小于实际并发建连速率(例如设为 1024,但每秒有 2000+ 新连接进来) -
somaxconn小于应用 listen() 时传入的backlog参数,内核会默默截断,但应用无感知 - 未开启
tcp_syncookies=1,面对突发流量无法动态缓解
三个关键内核参数怎么调才不翻车
这三个值必须协同调整,单独改一个几乎没用:
-
net.core.somaxconn:系统级最大全连接队列长度,建议统一设为65535(需配合应用 listen() 的 backlog 参数 ≥ 此值) -
net.ipv4.tcp_max_syn_backlog:半连接队列上限,应 ≥somaxconn,生产环境常见设为65535或10240 -
net.ipv4.tcp_syncookies=1:必须开。它让内核在半连接队列满时,用加密 cookie 代替队列存储,避免丢包;仅影响新建连接,不影响已建立连接 - 切忌把
tcp_abort_on_overflow设为 1 —— 它会让内核在全连接队列满时直接发 RST 给客户端,导致客户端看到“Connection refused”,但其实第三次握手已完成,行为极难排查
查完半连接数后下一步做什么
数值本身只是入口,关键要定位根因:
- 如果
ss -tn state syn-recv | wc -l突然从个位数跳到几百,立刻检查ss -tn state established | wc -l是否同步暴涨——若没有,大概率是攻击或客户端异常重试 - 若 SYN_RECV 高且 ESTABLISHED 增长缓慢,用
perf record -e syscalls:sys_enter_accept -a sleep 10看 accept 系统调用是否卡顿 - 确认应用监听代码里
listen(sockfd, backlog)的backlog值,它不能超过somaxconn,否则会被静默截断










