本文主要是介绍linux内核tcp syn seq读取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一 书上讲tcp 连接初始seq是随机取的,这里分析一下流程。
二 代码流程梳理
want_cookie 不在本文讨论范围,洪泛攻击的情况这里就不做分析了。
linux内核通过tcp_conn_request 完成握手动作。
初始syn的seq分为两种情况。
2.1 复用之前的timewait端口连接的最后一次的序列号。
__u32 isn = TCP_SKB_CB(skb)->tcp_tw_isn;
这样在接受连接一端,就会判断seq是符合递增的逻辑的,不会拒绝这次syn请求。
2.2 之前没有过连接的端口
isn = af_ops->init_seq(skb);
.init_seq = tcp_v4_init_seq,
分析一下tcp_v4_init_seq 函数。
static u32 tcp_v4_init_seq(const struct sk_buff *skb)
{
return secure_tcp_seq(ip_hdr(skb)->daddr,
ip_hdr(skb)->saddr,
tcp_hdr(skb)->dest,
tcp_hdr(skb)->source);
}
tcp_v4_init_seq 参数是链接四元组
u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
__be16 sport, __be16 dport)
{
u32 hash;
net_secret_init(); // 获取随机数,用随机数生成密钥,存入net_secret
hash = siphash_3u32((__force u32)saddr, (__force u32)daddr,
(__force u32)sport << 16 | (__force u32)dport,
&net_secret);//全局变量 net_secret
//通过net_secret 得到一个hash值
return seq_scale(hash);
}
static u32 seq_scale(u32 seq)
{
/*
* As close as possible to RFC 793, which
* suggests using a 250 kHz clock.
* Further reading shows this assumes 2 Mb/s networks.
* For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
* For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
* we also need to limit the resolution so that the u32 seq
* overlaps less than one time per MSL (2 minutes).
* Choosing a clock of 64 ns period is OK. (period of 274 s)
*/
return seq + (ktime_get_real_ns() >> 6);
}
尽可能接近RFC 793
*建议使用250 kHz时钟。
*进一步的阅读表明,这是假设2 Mb/s的网络。
*对于10 Mb/s以太网,1 MHz时钟是合适的。
*对于10 Gb/s以太网,1 GHz时钟应该可以,但是
*我们还需要限制分辨率,以便u32-seq
*每个MSL重叠少于一次(2分钟)。
*选择64 ns周期的时钟是可以的。(274 s周期)
通过上面的seq_scale 生成最终的随机数seq
这篇关于linux内核tcp syn seq读取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!