网络篇-2021春招准备

1、OSI七层与TCP/IP五层网络架构

  • 应用层: 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet
  • 表示层:数据格式化,代码转换,数据加密 没有协议
  • 会话层: 解除或建立与别的接点的联系 没有协议
  • 传输层: 提供端对端的接口 TCP,UDP
  • 网络层: 传输数据包选择路由 IP,ICMP,RIP,OSPF,BGP,IGMP,ARP(IP->MAC),RAPR
  • ICMP协议主要用来检测网络通信故障和实现链路追踪,最典型的应用就是PING和tracerooute
  • 数据链路层: 传输数据帧 SLIP,CSLIP,PPP,ARP,RARP,MTU
  • 物理层: 二进制比特位的传输 ISO2110,IEEE802,IEEE802.2

2、IPv4与IPv6的区别

  • IPv4协议具有32位(4字节)地址长度;点分十进制
    • 内网地址分为A,B和C类
      • A类地址范围:10.0.0.0 - 10.255.255.255
      • B类地址范围:172.16.0.0 - 172.31.255.255
      • C类地址范围:192.168.0.0 - 192.168.255.255
  • IPv6协议具有128位(16字节)地址长度;冒分十六进制

3、TCP三次握手四次挥手

数据格式:

title

  • seq:序列号,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号
  • ack:确认号,待收到对方下一个报文段的第一个数据字节的序号
  • 确认ACK标志位:ACK=1时,确认号字段才有效
  • 同步SYN标志位:连接建立时用于同步序号。当SYN=1,ACK=0时表示连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
  • 终止FIN标志位:用来释放一个连接。FIN=1表示此报文段的发送方的数据已经发送完毕,并释放连接。

三次握手过程:

title

  • 发送方: 打开SYN=1,自带序列号seq-x希望建立链接

  • 接收方:打开SYN=1,自带序列号seq-y。并且确认接收到了seq-x,并希望收到ack=seq-(x+1),ACK=1时,ack才有效

  • 发送方:自带序列号seq-(x+1)。确认接收到了seq-y,并希望收到ack=seq-(y+1),ACK=1时,ack才有效

四次挥手过程

title

  • 发送方:FIN=1,自带序列号seq-u。进入FIN-WAIT-1(终止等待1)状态。FIN报文段即使不携带数据,也要消耗一个序号。

  • 接收方:自带序列号seq-v,确认接收到了seq-u, 并希望收到ack=seq-(u+1),ACK=1时,ack才有效。服务端就入了CLOSE-WAIT(关闭等待)状态。发送方收到变为FIN-WAIT-2

  • 接收方将数据发送完成

  • 接收方:FIN=1,自带序列号seq-w,确认接收到了seq-u, 并希望收到ack=seq-(u+1),ACK=1时,ack才有效。变为LAST-ACK(最后确认)状态

  • 发送方:自带序列号seq-(u+1),确认接收到了seq-w, 并希望收到ack=seq-(w+1),ACK=1时,ack才有效。发送方变为TIME_WAIT状态

title

问题1: 为什么连接的时候是三次握手,关闭的时候却是四次握手?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。我收到了,你发数据吧

关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文+ACK。故需要四步握手。我收到了,等我发完数据,我关闭了

问题2: 为什么不能用两次握手进行连接?

3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

问题3: 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE?

为了保证A发送的最后一个ACK报文段能够到达B

防止已经断开的连接1中在链路中残留的FIN包终止掉新的连接2

防止链路上已经关闭的连接的残余数据包干扰正常的数据包,造成数据流不正常

可以看出:接收方结束TCP连接的时间比发送方早一点,因为接收方收到确认就断开连接了,而A还得等待2MSL。

问题4: TIME_WAIT会带来哪些问题?

(1) 作为服务器,短时间内关闭了大量的Client连接,就会造成服务器上出现大量的TIME_WAIT连接,占据大量的tuple,严重消耗着服务器的资源;
(2) 作为客户端,短时间内大量的短连接,会大量消耗Client机器的端口,毕竟端口只有65535个,端口被耗尽了,后续就无法再发起新的连接了

**问题5: **服务端time_wait过多的处理办法

net.ipv4.tcp_tw_reuse=1 (/etc/sysctl.conf)
表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;该文件表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接(这个对快速重启动某些服务,而启动后提示端口已经被使用的情形非常有帮助)

net.ipv4.tcp_tw_recycle=1
表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭

net.ipv4.tcp_timestamps=1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭

问题6: ACK攻击

ACK Flooding攻击是在TCP连接建立之后,所有的数据传输TCP报文都是带有ACK标志位的,主机在接收到一个带有ACK标志位的数据包的时候,需要检查该数据包所表示的连接四元组是否存在,如果存在则检查该数据包所表示的状态是否合法,然后再向应用层传递该数据包。

如果在检查中发现该数据包不合法,例如该数据包所指向的目的端口在本机并未开放,则主机操作系统协议栈会回应RST包告诉对方此端口不存在。

当发包速率很大的时候,主机操作系统将耗费大量的精力接收报文、判断状态,同时要主动回应RST报文,正常的数据包就可能无法得到及时的处理。

问题6: time_wait为什么要2倍MSL

报文一来一回的时间

4、HTTP

HTTP协议是超文本传输协议(默认端口80)

HTTP特点:
  • 无状态(无连接):HTTP 是一个无状态协议,这意味着每个请求都是独立的。
    • 请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端。但每次都要建立TCP请求,效率低
    • Keep-Alive 被提出用来解决这效率低的问题。就是长连接。
请求过程:
  • 浏览器发送url-http请求,根据域名解析出IP(浏览器缓冲->本机->DNS服务器)
  • 浏览器与WEB服务器建立TCP请求,发起http请求,解析那个路径下那个资源
  • WEB服务器响应HTTP请求,80端口,返回html代码
  • 浏览器解析html代码,关闭TCP连接
响应码:

title

HTTP

URI与URL

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。

  • URI:Uniform Resource Identifier 统一资源标识
  • URL:Uniform Resource Location 统一资源定位

URI 是用来标示 一个具体的资源的,我们可以通过 URI 知道一个资源是什么

URL 则是用来定位具体的资源的,标示了一个具体的资源位置。互联网上的每个文件都有一个唯一的URL

HTTP报文组成:
  • 请求头
    • 请求行:包括请求方法、URL、协议/版本
    • 请求头(Request Header)
      • Connection
      • Origin
      • User-Agent
      • cookie
      • content-type
      • Range: bytes=5000-10000 指定资源的Byte范围,范围请求
  • 请求正文
  • 响应报文
    • 状态行
    • 响应头
      • Date
      • Connect-Type
      • Connection
      • content-length:获取文件的总大小,然后读Stream,每读一段,就计算出当前读的总大小,除以content-length,用来显示进度条
    • 响应正文
常见方法
  • get
  • post
  • put
  • delete

get post区别

  • 都包含请求头请求行,post多了请求body。
  • get多用来查询,请求参数放在url中,不会对服务器上的内容产生作用。post用来提交,如把账号密码放入body中。
  • GET是直接添加到URL后面的,直接就可以在URL中看到内容,而POST是放在报文内部的,用户无法直接看到。
  • GET提交的数据长度是有限制的,因为URL长度有限制,具体的长度限制视浏览器而定。而POST没有。
http 1.0/1.1/2.0/3.0的区别
  • http 1.0

    • 短连接:每次发送请求都要重新建立tcp请求,即三次握手,非常浪费性能
    • 无host头域,也就是http请求头里的host,
    • 不允许断点续传,而且不能只传输对象的一部分,要求传输整个对象
  • http 1.1

    • 长连接,流水线,使用connection:keep-alive使用长连接,与http 2.0不同的是,
    • host头域
    • 由于长连接会给服务器造成压力
  • HTTP 2.0

    • 头部压缩,双方各自维护一个header的索引表,使得不需要直接发送值,通过发送key缩减头部大小

      • 在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。
      • HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
    • 多路复用,使用多个stream,每个stream又分帧传输,使得一个tcp连接能够处理多个http请求

      title

    • 可以使用服务端推送

      • 在HTTP1.1中这些资源每一个都必须明确地请求。这是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。
      • 为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络

      title

  • HTTP 3.0

    • 基于google的QUIC协议,而quic协议是使用udp实现的
    • 减少了tcp三次握手时间,以及tls握手时间
    • 解决了http 2.0中前一个stream丢包导致后一个stream被阻塞的问题
    • 优化了重传策略,重传包和原包的编号不同,降低后续重传计算的消耗
    • 连接迁移,不再用tcp四元组确定一个连接,而是用一个64位随机数来确定这个连接
    • 更合适的流量控制

5、Https

1、加密通信:

为了安全性,双方可以使用对称加密的方式key进行信息交流,但是这种方式对称加密秘钥也会被拦截,也不够安全,进而还是存在被中间人攻击风险;
于是人们又想出来另外一种方式,使用非对称加密的方式;使用公钥/私钥加解密;通信方A发起通信并携带自己的公钥,接收方B通过公钥来加密对称秘钥;然后发送给发起方A;A通过私钥解密;双发接下来通过对称秘钥来进行加密通信;但是这种方式还是会存在一种安全性;中间人虽然不知道发起方A的私钥,但是可以做到偷天换日,将拦截发起方的公钥key;并将自己生成的一对公/私钥的公钥发送给B;接收方B并不知道公钥已经被偷偷换过;按照之前的流程,B通过公钥加密自己生成的对称加密秘钥key2;发送给A;
这次通信再次被中间人拦截,尽管后面的通信,两者还是用key2通信,但是中间人已经掌握了Key2;可以进行轻松的加解密;还是存在被中间人攻击风险;

2、解决困境:权威的证书颁发机构CA来解决;
  • 制作证书:作为服务端的A,首先把自己的公钥key1发给证书颁发机构,向证书颁发机构进行申请证书;证书颁发机构有一套自己的公私钥,CA通过自己的私钥来加密key1,并且通过服务端网址等信息生成一个证书签名,证书签名同样使用机构的私钥进行加密;制作完成后,机构将证书发给A;
  • 校验证书真伪:当B向服务端A发起请求通信的时候,A不再直接返回自己的公钥,而是返回一个证书;
    说明:各大浏览器和操作系统已经维护了所有的权威证书机构的名称和公钥。B只需要知道是哪个权威机构发的证书,使用对应的机构公钥,就可以解密出证书签名;接下来,B使用同样的规则,生成自己的证书签名,如果两个签名是一致的,说明证书是有效的;
    签名验证成功后,B就可以再次利用机构的公钥,解密出A的公钥key1;接下来的操作,就是和之前一样的流程了;
  • 中间人是否会拦截发送假证书到B呢?
    因为证书的签名是由服务器端网址等信息生成的,并且通过第三方机构的私钥加密中间人无法篡改; 所以最关键的问题是证书签名的真伪;
  • HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
3、SSL加密的过程
  • 对称加密: 使用相同的密钥进行加密解密,效率高
  • 非对称加密: 客户端(公钥)加密,服务器(私钥)解密,安全
  • 非对称加密+对称加密: 非对称加密过程保护对称密钥的交换,然后采用对称密钥进行加密通信
  • CA认证: 在SSL加密过程,客户端必须能够验证自己收到的公钥的正确性(防止被第三方进行通信劫持),而这个验证通过CA认证,数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上
4、加密算法
  • 对称加密算法

    • DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
    • 3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
    • AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;
  • 非对称算法

    • RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;
    • DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);
    • ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。
5、Https握手过程

title

  • 1、客户端发起HTTPS请求

  • 2、服务端的配置

    • 采用HTTPS协议的服务器必须要有一套数字证书,可以是自己制作或者CA证书。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用CA证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。公钥给别人加密使用,私钥给自己解密使用。
  • 3、传送证书

    • 这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等。
  • 4、客户端解析证书

    • 这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值,然后用证书对该随机值进行加密。
  • 5、传送加密信息

    • 这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了
  • 6、服务段解密信息

    • 服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
  • 7、传输加密后的信息

    • 这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。
  • 8、客户端解密信息

    • 客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。

为什么HTTPS是安全的?

在HTTPS握手的第四步中,如果站点的证书是不受信任的,会显示出现下面确认界面,确认了网站的真实性。另外第六和八步,使用客户端私钥加密解密,保证了数据传输的安全。

6、常见端口

  • 21端口:FTP 文件传输服务
  • 22端口:SSH 端口
  • 23端口:TELNET 终端仿真服务
  • 25端口:SMTP 简单邮件传输服务
  • 53端口:DNS 域名解析服务
  • 80端口:HTTP 超文本传输服务
  • 110端口:POP3 “邮局协议版本3”使用的端口
  • 443端口:HTTPS 加密的超文本传输服务
  • 3306端口:MYSQL 默认端口号

7、IP字段

title

  • 版本:L3协议版本号,IPv4或IPv6

  • 首部长度:单位为4字节

  • 标识:每一个IP封包都有一个16位的唯一识别码。当程序产生的数据要通过网络传送时都会被拆散成封包形式发送,当封包要进行重组的时候这个ID就是依据了。占16位。

  • 协议:L4协议类型

  • TTL生存时间字段设置了数据报可以经过的最多路由器数。一旦经过一个处理它的路由器,它的值就减1。当该字段值为0时,数据报就被丢弃,并发送ICMP报文通知源主机。

  • 首部校验和(Header checksum): 这个数值用来检错用的,用以确保封包被正确无误的接收到。当封包开始进行传送后,接收端主机会利用这个检验值会来检验余下的封包,如果一切无误就会发出确认信息表示接收正常。与UDP和TCP协议包头中的校验和作用是一样的。占16位。

    首部检验和字段是根据IP首部计算的检验和码,不对首部后面的数据进行计算

8、TCP字段

title

  • 滑动窗口协议(Sliding Window Protocol)

    • 属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输,提高网络吞吐量。
    • 滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓 冲区。由于窗口由16位bit所定义,所以接收端TCP 能最大提供65535个字节的缓冲。由此,可以利用窗口大小和第一个数据的序列号计算出最大可接收的数据序列号。
    • 滑动窗口本质上是描述接受方的TCP数据报缓冲区大小的数据,发送方根据这个数据来计算自己最多能发送多长的数据。如果发送方收到接受方的窗口大小为0的TCP数据报,那么发送方将停止发送数据,等到接受方发送窗口大小不为0的数据报的到来。
  • 字段flag

    • URG:紧急指针有效
    • ACK:确认号有效
    • PSH:接收方应该尽快将这个报文段交给应用层
    • RST:重建连接
    • SYN:同步序号用来发起一个连接
  • 校验和字段 16bit:

    • 这个校验和是针对首部和数据两部分的。

9、UDP字段

title

  • 校验和字段
    • 是指整个UDP报文头和UDP所带的数据的校验和(也包括伪报文头)。伪报文头不包括在真正的UDP报文头中,但是它可以保证UDP数据被正确的主机收到了。因在校验和中加入了伪头标,故ICMP除能防止单纯数据差错之外,对IP分组也具有保护作用。

10、TCP拥塞控制如何实现

title

名词:

  • cwnd: 拥塞窗口
  • ssthresh: 门限

过程:

  • 慢开始: 初始化拥塞窗口为1,发送 1 2 4 8个报文段
  • 拥塞控制:当拥塞窗口增长到慢开始的门限制时改为拥塞避免,加法增大
  • 快重传:
    • 使发送方尽快进行重传,而不是等待重传计时器超时再重传
    • 发送方一段收到三个重复确认就立刻重传
  • 快恢复:门限制为当前窗口的一半,cwnd为奇数一般向下取整

11、TCP流量控制如何实现

区别

  • 流量控制:是端到端的控制,例如A通过网络给B发数据,A发送的太快导致B没法接收(B缓冲窗口过小或者处理过慢),这时候的控制就是流量控制,原理是通过滑动窗口的大小改变来实现。

  • 拥塞控制:是A与B之间的网络发生堵塞导致传输过慢或者丢包,来不及传输。防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不至于过载。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络性能有关的所有因素

流量控制

TCP是一个全双工的,TCP滑动窗口分为接受窗口,发送窗口。滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的

ACK包含的两个重要的信息:

  • 期望接收到的下一字节的序号n,该n代表接收方已经接收到了前n-1字节数据,此时如果接收方收到第n+1字节数据而不是第n字节数据,接收方是不会发送序号为n+2的ACK的。举个例子,假如接收端收到1-1024字节,它会发送一个确认号为1025的ACK,但是接下来收到的是2049-3072,它是不会发送确认号为3072的ACK,而依旧发送1025的ACK
  • 当前的窗口大小m,如此发送方在接收到ACK包含的这两个数据后就可以计算出还可以发送多少字节的数据给对方,假定当前发送方已发送到第x字节,则可以发送的字节数就是y=m-(x-n).这就是滑动窗口控制流量的基本原理

发送方根据收到ACK当中的期望收到的下一个字节的序号n以及窗口m,还有当前已经发送的字节序号x,算出还可以发送的字节数

接受端窗口的第一个字节序之前一定是已经完全接收的,后面窗口里面的数据都是希望接受的,窗口后面的数据都是不希望接受的。

title


网络篇-2021春招准备
https://zhangfuli.github.io/2021/02/09/2021春招准备-网络篇/
作者
张富利
发布于
2021年2月9日
许可协议