一、传输层协议概述
1、功能
传输层负责建立端到端 的连接,即应用进程之间的通信,负责数据在端到端之间的传输。与网络层不同的是,网络层负责主机与主机之间的通信。
同时,传输层还要对收到的报文进行差错检测(首部和数据部分),这一点与IP数据报首部具有显著差别。
2、复用与分用
传输层通过端口号来区分上下层服务。这里需要提到复用和分用 的概念,传输层的复用指的是发送方不同的应用进程 都可以使用同一个传输层协议传送数据;分用指的是接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程。
同样的,复用和分用并不是传输层特有,网络层同样也有复用分用的功能,具体来说,网络层的复用指发送方不同协议的数据 都可以封装成IP数据报发送出去,分用指的是接收方的网络层在剥去首部后能把数据交付给相应的协议。
二、TCP与UDP协议概述
1、TCP提供的服务
①面向字节流服务
在TCP中,发送方将数据分割成一个个的数据段(segment),每个数据段都有一个序号 (sequence number)和一个确认号(acknowledgement number)。接收方通过确认号来确认已经接收到的数据段,并向发送方发送确认消息。如果发送方没有收到确认消息,它会重新发送数据段,直到接收方确认为止。
由于TCP是面向连接 的协议,因此在数据传输之前,发送方和接收方必须先建立连接。在连接建立之后,数据才能被传输。在数据传输完成之后,连接会被关闭。
我们举一个例子,伍老师和小汪利用TCP协议互相发消息,伍老师想对小汪说:"我男朋友可细心了,每天都给我买好东西!",小汪想对伍老师说:"今天苏州好冷!"。但是由于伍老师的消息很长,TCP将这个消息分成了两部分发送。伍老师先发送了第一部分信息,内容为"我男朋友可细心了,"假设长为9个字节,序号为1。
小汪收到第一部分后,发送确认号ack的值为10,序列号为1,内容为"今天苏州好冷!"的信息,长度为7个字节。确认号为10的意思为想知道对方想发送的第十个字节的消息。
伍老师收到后,发送第二部分为"每天都给我买好东西!",该消息的序号为10,确认号为8。
这和我们平常利用微信或者QQ聊天的方式不大一样,我们在这里探讨的是TCP的工作原理,是微观上的而非宏观上的。
因此,从上述例子中我们不难发现,不能认为一个用户消息对应一个 TCP 报文,正因为这样,所以 TCP 是面向字节流的协议。
②全双工服务
建立连接后,两个进程之间的数据传输是双向的,放在上述例子解释,意思就是说小伍能和小汪发消息的同时,小汪也能给小伍发消息,并不是小伍的一言堂或者小汪的一言堂。
③面向连接的服务
使用TCP进行数据传输的客户/服务器之间,首先要建立一个TCP连接,数据传输完成后断开连接,也就是说,小伍和小汪发消息,首先会通过三次握手过程建立与小汪的连接,当没有消息可以发的时候,通过四次挥手断开连接。
④可靠服务
TCP提供了流量控制、拥塞控制、差错控制等保证数据传输的可靠性
2、TCP报文格式

TCP报文中数据部分是可选的,即TCP报文可以不包含数据(同理IP包也可以不包含数据)。不含数据的TCP报文通常是一些确认和控制信息类的报文,如TCP建立连接时的三次握手和TCP终止时的四次挥手等。
我们先来看看首部由哪些组成:
源端口号(Source Port):长度为16位,指明发送数据的进程。
目的端口号(Destination Port):长度为16位,指明目的主机接收数据的进程。
序号(Sequence Number):也称为序列号,长度为32位,序号用来标识从TCP发送端向接入端发送的数据字节流进行编号 ,可以理解成对字节流的计数。
确认号(Acknowledgement Number):长度为32位,确认号包含发送确认的一端所期望收到的下一个序号。确认号只有在ACK标志为1时才有效。该部分要与大写的ACK区分开。
首部长度:以4字节为单位,一个TCP报文首部20个字节是必有的,后40个字节可有可无。如果TCP报文首部是20个字节,则该位应是20/4=5。
保留位(Reserved):长度为6位,必须是0,它是为将来定义新用途保留的。
标志(Code Bits):长度为6位,在TCP报文中不管是握手还是挥手还是传数据等,这6位标志都很重要。最重要的是加粗的三个部分,其中RST我们在上一篇博客讲解过。6位从左到右依次为:
-
URG:紧急标志位,说明紧急指针有效;
-
ACK:确认标志位,多数情况下空,说明确认序号有效;
-
PSH:推标志位,置位时表示接收方应立即请求将报文交给应用层;
-
RST:复位标志,用于重建一个已经混乱的连接;
-
SYN:同步标志,该标志仅在三次握手建立TCP连接时有效
-
FIN:结束标志,带该标志位的数据包用于结束一个TCP会话。
窗口大小(Window Size):长度为16位,TCP流量控制由连接的每一端通过声明的窗口大小来提供。
检验和(Checksum):长度为16位,该字段覆盖整个TCP报文端(首部加数据部分),是个强制性的字段,是由发送端计算和存储,到接收端后,由接收端进行验证。
紧急指针(Urgent Pointer):长度为16位,指向数据中优先部分的最后一个字节,通知接收方紧急数据的长度,该字段在URG标志置位时有效。
选项(Options):长度为0-40B(字节),必须以4B为单位变化,必要时可以填充0。通常包含:最长报文大小(MaximumSegment Size,MSS)、窗口扩大选项、时间戳选项、选择性确认(Selective ACKnowlegement,SACK)等。
3、连接建立与断开
①三次握手
客户端与服务器建立连接的过程需要三个报文,由于很像人类之间建立联系时相互握手的过程,故这三个报文也被称为"三次握手"。
第一次握手:客户端向服务器发起连接请求报文 ,序列号位客户端初始序列号m ;由于标志SYN=1,ACK=0,该报文也被简称为SYN报文。
第二次握手:服务器等待连接的端口收到TCP连接请求后,回应一个TCP连接应答报文 ,序列号为服务器初始序列号n,确认序列号为客户端初始序列号加1(m+1);其中标志SYN=1、ACK=1,故该报文称为SYN/ACK报文。
第三次握手:客户端收到服务器的响应报文后,向服务器发送TCP确认报文,序列号为客户端初始序列号自增,即(m+1),确认号为服务器初始序列号加1,即(n+1),其中标志SYN=0、ACK=1,被称为ACK报文,该报文客户端可以携带相应的信息。

②四次挥手
客户端与服务器断开连接的过程需要四个报文,由于很像人类之间相互告别时挥手表示再见的过程,故这三个报文也被称为"四次挥手"。
第一次挥手:客户端发送一个FIN=1的报文段,主动 关闭客户端到服务器的数据传送,序列号假设为m;
第二次挥手:服务器收到FIN段后就向应用程序传送一个文件结束符,在给客户端发回一个ACK=1的报文,其ack为所收到的序列号自增,即(m+1);
第三次挥手:服务器发送完数据后,被动 关闭与客户端的连接,发送一个FIN=1、ACK=1的报文给客户端,其序列号与m无关 ,假设为n,ack的值不变,为(m+1);
第四次挥手:客户端收到FIN段后,回复一个ACK=1的报文,确定收到了服务器的FIN段,并将ack的值设置为所收到的序列号加1,即(n+1)。

三、TCP协议安全分析
1、SYN Flood攻击
①原理
攻击者利用TCP连接的半开放状态发动攻击。攻击者使用第一个数据包对服务器进行大流量冲击,使服务器一直处于半开放连接状态,从而无法完成三步握手过程,导致正常用户也无法访问服务,因此SYN-Flood攻击是一种拒绝服务式攻击Dos。
②举例
什么是半开放连接状态?
我们来看看下面这个例子:主人公还是伍老师,她的班上有一个不省心的学生,叫小陈,这一天,平常不怎么学习的小陈突然在下课的时候联系伍老师,对伍老师说:"伍老师,我的古诗默写好差劲啊,今天放学后我能找您默写吗?",伍老师一听,妈呀,太阳从西边亮起来了,赶忙同意,说:"好的好的,小陈同学,下午放学后来办公室找我吧!"
伍老师期待着小陈会在五点半之后到来,但实际情况确是,五点半放学后,伍老师并没有等到小陈的到来,小陈很可恶的放了伍老师的鸽子,直到六点半,伍老师等不下去了,下班回家了。
伍老师和小陈预约默写的言行像极了"建立连接"的前两次握手,小陈发出请求,伍老师进行应答。如果这个连接想要成功建立,那么小陈就要对自己说的话负责,也就是说,放学后来办公室找伍老师默写,但是小陈没有诚信,让伍老师长时间等待,变相的消耗伍老师的"时间",这种没得到确定消息的状态,就处于"半开放状态"。可以用下图来表示SYN Flood的攻击原理:

当然了,如果只有一个可恶的黑客让服务器白等,可能也占不了服务器多少资源,但是如果黑客伪造IP地址,让每一个伪造的IP地址都对服务器进行SYN Flood攻击,这样会大量占据服务器的半连接队列,消耗资源的同时,由于半连接队列已满,也能让真正有需要的客户端不能与服务器建立连接,从而无法访问该服务器。
③攻击检测
如何检测SYN Flood攻击呢?
一个最简单的方法就是检测半连接数,如果在一段时间内突然增多,说明很有可能有黑客对服务器进行了SYN Flood攻击,当然,也可以检测半连接数建立的速度,不过这个本质上与检测数量一致,可以归类为一种方法。
④攻击防范
如何防范SYN Flood攻击呢?
一类方法是释放无效连接,例如监视系统的半开连接和不活动连接,缩短阈值,服务器超过阈值时会释放这些无效的半连接;
另一类方法是利用代理或者防火墙,例如SYN Cookie技术或者SYN proxy技术。
SYN Cookie的原理是,在服务器接收到SYN报文并返回SYN/ACK报文时,不分配一个专门的数据区,而是根据这个SYN报文计算出一个cookie值。这个cookie值作为将要返回的SYN/ACK报文的初始序列号。当客户端返回一个ACK报文时,服务器根据报文头信息计算cookie,与客户端返回的确认序列号进行对比,如果相同,则是一个正常连接,然后,分配资源,建立连接。这样,对于恶意的客户端发起的连接,就不会在为他们分配资源,从根本上遏制了黑客的进攻。
SYN proxy则是在SYN cookie的基础上改进的。客户端与握手代理进行三次握手,握手代理回复客户端的ACK报文携带的初始序列号由SYN cookie算法生成,与SYN cookie工作流程相似;当cookie验证通过后,握手代理充当客户端和服务端进行三次握手,并负责校正初始序列号和窗口大小;在连接建立之后握手代理负责调整客户端和服务端之间数据传输过程中的序列号和确认号。
2、TCP序列号攻击
这个讲解起来很难,对于网络安全的初学者了解即可,小编在这里放一个视频连接,感兴趣的小伙伴可以看一看。
如果你觉得小编写的还不错,麻烦点一个免费的赞和收藏好吗!
