初始化序列号(initial sequence number),是在建立tcp三次握手的时候,存储在TCP头部的序列号位置中的数字的代称。也就是说,告诉对方我将要开始发送的初始化序列号是多少,两边都要发这个ISN,即tcp三次握手中第一次握手的SYN包和第二次握手的SYN+ACK包中都有这个数值。
这个ISN的具体数值是不固定的,通常我们在wireshark中看到的都是0,这是wireshark帮我们转换过了的。看wireshark的注释也知道,这里注释的是relative sequence number,也就是说这是相对的序列号,并不是确定的。
ISN的具体的数值得由操作系统的源码来决定,有好几种生成方式:
RFC1948中提出了一个较好的
初始化序列号ISN随机生成算法**:
**
ISN = M + F(localhost, localport, remotehost, remoteport)
M是一个计时器,这个计时器每隔4毫秒加1。
F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。要保证hash算法不能被外部轻易推算得出,用MD5算法是一个比较好的选择。
TCP的ISN为什么不能固定?
从攻击的角度:
TCP初始化序列号不能设置为一个固定值,因为这样容易被攻击者猜出后续的序列号,从而遭到攻击。
从TCP连接稳定角度:
广域网的随机性,复杂性都很高,假设client与server连接状况不好,不停的断开又重连。那么之前交互的报文很可能在连接已断开时还没到达server。
如果ISN是固定的,那很可能在新连接建立后,上次连接通信的报文才到达server,这种情况有概率发生上次连接发送的报文的seq序列号正好是server希望收到的新连接的报文seq序列号。这就全乱了。
因此,TCP的ISN不能是固定的。