TCP 的 初始序列号(ISN) 并非简单从 0
开始,而是经过精心设计的安全策略。其取值机制经历了从时间依赖到加密随机化的演变,核心目标是解决两大问题: 1. 防止历史连接冲突 2. 抵御序列号预测攻击
一、ISN 的核心设计原则
原则 | 原因 | 违反后果 |
---|---|---|
全局唯一性 | 避免同一四元组的旧数据包干扰新连接 | 数据错乱(旧包被误认属于新连接) |
不可预测性 | 防止攻击者伪造 RST 包或注入恶意数据(需猜中序列号) | 连接劫持、拒绝服务 |
均匀分布 | 减少序列号快速回绕(wrap-around)的风险 | 数据混淆 |
二、ISN 取值演进史
1. 早期实现(RFC 793):时间依赖算法
ISN = (每秒递增的计数器) × 常数 + 固定偏移
-
计数器:通常基于系统启动后的毫秒/微秒数
-
常数:如 125,000(对应 2GB/4.55 小时回绕)
-
问题:攻击者可估算服务器时间 → 预测 ISN(如 1985 年 Morris 攻击)
2. 现代实现(Linux 为例):加密哈希 + 随机化
c
ISN = F(local_ip, local_port, remote_ip, remote_port, secret_key) + 计数器
-
输入参数:四元组 + 密钥(定期刷新)
-
哈希函数:SipHash(轻量级加密哈希)
-
计数器:每 4μs 递增 1(避免短时间重复)
三、Linux 内核实现解析(源码级逻辑)
文件:net/ipv4/tcp_ipv4.c
u32 tcp_v4_init_seq(const struct sk_buff *skb) { return secure_tcp_seq(ip_hdr(skb)->daddr, // 目的IP ip_hdr(skb)->saddr, // 源IP tcp_hdr(skb)->dest, // 目的端口 tcp_hdr(skb)->source);// 源端口 } u32 secure_tcp_seq(__be32 daddr, __be32 saddr, __be16 dport, __be16 sport) { u32 hash; net_secret_init(); // 初始化密钥(系统启动时生成) hash = siphash_3u32((__force u32)daddr, (__force u32)saddr, (__force u32)dport << 16 | (__force u32)sport, &net_secret); // 使用SipHash加密 return hash + (ktime_get_real_ns() >> 6); // 叠加纳秒时间戳(每64ns递增1) }
📌 关键步骤:
密钥管理:
net_secret
在系统启动时生成(/proc/sys/kernel/random/boot_id
参与)哈希计算:用 SipHash 加密四元组,确保相同连接 ISN 一致
时间扰动:添加纳秒计数器防止短时间冲突
四、为什么需要如此复杂?
场景1:防止历史连接冲突
-
问题:客户端用相同四元组快速重建连接,旧连接的延迟包可能干扰新连接。
-
解决:新连接 ISN 必须显著大于旧连接的序列号范围(通过时间戳递增保证)。
场景2:抵御序列号预测攻击
-
攻击步骤:
-
攻击者嗅探客户端四元组
-
伪造合法序列号的
RST
包中断连接
-
-
解决:加密哈希使 ISN 无法被预测(不知密钥无法计算)。
五、ISN 与序列号回绕(Wrap-Around)
-
序列号空间:32 位(0~4294967295)
-
回绕时间:
理论最小时长 = 序列号空间 / 带宽速度
-
1 Gbps 网络:约 34 秒(
2^32 × 8 bits / 10^9 bps ≈ 34.3s
) -
防御措施:PAWS(Protect Against Wrapped Sequences)
-
使用 TCP 时间戳选项(
TCP Timestamps
) -
比较时间戳区分新旧数据包
-
-
六、抓包验证:ISN 的随机性
Wireshark 中右键序列号 → "Protocol Preferences" → 取消勾选 "Relative Sequence Numbers": https://i.imgur.com/8wGXfTp.png
-
真实 ISN 为极大随机数(如 3819098328)
-
显示值
Seq=0
是 Wireshark 简化显示的相对序列号
七、各操作系统实现差异
系统 | ISN 生成策略 | 安全等级 |
---|---|---|
Linux | SipHash(四元组 + 密钥) + 时间戳 | 高(防预测) |
Windows | CryptGenRandom()(密码学安全随机数) | 高 |
FreeBSD | arc4random()(基于 ChaCha20 算法的随机数) | 高 |
遗留设备 | 时间递增算法 | 低(易受攻击) |
⚠️ 警告:老式嵌入式设备可能仍使用简单时间算法(需升级固件)!
总结
-
ISN 使命:
-
唯一性 → 避免旧包干扰
-
随机性 → 抵御网络攻击
-
-
现代实现:
-
加密哈希绑定四元组(确保相同连接的 ISN 一致)
-
叠加时间戳/计数器(避免冲突)
-
密钥动态生成(增加预测难度)
-
-
协议设计智慧:
ISN 的复杂性是互联网安全的基石之一 —— 看似简单的随机数背后,是数十年对抗网络攻击的积累。