目录
1、介绍TCP连接的三次握手?追问:为什么TCP握手需要三次?
2、介绍TCP断开的四次挥手,追问:为什么TCP的挥手需要四次?
3、TCP的SYN攻击的过程?追问:怎么防御?
4、为什么连接的时候是三次,关闭的时候却是四次?
5、TCP是如何实现流量控制和拥塞控制的?
6、描述TCP和UDP的区别?
7、TCP有哪些定时器?
8、什么是CDN?CDN是如何工作的?
9、什么是DNS?说说DNS的解析过程?
10、什么是DHCP?描述工作过程?
第一次握手:客户端向服务端发送一个SYN同步标志位置1的数据包来,表明希望建立TCP连接;初始序列号为X,保存在包头的序列号字段里。
第二次握手:服务端收到数据包后,通过SYN的置位得知,这是一个建立TCP的请求;服务端会返回确认包(ACK),再次基础上,并将SYN同步标志位和ACK标志位均置1;确认序列号为X+1,表示收到了客户端的请求;而这个包的序列号为Y。
第三次握手:客户端收到服务端的回包,会再返回一个确认包,SYN标志位置0,ACK标志位置1,确认序列号为Y+1,表示已经收到服务器的回包。
原因:
从信息对等角度来看:通信双方只有确认4类信息才能建立连接,即我方的收和发能力与对端的收和发能力均正常。如果只有两次握手,站在客户端角度没有什么,但是服务端无法确定,自己的发送能力和对端的接收能力是否正常。因此需要第三次的确认。
从防止超时角度来看:如果只有两次握手,服务端发出的应答包,客户端到底收到没有,如果收到服务端也无从得知,如果没收到,服务端就需要重发,这就需要这个第三次握手来解决这个问题。
第一次断开:作为主动关闭连接的一方,客户端会发送一个FIN置位的数据包(其中头部的FIN位置为1,序列号为U)。
第二次断开:服务端收到客户端的断开请求,会回复一个ACK包,序列号为V,ACK确认号为U+1,其中ACK位置为1。
第三次断开:当服务端准备好断开后,会再次向客户端发送一个FIN置位的数据包,其中FIN位置为1,序列号为W。
第四次断开:客户端收到服务端的FIN置位的数据包后,会回复一个确认包(ACK包),其中确认号为W+1,序列号为U+1。
经过2MSL时间后关闭连接;被动关闭方收到主动关闭方的ACK后,关闭连接。
原因:
有了三次握手的基础,我们对四次挥手就不难理解,因为TCP要实现可靠的连接关闭,这里客户和服务器分别向对方发送了一个FIN包用来断链,但是为了告知对方本端顺利的收到了FIN包,会分别对这个FIN报文进行ACK的确认,这就需要四次断开来实现,少一次都不行。
利用TCP协议缺陷,攻击者向被攻击者的主机大量伪造的TCP请求连接,从而使被攻击者的服务器资源耗尽的攻击方式。也就是我们所熟知的DOS攻击。
防御:
网络终端对策:
1、增加TCP backlog队列
2、减少SYN-RECEIVED的时间
3、SYN 缓存
4、SYN cookie机制
基于网络的对策:
1、防火墙与代理
一个有防火墙或者代理的设备在网络中就能够通过两种方法缓冲SYN洪泛攻击,一种是对连接发起人伪装SYN-ACK包,另一种是对服务器伪装ACK包
如果连接发起人是合法的,防火墙/代理就会收到ACK,然后在它自己和服务器之间建立连接并伪装连接发起人的地址。防火墙/代理将连接双方分割开。这种分割能够抵御SYN洪泛攻击,因为服务器方根本没接受收过攻击者的SYN。只要防火墙/代理实现了一些基于TCP的防御策略,比如SYN cookies或SYN 缓存,他就能够保护所有在其后面的服务器免于SYN洪泛攻击。
另一种是响应SYN-ACK的伪装ACK包通过防火墙/代理到达服务器。这种伪装防止服务器的TCB一直停留在SYN-RECEIVED状态,因此保证了backlog队列中的空余空间。防火墙/代理将会停留等待一段时间,如果连接发起人正确的ACK没有被检测到,它将会通过伪装的TCP RET报文使服务器释放TCB。对合法的连接,数据包流能够在没有防火墙/代理的影响下继续进行。这种方法相比于上面伪装SYN-ACK的方法更具吸引力,因为当合法连接建立以后防火墙/代理不需要直接参与到连接中去。
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,并不能一起发送。故需要四步断开。
(1)滑动窗口解决流量控制
首先明确滑动窗口的范畴:TCP是双工的协议,会话的双方都可以同时接收和发送数据。TCP会话的双方都各自维护一个发送窗口和一个接收窗口。各自的接收窗口大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率),以字节为单位调整。各自的发送窗口则要求取决于对端通告的接收窗口,要求相同。
滑动机制:
发送窗口只有收到发送窗口内字节的ACK确认,才会移动发送窗口的左边界。
接收窗口只有在前面所有的段都确认的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此确保对端会对这些数据重传。
遵循快速重传、累计确认、选择确认等规则。
发送方发的window size = 5000;就是接收端最多发送5000字节,这个5000一般就是发送方接收缓存的大小。
滑动窗口解决的是流量控制问题如果接收端和发送端对数据包的处理速度不同,如何让双方达成一致。接收端的缓存传输数据给应用层,但这个过程不一定是即时的,如果发送速度太快,会出现接收端数据overflow,流量控制解决的是这个问题。
关于滑动窗口:
1.接收端将自己缓冲区大小放进TCP头部的“窗口大小”字段,通过ACK告知发送端;
2.窗口大小是指无需等待确认应答而可以一次连续发送数据的最大值;
3.操作系统内核为了维护滑动窗口,需开辟发送缓冲区,来记录哪些数据还没有被应答,只有确认应答后才从缓冲区删除;
4.接收端发现自己缓存区快满了,将窗口大小设置更小发送给发送端,发送端收到后就会减慢发送速度;
5.接收端发现自己缓冲区满了,将窗口大小设置为0,此时发送端停止发送数据,而是定期发送一个窗口探测数据段,让接收端告诉它的窗口大小;
(2)通过慢启动、拥塞避免、快速重传、快恢复来实现拥塞控制
拥塞窗口,其大小取决于网络的拥塞程度,并且动态地在变化。
慢开始算法的思路就是,不要一开始就发送大量的数据,先从1慢慢增加,试探一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。
为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需设置一个慢开始的门限值ssthresh状态变量。ssthresh的用法如下:
当cwnd < ssthresh时,使用慢启动算法 ,即拥塞窗口数量呈指数增长。
当cwnd > ssthresh时,改用拥塞避免算法,即拥塞窗口大小为线性增长。
当cwnd = ssthresh时,慢开始与拥塞避免算法任意。
拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间就把发送发的拥塞窗口cwnd加K(K为常数),即线性增长,而不是指数增长。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢启动的门限设置为出现拥塞时的发送窗口大小的一半。然后使用快恢复算法,拥塞窗口以线性方式增长,直到网络出现拥塞时,拥塞窗口再次减半,重复以上操作。
1.是否有连接。TCP是一个面向连接的协议,在数据收发开始前,需要建立端到端的连接,UDP是一个无连接无连接协议,不需要建立连接。UDP更适合多播发布,从单点到多点传输消息。
2、可靠性。TCP利用握手,确认,和重传机制提供了可靠性保证;而UDP则可能会丢失,不知道是否被接收。
3.有序性。消息会以发出的同样的顺序发送到客户端,尽管这些消息到网络的另一端时可能是无序的,TCP协议将会为你排好序。UDP不提供任何有序性或序列性的保证,数据包将以任何可能的顺序到达。
4.包头大小。在保证可靠性的代价就是庞大的包头,TCP的包头为20个字节,而UDP仅仅为8字节。
5.传递速度。TCP速度比较慢,而UDP速度比较快,因为TCP必须创建连接,以保证消息的可靠交付和有序性,他需要做比UDP多的多的事。这就是为什么UDP更适用于对速度比较敏感的应用,例如:在线视频媒体,电视广播和多人在线游戏。
6.由于协议的特性,所以在传输模式上,TCP为流模式,而UDP则是数据报模式
1.建立连接定时器(connection-establishment timer)
建立连接的过程中,在发送SYN时, 会启动一个定时器(默认应该是3秒),如果SYN包丢失了, 那么3秒以后会重新发送SYN包(这时会启动一个新的计时器,设置为6s超时)。当然也不会一直重发,可以在/proc/sys/net/ipv4/tcp_syn_retries 可以设置到底要重新发送几次SYN包。
2.重传定时器(retransmission timer)
重传定时器在TCP发送数据时设定,在计时器超时后没有收到返回的确认ACK,发送端就会重新发送队列中需要重传的报文段。当TCP发送了位于发送队列最前端的报文后就启动这个RTO计时器;如果队列为空则停止计时器,否则重启计时器;计时器超时后TCP就会重传发送队列最前端的报文段;当一个或者多个报文段被累计确认后,这个报文就会被清除队列。
重传计时器保证了接收端能够接收到丢失的报文段,继而保证了接收端交付给接收进程的数据始终的有序完整的。因为接收端永远不会把一个失序不完整的报文段交付给接收进程。
3.延迟应答定时器(delayed ACK timer)
延迟应答也被称为捎带ACK, 这个定时器是在延迟应答的时候使用的。 为什么要延迟应答呢? 延迟应答是为了提高网络传输的效率。
举例说明,比如服务端收到客户端的数据后, 不是立刻回ACK给客户端, 而是等一段时间(一般最大200ms),这样如果服务端要是有数据需要发给客户端,那么这个ACK就和服务端的数据一起发给客户端了, 这样比立即回给客户端一个ACK节省了一个数据包。
4.坚持定时器(persist timer)
我们知道TCP接收方通过指明窗口大小来进行流量控制。如果窗口大小为0,这将会阻止发送方传送数据,直到窗口变为非0为止;接收端窗口变为非0后,就会发送一个确认ACK指明需要的报文段序号以及窗口大小。
如果这个确认ACK丢失了,则双方就有可能因为等待对方而使连接终止:接收方等待接收数据(因为它已经向发送方通告了一个非0的窗口),而发送方在等待允许它继续发送数据的窗口更新。为防止这种死锁情况的发生,发送方使用一个坚持定时器 (persist timer)来周期性地向接收方查询,以便发现窗口是否已增大。这些从发送方发出的报文段称为窗口探查 (window probe)
5.保活定时器(keepalive timer)
在TCP连接建立的时候指定了SO_KEEPALIVE,保活定时器才会生效。如果客户端和服务端长时间没有数据交互,那么需要保活定时器来判断是否对端还活着,但是这个其实很不实用,因为默认是2小时没有数据交互才探测,时间实在是太长了。如果你真的要确认对端是否活着, 那么应该自己实现心跳包,而不是依赖于这个保活定时器。
6.FIN_WAIT_2定时器(FIN_WAIT_2 timer)
主动关闭的一端调用完close以后(即发FIN给被动关闭的一端, 并且收到其对FIN的确认ACK)则进入FIN_WAIT_2状态。如果这个时候因为网络突然断掉、被动关闭的一段宕机等原因,导致主动关闭的一端不能收到被动关闭的一端发来的FIN,主动关闭的一段总不能一直傻等着,占着资源不撒手吧?这个时候就需要FIN_WAIT_2定时器,如果在该定时器超时的时候,还是没收到被动关闭一端发来的FIN, 直接释放这个链接。FIN_WAIT_2定时器的时间可以从/proc/sys/net/ipv4/tcp_fin_timeout中查看和设置。
7.TIME_WAIT定时器 (TIME_WAIT timer, 也叫2MSL timer)
TIME_WAIT是主动关闭连接的一端最后进入的状态, 而不是直接变成CLOSED的状态, 为什么呢?第一个原因是万一被动关闭的一端在超时时间内没有收到最后一个ACK, 则会重发最后的FIN,2MSL(报文段最大生存时间)等待时间保证了重发的FIN会被主动关闭的一段收到且重新发送最后一个ACK;另外一个原因是在2MSL等待时间时,任何迟到的报文段会被接收并丢弃,防止老的TCP连接的包在新的TCP连接里面出现。不可避免的,在这个2MSL等待时间内,不会建立同样(源IP, 源端口,目的IP,目的端口)的连接。
CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
工作原理:当用户请求一个文件时,DNS请求当地local DNS服务器,然后local DNS服务器查询Root DNS服务器,Root服务器根据授权的DNS记录返回给local DNS服务器一个域名,local DNS服务器继续向授权服务器查询,授权服务器查询后回复local DNS服务器,Local DNS得到域名记录后,向智能调度DNS查询域名的ip地址,智能调度DNS根据一定的算法和策略(比如静态拓扑,容量等),将最适合的CDN节点ip地址回应给 Local DNS,Local DNS将得到的域名ip地址,回应给用户端,用户得到域名ip地址后,访问站点服务器
,CDN节点服务器应答请求,将内容返回给客户端.(缓存服务器一方面在本地进行保存,以备以后使用,二方面把获取的数据返回给客户端,完成数据服务过程)。
DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。DNS使用TCP和UDP的53号端口。
过程:
1、在浏览器中输入WWW.QQ.COM域名,主机先从浏览器的缓存中查找目标IP,因为浏览器会记录DNS一段时间;然后检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
2、如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回。
3、如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
4、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理qq.com的DNS服务器地址给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找QQ.COM域服务器,重复上面的动作,进行查询,直至找到WWW.QQ.COM主机。
5、如果用的是转发模式,本地DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把请求转至上上级,以此循环。找到最后把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。
注:从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间使用的交互查询就是迭代查询。
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作, 主要有两个用途:给内部网络或网络服务供应商自动分配IP地址,给用户或者内部网络管理员对所有计算机作中央管理的手段。主机发送请求消息到DHCP服务器的67号端口,DHCP服务器回应应答消息给主机的68号端口。
过程:
1.用户以广播的形式发送discover请求,数据包的源IP为0.0.0.0,目标IP为255.255.255.255,源MAC为自己的MAC,目标MAC为全F,寻找能够提供服务的服务器。一般主机收到这个包会直接丢掉。
2.当服务器收到这个discover包之后会单播进行回复一个offer包给予Client端应答,意在告诉Client端它可以提供IP地址。但在给出此地之前,应当用ICMP ECHO REQUEST报文进行检查,检查是否有其他机器配置此IP地址。
3.Client只能处理其中的一个DHCP Offer报文,一般的原则是Client处理最先收到的DHCP Offer报文。 Client会发出一个广播的DHCP Request报文,在选项字段中会加入选中的DHCP Server的IP地址和需要的IP地址。此时数据包的源IP和目的IP依然是0.0.0.0和255. 255.255.255。
4.当server收到请求后,DHCP Server就会向Client响应一个DHCP ACK报文,并在选项字段中增加IP地址的使用租期信息。至此IP分配完成。