一、介绍TCP 连接的三次握手?追问:为什么 TCP 握手需要三次?

TCP是面向连接的可靠传输协议

面向连接:三次握手

可靠传输:确认、重传、排序、流控(滑动窗口)

传输层的协议

 

其协议头部有20个字节 分为五个四字节

第一行四字节是 源目端口 各占两字节 16bit

第二行是序列号 占四字节 32bit

第三行是确认序列号 占四字节 32bit

第四行是 4bit的头部长度 6位保留 6位标志位 16位窗口大小

第五行是16位校验和 16位紧急指针

 

TCP会话建立图解如下,可以很明显的看出来,客户端的SYN请求需要服务器的ACK确认,而服务器的SYN请求需要客户端的确认,所以握手需要三次

ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

SYN(SYNchronization) : 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此,  SYN置1就表示这是一个连接请求或连接接受报文。

二、介绍 TCP 断开的四次挥手,追问:为什么 TCP 的挥手需要四次?

四次挥手的图解如下,可以明显的看出来,客户端的FIN(请求释放连接)需要服务器的ACK确认,而服务器的FIN需要客户端的ACK

三、TCP 的 syn 攻击的过程?追问:怎么防御?

过程

攻击者伪造不存在的主机IP 向服务器发送大量的SYN包 ,使服务器的缓存造成溢出,即不能处理正常的SYN请求,这属于DDOS攻击

防御

  1. 具有SYN proxy(SYN***)功能的防火墙
  2. 加快淘汰无效SYN请求
  3. SYN Cookie

四、为什么连接的时候是三次握手,关闭的时候却是四次握手?

连接时,每次的SYN请求需要ACK确认,所以是三次

关闭时,需要客户端与服务器端的都发送FIN并且进行确认,所以是四次

五、TCP 是如何通过滑动窗口协议实现流量控制和拥塞控制的?

流量控制

拥塞控制

六、描述 TCP 和 UDP 的区别?

共同点:

同处于TCP/IP协议栈的传输层

不同点:

协议层面:

TCP是面向连接的可靠传输协议 协议号为6  

UDP是非面向连接的不可靠传输 协议号为17

传输层面:

TCP只能一对一传输且需要维护连接状态  通过流模式传输数据   

UDP支持一对一、一对多、多对一、多对多且不需要建立连接 通过数据报模式传输数据

说明:

      流模式是指存在缓存区,传进来的数据先进入缓冲区;防止发送方发送的数据太大导致接收方接受不了,而数据报追求的是速度,即即时性的将发送方发送的数据发送至接收方

数据层面:

TCP保证数据正确性、不丢包、不重复、有顺序

UDP只尽最大努力交付、不保证可靠性

适用场景

TCP适合网络负担不大,可靠性要求高的场景

UDP适合网络负担大、响应高、客户端较多、可靠性要求不高的场景

报文层面:

封装的报文头大小不同 TCP 20byte  UDP 8byte

七、TCP 有哪些定时器?

  1. 建立连接定时器(connection-establishment timer)
  2. 重传定时器(retransmission timer)
  3. 延迟应答定时器(delayed ACK timer)
  4. 坚持定时器(persist timer)
  5. 保活定时器(keepalive timer)
  6. FIN_WAIT_2定时器(FIN_WAIT_2 timer)
  7. TIME_WAIT定时器 (TIME_WAIT timer, 也叫2MSL timer)

建立连接定时器(connection-establishment timer)

   顾名思义,这个定时器是在建立连接的时候使用的, 我们知道, TCP建立连接需要3次握手, 如下图所示: 

   建立连接的过程中,在发送SYN时, 会启动一个定时器(默认应该是3秒),如果SYN包丢失了, 那么3秒以后会重新发送SYN包的(当然还会启动一个新的定时器, 设置成6秒超时),当然也不会一直没完没了的发SYN包, 在/proc/sys/net/ipv4/tcp_syn_retries 可以设置到底要重新发送几次SYN包。

重传定时器(retransmission timer)

   重传定时器在TCP发送数据时设定,在计时器超时后没有收到返回的确认ACK,发送端就会重新发送队列中需要重传的报文段。使用RTO重传计时器一般有如下规则:

  1. 当TCP发送了位于发送队列最前端的报文段后就启动这个RTO计时器;
  2. 如果队列为空则停止计时器,否则重启计时器;
  3. 当计时器超时后,TCP会重传发送队列最前端的报文段;
  4. 当一个或者多个报文段被累计确认后,这个或者这些报文段会被清除出队列

   重传计时器保证了接收端能够接收到丢失的报文段,继而保证了接收端交付给接收进程的数据始终的有序完整的。因为接收端永远不会把一个失序不完整的报文段交付给接收进程。

延迟应答定时器(delayed ACK timer)

   延迟应答也被称为捎带ACK, 这个定时器是在延迟应答的时候使用的。 为什么要延迟应答呢? 延迟应答是为了提高网络传输的效率。

   举例说明,比如服务端收到客户端的数据后, 不是立刻回ACK给客户端, 而是等一段时间(一般最大200ms),这样如果服务端要是有数据需要发给客户端,那么这个ACK就和服务端的数据一起发给客户端了, 这样比立即回给客户端一个ACK节省了一个数据包。

坚持定时器(persist timer)

   我们已经知道TCP通过让接收方指明希望从发送方接收的数据字节数(即窗口大小)来进行流量控制。如果窗口大小为 0会发生什么情况呢?这将有效地阻止发送方传送数据,直到窗口变为非0为止。接收端窗口变为非0后,就会发送一个确认ACK指明需要的报文段序号以及窗口大小。

   如果这个确认ACK丢失了,则双方就有可能因为等待对方而使连接终止:接收方等待接收数据(因为它已经向发送方通告了一个非0的窗口),而发送方在等待允许它继续发送数据的窗口更新。为防止这种死锁情况的发生,发送方使用一个坚持定时器 (persist timer)来周期性地向接收方查询,以便发现窗口是否已增大。这些从发送方发出的报文段称为窗口探查 (window probe)。

保活定时器(keepalive timer)

   在TCP连接建立的时候指定了SO_KEEPALIVE,保活定时器才会生效。如果客户端和服务端长时间没有数据交互,那么需要保活定时器来判断是否对端还活着,但是这个其实很不实用,因为默认是2小时没有数据交互才探测,时间实在是太长了。如果你真的要确认对端是否活着, 那么应该自己实现心跳包,而不是依赖于这个保活定时器。

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中查看和设置。

TIME_WAIT定时器 (TIME_WAIT timer, 也叫2MSL timer)

   TIME_WAIT是主动关闭连接的一端最后进入的状态, 而不是直接变成CLOSED的状态, 为什么呢?第一个原因是万一被动关闭的一端在超时时间内没有收到最后一个ACK, 则会重发最后的FIN,2MSL(报文段最大生存时间)等待时间保证了重发的FIN会被主动关闭的一段收到且重新发送最后一个ACK;另外一个原因是在2MSL等待时间时,任何迟到的报文段会被接收并丢弃,防止老的TCP连接的包在新的TCP连接里面出现。不可避免的,在这个2MSL等待时间内,不会建立同样(源IP, 源端口,目的IP,目的端口)的连接。

八、什么是 CDN?CDN 是如何工作的?

CDN

CDN是Content Delivery Network的简称, 即“内容分发网络”的意思。 一般我们所说的CDN加速, 一般是指网站加速或者用户下载资源加速。

详细解释:

举个通俗的例子:

  谈到CDN的作用, 可以用8年买火车票的经历来形象比喻:8年前, 还没有火车票代售点一说, 12306.cn更是无从说起。 那时候火车票还只能在火车站的售票大厅购买, 而小县城并不通火车, 火车票都要去市里的火车站购买, 而从县城到市里, 来回就是4个小时车程, 简直就是浪费生命。

  后来就好了, 小县城里出现了火车票代售点, 可以直接在代售点购买火车, 方便了不少, 全市人民再也不用在一个点苦逼的排队买票了。

  CDN就可以理解为分布在每个县城的火车票代售点, 用户在浏览网站的时候, CDN会选择一个离用户最近的CDN边缘节点来响应用户的请求, 这样海南移动用户的请求就不会千里迢迢跑到北京电信机房的服务器(假设源站部署在北京电信机房)上了。

CDN的优势很明显:

(1)CDN节点解决了跨运营商和跨地域访问的问题, 访问延时大大降低;

(2)大部分请求在CDN边缘节点完成, CDN起到了分流作用, 减轻了源站的负载。

CDN缓存是什么?

  首先, 看看没有网站没有接入CDN时, 用户浏览器与服务器是如何交互的:

  用户在浏览网站的时候, 浏览器能够在本地保存网站中的图片或者其他文件的副本, 这样用户再次访问该网站的时候, 浏览器就不用再下载全部的文件, 减少了下载量意味着提高了页面加载的速度。

  如果中间加上一层CDN 那么用户浏览器与服务器的交互如下:

  客户端浏览器先检查是否有本地缓存是否过期, 如果过期, 则向CDN边缘节点发起请求, CDN边缘节点会检测用户请求数据的缓存是否过期, 如果没有过期, 则直接响应用户请求, 此时一个完成http请求结束;如果数据已经过期, 那么CDN还需要向源站发出回源请求(back to the source request),来拉取最新的数据。 CDN的典型拓扑图如下:

可以看到, 在存在CDN的场景下, 数据经历了客户端(浏览器)缓存和CDN边缘节点缓存两个阶段。

CDN工作过程

九、什么是 DNS?说说 DNS 的解析过程?

 

解析过程:

  1. 首先查找本地浏览器的DNS缓存
  2. 查找本地的hosts文件是否有网址的映射关系
  3. 查找本地DNS服务器

至此如果没有找到映射关系的话,就继续向更高级的DNS服务器进行查找

迭代查询

  1. 找13台DNS根服务器(根肯定知道要找的位置属于哪个顶级域名下),将结果返回给本地DNS服务器
  2. 找DNS顶级服务器(顶级肯定知道具体的域名位置),返回给本地DNS服务器
  3. 本地DNS服务器直接去目标然后返回
  4. 本地DNS服务器将结果给到请求的客户端

递归查询:

  1. 找13台DNS根服务器
  2. 根据根DNS服务器端返回的结果直接去顶级DNS服务器
  3. 根据顶级DNS服务器的提示直接去权限域名服务器(具体的域名映射)
  4. 逐级递归返回,至根DNS服务器,然后给到本地DNS服务器一个结果
  5. 本地DNS服务器将结果给到请求的客户端

 

 

以上这种DNS的解析过程是

客户端到本地DNS递归查询

本地DNS服务器与其他高级的DNS服务器的交互是迭代查询

十、什么是 DHCP?描述工作过程?DHCP 有什么安全问题?如何防范?

手段

DHCP耗尽攻击---伪造大量的DHCP请求包来耗尽DHCP的地址池资源

DHCP伪造攻击---伪造dhcp服务器来给发出DHCP请求的主机回包(dhcp会提供网关,DNS)

防御

DHCP Snooping(嗅探技术)

  1. 中继设备上设置信任接口 将真实的DHCP服务器连接中继设备的接口设置为信任接口
  2. 中继设备上限制非信任端口的接收DHCP 数据包的频率