什么情况下会把 SYN 包丢弃?

什么情况下会把 SYN 包丢弃?(超详细解析)

👤 作者:凡间的八戒

🏷 标签: 计算机网络 / TCP / 传输层 / Linux 内核 / 网络协议

💬 一句话导读: 本文从内核参数、NAT 环境、队列溢出以及 SYN 攻击四个角度,彻底解析为什么服务端会丢弃 SYN 包。


🧭 一、背景

在学习 TCP 协议(三次握手、连接维护和关闭)时,遇到了一个常见但很容易忽视的问题:

在什么情况下服务器会直接丢掉客户端的 SYN 包?

SYN 是建立 TCP 连接的第一步,丢失后会导致:

  • 连接建立失败
  • 服务偶尔无法访问
  • NAT 环境下间歇性掉线
  • 线上系统莫名"抽风"

为了彻底理解这一问题,我写下了本篇博客,用最清晰的结构帮你搞懂 SYN 丢弃背后的真正原因。


🧩 二、SYN 包会被丢弃的三大典型情况

下面我按照出现概率 + 隐蔽性,从最容易造成线上事故的情况开始讲起。


Ⅰ. 开启 tcp_tw_recycle + 开启 tcp_timestamps + 客户端在 NAT 后面(最隐蔽的元凶)

这是网络领域最著名的坑,甚至坑到 Linux 官方直接把 tcp_tw_recycle 彻底删除。


🔹 1.1 tcp_tw_recycle 是什么?

它的作用是:

加速 TIME_WAIT 状态的回收,让来自同一客户端 IP 的连接能更快复用端口。

但问题是,它依赖于客户端 时间戳 monotonic(单调递增)


🔹 1.2 tcp_timestamps 的作用

时间戳用于:

  • 判断报文是否过期
  • 分辨乱序报
  • 作为可靠性提升机制

但时间戳会循环(32 位数字),并不绝对可靠。


🔹 1.3 NAT 环境会引发必现致命问题

NAT 的所有客户端 共享一个出口 IP

但每个客户端时间戳不同!

于是:

  1. A 客户端通过 NAT 上网
  2. A 的 TCP 时间戳被服务端记录
  3. B 客户端发送 SYN
  4. B 的时间戳 < A 的时间戳
  5. 服务端认为报文过期
  6. B 的 SYN 被直接丢弃

所以:

NAT + recycle = 必乱套

这也是为什么 Linux 内核从 4.12 起删除了 tcp_tw_recycle


Ⅱ. 连接队列(半连接 / 全连接)满了,也会丢 SYN

握手队列分两种:

队列 状态 描述
半连接队列 SYN_RCVD 三次握手未完成的连接
全连接队列 ESTABLISHED 等待应用层 accept()

🔸 2.1 半连接队列满(SYN 队列)

当客户端没发送第三次握手(ACK):

  • TCP 会把连接放在半连接队列
  • 队列满 → 新的 SYN 会被丢掉

常见原因:

  • 客户端延迟大
  • 防火墙丢 ACK
  • SYN Flood 攻击

🔸 2.2 全连接队列满(accept 队列)

当握手完成后,如果服务器应用层太慢:

  • accept() 没及时取走连接
  • 队列填满

结果:

新的连接无法进入 → SYN 可能被丢或者延迟处理

典型场景:

  • Web 服务处理阻塞
  • 日志写入太慢
  • 单线程应用卡顿

Ⅲ. 遭受 SYN Flood,但未开启 syn cookies

SYN Flood 的特点:

  • 伪造源地址
  • 不发送第三次握手 ACK
  • 半连接队列瞬间堆满

如果没启用 syn cookies:

➡ 正常用户的 SYN 也会被丢弃。


🔹 开启 syn cookies 后情况不同

队列满时:

  • 内核不占队列
  • 直接根据 Cookie 算法生成 SYN+ACK
  • 客户端回 ACK 后才建立连接

因此:

syn cookies 是服务器抵御 SYN Flood 的关键手段。


📝 三、总结:SYN 包被丢弃的四大原因

序号 原因 场景说明
1 tcp_tw_recycle + NAT 最隐蔽,最容易引发线上事故
2 半连接队列满 网络慢、ACK 丢失、攻击导致
3 全连接队列满 应用层 accept 太慢
4 SYN Flood 未开启 cookies 队列耗尽

🛠 四、生产环境推荐配置

复制代码
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_syncookies = 1

🛑 务必关闭 tcp_tw_recycle

🛑 新内核已移除此参数,千万不要再用


💡 五、个人学习总结

写完这篇文章,我对 TCP 三次握手背后的机制、内核参数影响、NAT 行为的冲突有了更深刻理解。

尤其是:

  • tcp_tw_recycle 为什么会造成线上随机掉线
  • SYN 队列与 accept 队列的真正差别
  • 为什么 SYN Flood 不开启 syn cookies 会全线瘫痪

这些知识在课程学习、项目开发、甚至未来运维网络系统时都有重大价值。

相关推荐
10WTW011 天前
NTP协议
网络协议·计算机网络·ntp·ntp协议
多巴胺梦想家3 天前
计算机系统概述
计算机网络
AI人工智能+电脑小能手3 天前
【大白话说Java面试题 第210题】【10_网络协议篇】第1题:说说 TCP/IP 网络五层模型
java·网络协议·tcp/ip·计算机网络·网络五层模型
一条泥憨鱼3 天前
【从0开始学习计算机网络】| HTTP方法疑点解析
开发语言·计算机网络·http
一条泥憨鱼3 天前
【从0开始学习计算机网络】| RESTful API 设计原则
计算机网络·http·restful api
纵有疾風起4 天前
计算机网络的性能指标体系:带宽、时延、吞吐量
计算机网络·rtt·408·带宽·性能指标·吞吐量·时延
纵有疾風起4 天前
从OSI到TCP/IP——分层架构的思想根源与模型之争
tcp/ip·计算机网络·架构·osi·408·体系结构·分层
游戏开发爱好者84 天前
TraceEagle 代理抓包详解,无感代理、去证书绑定与 HTTP/3 解密能力解析
网络协议·计算机网络·网络安全·ios·adb·https·udp
2501_915918415 天前
抓包鹰 抓包会话重放与压力测试,接口回归验证与性能压测的方法
网络协议·计算机网络·网络安全·ios·adb·https·压力测试
一条泥憨鱼5 天前
【从0开始学习计算机网络】| HTTP 状态码
开发语言·网络·网络协议·计算机网络·http