-
2016-02-01 10:36:32
TCP初始化序列号不能设置为一个固定值,因为这样容易被攻击者猜出后续序列号,从而遭到攻击。
RFC1948中提出了一个较好的初始化序列号ISN随机生成算法。
ISN = M + F(localhost, localport, remotehost, remoteport).
M是一个计时器,这个计时器每隔4毫秒加1。
F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。要保证hash算法不能被外部轻易推算得出,用MD5算法是一个比较好的选择。
更多相关内容 -
为什么 TCP 三次握手期间,客户端和服务端的初始化序列号要求不一样?
2022-01-10 12:07:50为什么 TCP 三次握手期间,客户端和服务端的初始化序列号要求不一样的呢? 接下来,我一步一步给大家讲明白,我觉得应该有不少人会有类似的问题,所以今天在肝一篇! 正文 为什么 TCP 三次握手期间,为什么客户端和...大家好,我是小林。
为什么 TCP 三次握手期间,客户端和服务端的初始化序列号要求不一样的呢?
接下来,我一步一步给大家讲明白,我觉得应该有不少人会有类似的问题,所以今天在肝一篇!
正文
为什么 TCP 三次握手期间,为什么客户端和服务端的初始化序列号要求不一样的呢?
主要原因是为了防止历史报文被下一个相同四元组的连接接收。
TCP 四次挥手中的 TIME_WAIT 状态不是会持续 2 MSL 时长,历史报文不是早就在网络中消失了吗?
是的,如果能正常四次挥手,由于 TIME_WAIT 状态会持续 2 MSL 时长,历史报文会在下一个连接之前就会自然消失。
但是来了,我们并不能保证每次连接都能通过四次挥手来正常关闭连接。
假设每次建立连接,客户端和服务端的初始化序列号都是从 0 开始:
过程如下:
- 客户端和服务端建立一个 TCP 连接,在客户端发送数据包被网络阻塞了,而此时服务端的进程重启了,于是就会发送 RST 报文来断开连接。
- 紧接着,客户端又与服务端建立了与上一个连接相同四元组的连接;
- 在新连接建立完成后,上一个连接中被网络阻塞的数据包正好抵达了服务端,刚好该数据包的序列号正好是在服务端的接收窗口内,所以该数据包会被服务端正常接收,就会造成数据错乱。
可以看到,如果每次建立连接,客户端和服务端的初始化序列号都是一样的话,很容易出现历史报文被下一个相同四元组的连接接收的问题。
客户端和服务端的初始化序列号不一样不是也会发生这样的事情吗?
是的,即使客户端和服务端的初始化序列号不一样,也会存在收到历史报文的可能。
但是我们要清楚一点,历史报文能否被对方接收,还要看该历史报文的序列号是否正好在对方接收窗口内,如果不在就会丢弃,如果在才会接收。
如果每次建立连接客户端和服务端的初始化序列号都「不一样」,就有大概率因为历史报文的序列号「不在」对方接收窗口,从而很大程度上避免了历史报文,比如下图:
相反,如果每次建立连接客户端和服务端的初始化序列号都「一样」,就有大概率遇到历史报文的序列号刚「好在」对方的接收窗口内,从而导致历史报文被新连接成功接收。
所以,每次初始化序列号不一样能够很大程度上避免历史报文被下一个相同四元组的连接接收,注意是很大程度上,并不是完全避免了。
那客户端和服务端的初始化序列号都是随机的,那还是有可能随机成一样的呀?
RFC793 提到初始化序列号 ISN 随机生成算法:ISN = M + F(localhost, localport, remotehost, remoteport)。
- M是一个计时器,这个计时器每隔4毫秒加1。
- F 是一个 Hash 算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值,要保证 hash 算法不能被外部轻易推算得出。
可以看到,随机数是会基于时钟计时器递增的,基本不可能会随机成一样的初始化序列号。
懂了,客户端和服务端初始化序列号都是随机生成的话,就能避免连接接收历史报文了。
是的,但是也不是完全避免了。
为了能更好的理解这个原因,我们先来了解序列号(SEQ)和初始序列号(ISN)。
- 序列号,是 TCP 一个头部字段,标识了 TCP 发送端到 TCP 接收端的数据流的一个字节,因为 TCP 是面向字节流的可靠协议,为了保证消息的顺序性和可靠性,TCP 为每个传输方向上的每个字节都赋予了一个编号,以便于传输成功后确认、丢失后重传以及在接收端保证不会乱序。序列号是一个 32 位的无符号数,因此在到达 4G 之后再循环回到 0。
- 初始序列号,在 TCP 建立连接的时候,客户端和服务端都会各自生成一个初始序列号,它是基于时钟生成的一个随机数,来保证每个连接都拥有不同的初始序列号。初始化序列号可被视为一个 32 位的计数器,该计数器的数值每 4 微秒加 1,循环一次需要 4.55 小时。
给大家抓了一个包,下图中的 Seq 就是序列号,其中红色框住的分别是客户端和服务端各自生成的初始序列号。
图片
通过前面我们知道,序列号和初始化序列号并不是无限递增的,会发生回绕为初始值的情况,这意味着无法根据序列号来判断新老数据。
不要以为序列号的上限值是 4GB,就以为很大,很难发生回绕。在一个速度足够快的网络中传输大量数据时,序列号的回绕时间就会变短。如果序列号回绕的时间极短,我们就会再次面临之前延迟的报文抵达后序列号依然有效的问题。
为了解决这个问题,就需要有 TCP 时间戳。tcp_timestamps 参数是默认开启的,开启了 tcp_timestamps 参数,TCP 头部就会使用时间戳选项,它有两个好处,一个是便于精确计算 RTT ,另一个是能防止序列号回绕(PAWS)。
试看下面的示例,假设 TCP 的发送窗口是 1 GB,并且使用了时间戳选项,发送方会为每个 TCP 报文分配时间戳数值,我们假设每个报文时间加 1,然后使用这个连接传输一个 6GB 大小的数据流。
32 位的序列号在时刻 D 和 E 之间回绕。假设在时刻B有一个报文丢失并被重传,又假设这个报文段在网络上绕了远路并在时刻 F 重新出现。如果 TCP 无法识别这个绕回的报文,那么数据完整性就会遭到破坏。
使用时间戳选项能够有效的防止上述问题,如果丢失的报文会在时刻 F 重新出现,由于它的时间戳为 2,小于最近的有效时间戳(5 或 6),因此防回绕序列号算法(PAWS)会将其丢弃。
防回绕序列号算法要求连接双方维护最近一次收到的数据包的时间戳(Recent TSval),每收到一个新数据包都会读取数据包中的时间戳值跟 Recent TSval 值做比较,如果发现收到的数据包中时间戳不是递增的,则表示该数据包是过期的,就会直接丢弃这个数据包。
懂了,客户端和服务端的初始化序列号都是随机生成,能很大程度上避免历史报文被下一个相同四元组的连接接收,然后又引入时间戳的机制,从而完全避免了历史报文被接收的问题。
嗯嗯,没错。
-
20-1-tcp连接——初始化序列号(ISN)
2018-06-02 22:15:141. 为什么要初始化序列号(ISN) 在前面学习tcp连接三次握手的时候,客户端和服务端在建立tcp连接时,双方都会发送SYN报文并初始化序号(ISN)。大家不妨先思考一下:为什么要在建立tcp连接时初始化序列号?...1. 为什么要初始化序列号(ISN)
在前面学习tcp连接三次握手的时候,客户端和服务端在建立tcp连接时,双方都会发送SYN报文并初始化序号(英文为:Initial Sequence Number,简称ISN)。大家不妨先思考一下:为什么要在建立tcp连接时初始化序列号?如果双方在建立tcp连接时使用相同的序号又会有什么问题?
2. 使用固定序列号的问题
带着这几个问题,我们通过这个例子来看一下在tcp连接建立时使用相同序号的情况,如下图所示:
1. 假设现在A和B使用固定的序号,A使用序号1和B建立tcp连接,发送一个SYN报文,SEQ = 1,经过三次握手后A和B之间就建立tcp连接完成。
2. 当A和B建立完tcp连接后,然后A又使用相同的序号1向B发送了200字节数据,不过因为网络拥塞问题,这个tcp数据报一直在网络中逗留,并没有立即到达B。
3. 由于A发送的tcp数据报一直没到达B,正好此时A发生故障并重启,于是B就释放这条tcp连接了。
4. 然后A重启后又使用序号1和B建立新的tcp连接。
5. 当tcp连接建立完成后,A又使用序号1向B发送了240字节的数据,不过这次网络很稳定,B马上就收到A发送的这240字节的数据,注意:此时A发送数据是使用的新的tcp连接。
6. 然后A之前发送的tcp数据报(200字节)经过一段时间后,终于到达B。不过这个tcp数据报是属于之前已经释放的旧的tcp连接,按理来说,B应该把这个数据报丢弃掉才是。但是由于A每次发送报文都使用了相同的序号(SEQ = 1),这可能会让B误认为这200字节是属于新建立的tcp连接的,因此B会对这200字节数据照收不误。这就导致B在收到新tcp连接的数据后,又收到旧tcp连接的数据,从而出现数据乱序的问题。
3. 初始化序列号的目的
由于A和B之间的一个tcp连接通常是由A和B的2个ip地址,2个端口号构成的四元组,因此当A出现了故障把这个tcp连接断开了,之后再以相同的四元组建立新的tcp连接(也就是说A和B两次建立tcp连接都是使用了相同的ip地址和端口),就会出现数据乱序的问题。
换句话说,只要A发送了一个tcp报文段,且这个tcp报文段的四元组和序号,和之前的tcp连接(四元组和序号)相同的话,就会被B确认。这其实反映了tcp的一些缺点,如果被一些恶意攻击者加以利用tcp的这种缺点:选择合适的序号,ip地址和端口的话,就能伪造出一个tcp报文段,从而打断正常的tcp连接。但是初始化序号的方式(通过算法来随机生成序号)就会使序号难以猜出,也就不容易利用这种缺点来进行一些恶意攻击行为。
通过上面所述我们知道,如果A和B之间发送数据每次都使用相同序号的话可能会引发一系列的问题,但是使用不同序号的话,那么B在接收到这个序号为1的tcp报文时,发现这个tcp报文的序号不在新tcp连接的接收范围内时会把这个tcp报文丢弃掉,也就避免了数据乱序的问题。
因此我们可以明白,
客户端和服务端双方在建立tcp连接并初始化序列号,那么上面所说的这些情况从一开始就可以避免
。另外,tcp在初始化序列号的过程也是比较复杂的,一般来说,这个序号的范围是0 — 2 32 − 1 2^{32} - 1 232−1之间,而且序号的生成也是随机的,通常是一个很大的数值,也就是说每个tcp连接使用的序号也是不一样的。
序号(ISN)在tcp中是非常重要的,学好tcp的第一步就是先把序号(ISN)搞懂。
-
为什么 TCP 每次建立连接时,初始化序列号都要不一样呢?
2022-04-24 11:03:45为什么 TCP 每次建立连接时,初始化序列号都要不一样呢? 主要原因是为了防止历史报文被下一个相同四元组的连接接收。 TCP 四次挥手中的 TIME_WAIT 状态不是会持续 2 MSL 时长,历史报文不是早就在网络中消失了...为什么 TCP 每次建立连接时,初始化序列号都要不一样呢?
主要原因是为了防止历史报文被下一个相同四元组的连接接收。
TCP 四次挥手中的 TIME_WAIT 状态不是会持续 2 MSL 时长,历史报文不是早就在网络中消失了吗?
是的,如果能正常四次挥手,由于 TIME_WAIT 状态会持续 2 MSL 时长,历史报文会在下一个连接之前就会自然消失。
但是来了,我们并不能保证每次连接都能通过四次挥手来正常关闭连接。
假设每次建立连接,客户端和服务端的初始化序列号都是从 0 开始:
过程如下:
- 客户端和服务端建立一个 TCP 连接,在客户端发送数据包被网络阻塞了,而此时服务端的进程重启了,于是就会发送 RST 报文来断开连接。
- 紧接着,客户端又与服务端建立了与上一个连接相同四元组的连接;
- 在新连接建立完成后,上一个连接中被网络阻塞的数据包正好抵达了服务端,刚好该数据包的序列号正好是在服务端的接收窗口内,所以该数据包会被服务端正常接收,就会造成数据错乱。
客户端和服务端的初始化序列号不一样不是也会发生这样的事情吗?
是的,即使客户端和服务端的初始化序列号不一样,也会存在收到历史报文的可能。
但是我们要清楚一点,历史报文能否被对方接收,还要看该历史报文的序列号是否正好在对方接收窗口内,如果不在就会丢弃,如果在才会接收。
如果每次建立连接客户端和服务端的初始化序列号都「不一样」,就有大概率因为历史报文的序列号「不在」对方接收窗口,从而很大程度上避免了历史报文,比如下图:
-
为什么TCP建立连接要求发送方和接收方的初始化序列号不一样的呢?
2022-01-04 16:11:10就是他不明白「序列号解决了数据包的缺失和顺序颠倒等问题,但为什么要求发送方和接收方的初始序列号不一样?」 后来,我跟他交流半个小时,终于把他讲明白了。 我觉得应该有不少人会有以下的问题。 1.为什么... -
面试官:为什么 TCP 三次握手期间,客户端和服务端的初始化序列号要求不一样?...
2022-01-12 11:52:01为什么 TCP 三次握手期间,客户端和服务端的初始化序列号要求不一样的呢? 接下来,我一步一步给大家讲明白,我觉得应该有不少人会有类似的问题,所以今天在肝一篇! 正文 为什么 TCP 三次握手期间,为什么客户端和... -
TCP三次握手期间,为啥客户端和服务端的初始化序列号要求不一样
2022-01-10 21:53:33就是他不明白「为什么 TCP 三次握手期间,为什么客户端和服务端的初始化序列号要求不一样的呢?」 我的图解网络 PDF 在解释这个原因的时候,就写的几句话,可能会让人看得很懵逼。 后来,我跟他交流半个小时,终于... -
TCP初始序列号ISN
2021-01-31 18:01:13ISN:初始化序列号(initial sequence number),是在建立tcp三次握手的时候,存储在TCP头部的序列号位置中的数字的代称。也就是说,告诉对方我将要开始发送的初始化序列号是多少,两边都要发这个ISN,即tcp三次握手... -
TCP/IP卷一:65---TCP连接管理之(TCP连接的建立与终止、TCP半关闭、同时打开/同时关闭、初始化序列号、连接...
2020-01-18 13:40:51一个TCP连接通常分为3个阶段:启动、数据...1.主动开启者(通常称为客户端)发送一个SYN报文段(即一个在TCP头部的SYN位字段置位的TCP/IP数据包),并指明自己想要连接的端口号和它的客户端初始序列号(记为ISN(c)... -
TCP初始化序列号ISN的程序实现
2015-03-24 22:00:42RFC1948中提出了一个较好的初始化序列号ISN随机生成算法,简单描述就是: ISN = C +H(sourceIP, sourcePort, destIP, destPort) H中的4个参数分别是:源IP,源端口号,目的IP,目的端口号。 闲话少说,看代码。 #... -
TCP进行通信时的初始序列号为什么是随机的
2020-12-21 16:07:41TCP在开始传输数据前,客户端和服务器需要随机生成自己的初始序列号(initial sequence number-ISN),然后通过三次握手进行交换确认。 问题:为什么ISN是随机的? 考虑场景,B是服务器,A是一个合法的客户端,C假冒... -
为什么TCP的初始序列号ISN是随机生成的?
2020-09-11 17:42:57ISN随机生成算法 RFC1948中提出了一个较好的初始化序列号ISN随机生成算法: ISN = M + F(localhost, localport, remotehost, remoteport). 其中: M是一个计时器,这个计时器每隔4毫秒加1。 F是一个Hash算法,根据... -
TCP的ISN为什么不能固定?
2021-08-16 15:34:02初始化序列号(initial sequence number),是在建立tcp三次握手的时候,存储在TCP头部的序列号位置中的数字的代称。也就是说,告诉对方我将要开始发送的初始化序列号是多少,两边都要发这个ISN,即tcp三次握手中第... -
深思及各种加密狗初始化及写入工具。
2019-04-22 17:22:02一般用于正版软件和数据的外接加密硬件,形状和普通的U盘差不多,应用的时把他插在USB接口上,他的作用就是如果要运行这种带加密狗的软件,就必须要把加密狗插到电脑上 , 说白了 就是软件密钥 接码器 -
TCP初始序列号
2020-03-04 21:30:05TCP客户端首次发起连接,在函数tcp_v4_connect中,调用secure_tcp_seq函数初始化其ISN序号,在稍后一节进行介绍。 int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) {... -
TCP协议中的序列号
2017-10-16 10:29:00响应包内也包括一个序列号,表示接收方准备好这个序列号的包。在TCP传送一个数据包时,它会把这个数据包放入重发队列中,同时启动计时器,如果收到了关于这个包的确认信息,便将此数据包从队列中删除,如果在计时器... -
简述TCP协议的三次握手过程,以及序列号和确认号的作用
2020-10-19 20:13:20简述TCP协议的三次握手过程,以及序列号和确认号的作用 A与B建立TCP连接时:首先A向B发SYN,然后B回复SYN+ACK,最后A回复ACK确认,这样TCP的一次三次握手的过程就完成了。 TCP协议中序列号和确认号的作用 序列号即,... -
5个ic、id的初始化加密工具
2014-10-05 21:15:141.IC序号读卡接口 不需要专门的写程序就可以读出M1卡的序列号出来,可以当作条码来使用,某些场合下可以当作接口来... 也是用来批量初始化SLE4442卡的序列号和密码,出厂时使用!卡号10位,初始化后5位卡号自动增加 -
Spring项目启动时执行初始化方法
2021-03-05 12:48:34spring 在web容器启动时执行初始化方法 开发框架:spingMVC+myBatis 解决方案:给web容器添加一个Listener类,在容器启动的时候执行Listener的“初始化”方法,在这个初始化方法中执行查询数据库的所有操作,然后将数 ..... -
易语言读取windows序列号
2020-07-15 21:16:21易语言读取windows序列号源码,读取windows序列号,写表头,我的_取编辑框文本,Sql查询子程序,处理表格数据1,高级表格初始化子程序,数据库连接初始化,sql查询子程序2,查询子程序2,Sql模糊查询子程序,分割文本子程序1,... -
Oracle报错:ORACEL12C ORA-01033: ORACLE 正在初始化或关闭 进程 ID: 0 会话 ID: 0 序列号: 0
2020-12-22 19:03:27ORACEL12C ORA-01033: ORACLE 正在初始化或关闭 进程 ID: 0 会话 ID: 0 序列号: 0 问题分析: Oracle重启后未指定数据库 问题解决: 重新指定数据库 SQL> alter session set container=AWASOPPDB; SQL> ... -
宝利通polycom-group500、group550初始化配置手册.doc
2022-04-17 01:50:47宝利通polycom-group500、group550初始化配置手册.doc -
RAID5阵列掉盘显示未初始化---解决过程
2021-12-13 18:48:51RAID5阵列掉盘显示未初始化---解决过程 -
TCP为什么采用随机初始序列号
2019-03-23 14:26:03在TCP的三次握手中,采用随机产生的初始化序列号进行请求,这样做主要是出于网络安全的因素着想。如果不是随机产生初始序列号,黑客将会以很容易的方式获取到你与其他主机之间通信的初始化序列号,并且伪造序列号... -
为什么三次握手才可以初始化Socket、序列号和窗口大小并建立 TCP 连接。
2020-06-04 13:28:07三次握手才可以阻止历史重复连接的初始化(主要原因) 三次握手才可以同步双方的初始序列号,MSS,窗口大小等 三次握手才可以避免资源浪费 -
金蝶K3系统初始化流程
2013-03-25 22:20:02金蝶K3系统初始化流程,如何初始化流程 -
IC卡ID卡读序列号和初使化小工具
2011-11-11 16:38:12明华系列IC卡ID卡读写器读取序列号、密码初始化的小工具。