
当 Linux 服务器上出现大量 SYN_RECV 连接时,说明系统已经收到客户端的 SYN 请求并返回了 SYN-ACK,但三次握手还没有完成。少量、短暂的 SYN_RECV 属于正常现象;如果数量持续上升,并伴随新连接超时、网站偶发打不开、反向代理报错或监听队列溢出,就需要检查流量突增、链路丢包、应用处理能力和 SYN Flood 等问题。
本文给出一套低风险排查顺序:先确认现象和影响范围,再定位来源与监听端口,随后检查队列溢出、网络回程和应用负载,最后才评估内核参数。不要看到 SYN_RECV 多就直接扩大队列或封禁 IP。
SYN_RECV是什么意思?
TCP 服务端收到 SYN 后,会返回 SYN-ACK,并暂时保存这次未完成连接的状态。此时连接通常显示为 SYN_RECV。只有服务端收到客户端最后一个 ACK,连接才会进入 ESTABLISHED。
SYN_RECV 多并不自动等于服务器遭到攻击。常见原因包括正常业务流量短时增加、客户端网络质量差、防火墙或负载均衡回程异常、应用接受连接过慢,以及大量伪造源地址的 SYN 请求。
第一步:确认SYN_RECV是否真的异常
先看 TCP 状态摘要,再查看并统计处于该状态的连接:
ss -s ss -tan state syn-recv ss -Htan state syn-recv | wc -l
可以连续观察数量变化:
watch -n 2 'ss -Htan state syn-recv | wc -l'
同时检查网站或 API 是否出现连接超时、502/504、握手失败或延迟升高。如果连接数只在流量高峰短暂上升,随后迅速下降,而且业务没有报错,通常不必立即修改内核参数。
第二步:定位端口和来源地址
使用下面的命令查看详细连接和监听进程:
ss -Htan state syn-recv ss -lntp
如果连接集中在 80、443 或某个 API 端口,应继续核对该端口对应的 Nginx、HAProxy、应用进程或容器。下面的命令可粗略统计对端地址;不同发行版的输出及 IPv6 格式可能不同,执行后要先抽样核对:
ss -Htan state syn-recv | awk '{print $5}' | sed 's/:[^:]*$//' | sort | uniq -c | sort -nr | head来源分散、请求速率很高且客户端长期不完成握手时,攻击或扫描的可能性会上升。如果来源集中在可信负载均衡器、代理或 NAT 出口,则不能直接封禁出口 IP,而应检查上游设备和真实客户端日志。
第三步:检查监听队列是否溢出
SYN_RECV 与半连接队列有关,但队列是否成为瓶颈,不能只靠连接数量判断。可以查看监听溢出、丢弃和 SYN cookies 相关计数:
nstat -az | grep -E 'ListenOverflows|ListenDrops|Syncookies' netstat -s | grep -i -E 'listen|overflow|drop|syn'
如果 ListenOverflows 或 ListenDrops 在业务高峰持续增加,应同时检查应用监听 backlog、工作进程是否阻塞、CPU 与内存、文件描述符、容器限制,以及负载均衡健康检查是否反复创建短连接。
应用传给 listen() 的 backlog、内核上限和程序接受连接的速度会共同影响结果。只调高一个 sysctl,不一定能解决应用处理能力不足的问题。
第四步:排查丢包、回程和中间设备
服务端已经返回 SYN-ACK,但客户端最后的 ACK 没回来,也可能是网络问题。建议检查安全组、防火墙和 ACL 的双向规则,负载均衡或 NAT 的连接上限,多出口环境中的非对称路由,以及网卡丢包、MTU 和跨区域链路抖动。
得到授权并注意隐私后,可以短时间抓取目标端口的握手包:
tcpdump -nn -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0 and port 443'
抓包可能包含客户端 IP 和业务元数据,应限制时间、接口、端口与文件权限,排查完成后妥善清理。
第五步:核对关键内核参数
先读取当前值,不要立即修改:
sysctl net.core.somaxconn sysctl net.ipv4.tcp_max_syn_backlog sysctl net.ipv4.tcp_syncookies
net.core.somaxconn
somaxconn 是监听队列 backlog 的系统上限之一。应用请求的 backlog 高于该值时,会受到内核上限约束。它主要关系到已完成握手、等待应用接受的连接队列,不能简单当成所有 SYN_RECV 的万能修复参数。
net.ipv4.tcp_max_syn_backlog
该参数控制每个监听套接字可保留的、尚未完成握手的连接请求上限。提高它可能缓解合法突发流量下的半连接队列压力,但会增加资源占用,也无法解决链路丢包、应用过载或持续攻击。
net.ipv4.tcp_syncookies
SYN cookies 用于在 SYN 队列溢出时维持建立连接的能力。Linux 内核文档提示,它是一种压力或攻击场景下的防护机制,不应被当作解决正常高负载容量不足的方法。若相关计数持续增长,应继续查清队列为什么溢出。
是否应该直接修改sysctl?
不建议根据一张监控截图直接修改。应先记录连接数、溢出计数和业务错误率,确认应用 backlog 与内核上限的关系,在测试环境或低风险时段小幅调整,并保存原值和回滚方法。示例配置应使用经过压测确认的值,而不是复制所谓“通用最佳参数”:
# /etc/sysctl.d/99-syn-backlog.conf net.core.somaxconn = <经过压测确认的值> net.ipv4.tcp_max_syn_backlog = <经过压测确认的值>
合理值取决于内存、并发连接、应用模型、内核版本、流量峰值和攻击面。使用 sysctl --system 加载后,还要核对实际生效结果并观察高峰期指标。
怀疑SYN Flood时怎么处理?
保存监控和短时抓包证据,确认不是正常活动或上游代理。
优先在云防火墙、DDoS 防护或负载均衡层吸收和清洗流量。
使用速率限制、访问控制和区域策略降低无效连接。
检查 SYN cookies 是否在队列压力下发挥作用。
扩容或横向分流合法流量,避免全部连接集中到单台服务器。
持续观察误拦截,尤其是共享 NAT、移动网络和企业代理用户。
不要仅凭“某个 IP 连接多”就永久封禁。一个代理出口可能代表大量正常用户,而伪造源地址的攻击也未必能靠服务器本机封禁解决。
调整后如何验证?
ss -s nstat -az | grep -E 'ListenOverflows|ListenDrops|Syncookies'
重点观察 SYN_RECV 是否从持续堆积变为随流量正常波动,溢出和丢弃计数是否停止快速增长,新连接成功率和延迟是否恢复,以及防护规则是否误伤正常用户。
常见问题
SYN_RECV很多就一定是攻击吗?
不一定。合法流量突增、丢包、非对称路由、负载均衡异常和应用接受连接过慢都可能造成堆积,应结合持续时间、来源分布、握手完成率和队列丢弃计数判断。
SYN_RECV和TIME_WAIT有什么区别?
SYN_RECV 出现在连接建立阶段,表示服务端仍在等待三次握手的最后一个 ACK;TIME_WAIT 出现在连接关闭后,用于避免旧报文干扰后续连接,两者处理方向不同。
把tcp_max_syn_backlog调得越大越好吗?
不是。更大的队列会占用更多资源,也可能只是延后暴露应用过载或攻击问题。参数应通过峰值数据和压测确定,并与应用 backlog、进程能力和上游防护一起调整。
结论
Linux 服务器出现大量 SYN_RECV 时,先确认它是否持续影响业务,再定位端口和来源,检查监听溢出、应用负载、回程链路与中间设备。只有证据指向半连接队列容量不足时,才考虑调整 tcp_max_syn_backlog、somaxconn 等参数。
如果确认是 SYN Flood,应优先在负载均衡、云防火墙或 DDoS 防护层处理,同时保留内核保护。最终判断标准不是连接列表变得“好看”,而是握手成功率恢复、队列不再溢出,并且正常用户没有被误伤。
参考资料
资料核查日期:2026年8月28日。