SYN Cookie 是什么
net.ipv4.tcp_syncookies 是内核面对半连接队列溢出时的兜底机制:不再为每个 SYN 分配队列条目,而是用密钥把连接信息编码进 SYN+ACK 的初始序列号里,等客户端回 ACK 时再解出来重建连接。这样服务端不需要保存任何半连接状态,队列耗尽也不会导致正常新连接被拒。代价是启用 Cookie 的连接无法协商窗口缩放、选择确认等选项,长肥管道上的单连接吞吐会受影响,所以它适合作为应急与兜底,而不是日常依赖的容量方案。
基本信息
| 参数 | net.ipv4.tcp_syncookies |
|---|---|
| 取值 | 0 关闭 / 1 仅在半连接队列满时启用(常见默认) / 2 无条件启用 |
| 依赖 | 内核需编译 CONFIG_SYN_COOKIES 支持,多数发行版内核已开启 |
| 典型日志 | possible SYN flooding on port N,出现在半连接队列溢出时 |
| 计数指标 | TCPExt 中的 SyncookiesSent、SyncookiesRecv、SyncookiesFailed |
| 副作用 | Cookie 生效的连接无法协商部分 TCP 选项,吞吐可能下降 |
典型使用场景
- 公网服务遭受 SYN 泛洪:在没有上游清洗时先保住服务可用性
- 半连接队列被正常高并发填满:短连接风暴时可避免请求被直接丢弃
- 内核日志出现 SYN flooding 告警:结合计数判断是攻击还是容量不足
- 对比验证:确认 Cookie 是否已在真实流量中生效,而不是只看参数值
- 应急演练:验证极端建连压力下服务能否维持基本可用
查看与判断
查看与判断
sysctl net.ipv4.tcp_syncookies # 读当前模式
nstat -az TcpExtSyncookiesSent TcpExtSyncookiesRecv TcpExtSyncookiesFailed # Cookie 使用计数
nstat -az TcpExtTCPReqQFullDoCookies # 因队列满而改用 Cookie 的次数
dmesg -T | grep -i -E 'syn flooding|syncookies' | tail # 内核告警
ss -nt state syn-recv | wc -l # 当时的半连接数量观测指标读法
| 指标 | 含义 | 正常与异常 |
|---|---|---|
| SyncookiesSent | 发出的 Cookie 响应数量 | 长期为 0 说明从未触发,结合溢出计数判断 |
| SyncookiesRecv | 客户端回带 Cookie 的 ACK 数量 | 远小于 Sent 说明多数请求没有真正完成握手 |
| SyncookiesFailed | Cookie 校验失败的数量 | 偏高可能是伪造源地址流量或链路异常 |
| possible SYN flooding 日志 | 内核在半连接溢出时打印 | 反复出现需要核实来源与业务真实建连速率 |
取值 2(无条件启用)会让所有连接都走 Cookie 路径,省掉队列但持续承担选项受限与额外计算开销。除非环境明确要求,一般保持 1,把 Cookie 留给队列真正溢出的时刻。
看到 possible SYN flooding 日志时,处理顺序应当是先确认来源(真实业务高峰、爬虫、扫描还是伪造源地址攻击),再决定做限速、上游清洗还是扩容。把 Cookie 当日常手段会把真实的容量问题掩盖掉。
Cookie 生效的连接缺少窗口缩放等选项,在高延迟链路上单连接吞吐会明显下降。如果业务本身依赖长肥管道的吞吐,应当在流量特征上把这类连接区分出来,评估是否需要在源头做限速而不是依赖兜底。