TCP 安全与攻击防御
TCP 层攻击面
TCP 的设计年代(1981 年 RFC 793)互联网还是学术网络,安全不是首要考虑。现代 TCP 实现需要防御多种攻击:
SYN Flood 与 SYN Cookie
攻击原理
攻击者伪造大量源 IP,发送 SYN 但不回复 ACK,占满服务端半连接队列:
防御:SYN Cookie(RFC 4987)
服务端收到 SYN 后不分配 TCB,而是计算 Cookie 放入 SYN-ACK 的序列号:
Cookie = Hash(客户端IP, 客户端端口, 服务端IP, 服务端端口, 时间戳, 秘密密钥)
合法客户端回复 ACK(Ack = Cookie + 1),服务端验证 Cookie 后才分配 TCB。
# Linux 开启 SYN Cookie
sysctl net.ipv4.tcp_syncookies=1
注意:SYN Cookie 有副作用:
- 不支持 TCP 选项(如 Window Scale、SACK)的协商
- 高负载时可能降低性能
序列号预测与连接劫持
攻击原理
如果 ISN 可预测,攻击者可以:
- 嗅探到客户端与服务端的连接
- 预测下一个 ACK 的序列号
- 伪造报文注入数据或 RST 切断连接
防御:ISN 随机化
现代操作系统使用强随机化策略:
- Linux:基于密钥的伪随机生成器
- 每个新连接使用不同 ISN
- 增加 32 位秘密密钥,使预测计算上不可行
# Linux ISN 生成方式(不可调,内核自动处理)
# 旧版本可能使用较弱算法,建议保持内核更新
RST 攻击
攻击者伪造 RST 报文切断连接:
防御:
- 现代系统要求 RST 的序列号落在接收窗口内才处理
- 窗口外的 RST 被静默丢弃
- 结合 ISN 随机化,攻击者难以构造有效序列号
TCP MD5 签名与 TCP-AO
BGP 等关键协议使用 TCP 连接,需要防止中间人篡改。
TCP MD5(RFC 2385,已废弃)
在 TCP 选项中加入 MD5 签名,验证报文完整性。但 MD5 已被破解,不再安全。
TCP-AO(TCP Authentication Option,RFC 5925)
替代 TCP MD5,使用更安全的 HMAC 算法(如 SHA-1、AES)。
# Linux 支持 TCP_MD5SIG(用于 BGP 等)
setsockopt(sockfd, TCP_MD5SIG, ...)
TIME_WAIT 与端口耗尽攻击
攻击者快速建立并关闭大量连接,让服务端进入大量 TIME_WAIT,耗尽端口:
# 攻击者脚本(示意)
for i in {1..65535}; do
nc target_ip target_port &
done
防御:
tcp_tw_reuse=1:允许复用 TIME_WAIT 连接- 限制单 IP 连接数(iptables connlimit)
- 应用层限流(Rate Limiting)
本篇小结
- SYN Flood:伪造 SYN 占满半连接队列,用 SYN Cookie 防御
- 序列号预测:ISN 随机化,现代系统已免疫
- RST 攻击:伪造 RST 切断连接,窗口检查 + ISN 随机化防御
- TCP-AO:替代 TCP MD5,为关键连接提供认证
- TIME_WAIT 攻击:快速建连拆连耗尽端口,用 reuse + 限流防御
动手实践
查看 SYN Cookie 是否开启:
sysctl net.ipv4.tcp_syncookies用 hping3 模拟 SYN Flood(测试环境!):
sudo hping3 -S -p 80 --flood --rand-source target_ip观察半连接队列状态:
watch -n 1 'ss -tan | grep SYN-RECV | wc -l'思考:为什么 SYN Cookie 不支持 TCP 选项协商?如果客户端在 SYN 中请求 Window Scale,服务端用 SYN Cookie 回复,后续连接会怎样?