网络分层模型

  • OSI七层模型
    • 应用层:为计算机用户提供服务
    • 表示层:数据处理(编解码、加密解密、压缩解压缩)
    • 会话层:管理(建立、维护、重连)应用程序之间的会话
    • 传输层:为两台主机进程之间的通信提供通用的数据传输服务
    • 网络层:路由和寻址
    • 数据链路层:帧编码和误差纠正控制
    • 物理层:透明地传送比特流
  • TCP/IP四层模型
    • 应用层
    • 传输层
    • 网络层
    • 网络接口层

从输入URL到页面展示到底发生了什么

  • 浏览器查找域名的IP地址
  • 浏览器向Web服务器发送HTTP请求
  • Web服务器处理请求
  • 服务器发回一个HTML响应
  • 浏览器显示HTML
  • 具体一些:
    • 使用DNS协议获取域名对应的IP
    • 使用TCP协议建立与服务器的连接
    • 使用OSPF在路由之间寻址
    • 使用ARP协议将IP地址转换成MAC地址
    • TCP连接建立后,使用HTTP协议访问网页

常用的HTTP状态码

  • 1xx:传递信息,表明请求正在处理
  • 2xx:成功状态码,请求正常处理
    • 200
    • 201
    • 202
    • 204
  • 3xx:重定向状态码
    • 301
    • 302
  • 4xx:客户端错误,服务器无法处理请求
    • 400
    • 401
    • 403
    • 404
    • 409
  • 5xx:服务器错误,服务器处理请求出错
    • 500
    • 502

HTTPS与HTTP的区别?

  • SSL/TLS:

    • SSL/TLS 的工作原理
  • 内容对称加密,加密的密钥为非对称加密

HTTP/1.0 vs HTTP/1.1

  • 连接方式:长短
  • 状态响应码:206 409 410
  • 缓存机制
  • 带宽:允许部分请求
  • Host头:允许在同一HTTP上托管多个域名

HTTP/1.1 vs HTTP/2.0

  • 多路复用:不同请求共用一个连接
  • 二进制帧
  • 头部压缩:HPACK
  • 服务器推送:在服务器请求一个资源的时候,将其他资源一并推送

HTTP/2.0 vs HTTP/3.0

  • 传输协议:QUIC(基于UDP实现SSL/TLS相似的安全性)

HTTP无状态,如何保存用户的状态?

  • 使用Session,第一次请求会返回SessionID,接下来的请求都需要带有SessionID(附带在Cookie中)
  • Cookie被禁用:将SessionID直接附加于URL路径后

GET和POST区别:

WebSocket:持久性连接,基于SSL/TLS TCP

  • 建立过程:
    • HTTP升级

全双工?半双工?

TCP vs UDP

  • 建立连接?
  • 传输可靠性?
  • 传输状态?
  • 效率?
  • 传输数据形式?
  • 头部开销,空间占用?
  • 广播或多播?
  • 用途?

TCP三次握手和四次挥手?

  • Client:
    • SYN_SENT、FIN_WAIT1、FIN_WAIT2、TIME_WAIT
  • Server:
    • SYN_RECV、CLOSE_WAIT、CLOSED

TCP如何保持传输可靠性?

  • 基于数据块
  • 给数据包编号,排序,去重
  • 检验和
  • 重传机制
    • 超时
    • 立即
    • SACK-Server发送,获取收到的报文段
    • D-SACK
  • 流量控制
    • 滑动窗口,避免发送方发的太快,接收方接受不过来导致的数据丢弃
  • 拥塞控制
    • 拥塞窗口
    • 慢开始、拥塞避免、快重传、快恢复

AQS自动重传协议:

  • 停止等待
    • 无差错情况:一收一确认
    • 存在差错:超时重传
      • 确认丢失
      • 确认迟到
  • 连续ARQ

RTT、RTO、MSL

HTTP

HTTP常见的状态码:

  • 1xx 协议处理中间状态,还需后续操作
  • 2xx 成功,报文收到,并正确处理
    • 200 OK ,一切正常,如果是非HEAD请求,服务器返回的响应头都会有body数据
    • 204 NO CONTENT 一切正常,响应头无Body数据
    • 206 Partial Content 用于HTTP分块下载或断点续传,表示响应返回的body数据不是资源的全部,而是一部分
  • 3xx 重定向,资源位置发生变动,需要客户端重新请求
    • 301 Moved permanently 永久重定向,请求的资源不在,需要用新的URL再次访问
    • 302 Found 临时重定向,请求的资源还在,暂时需要另一个URL访问
      • 301 302 在响应头中的Location字段,指明了后续要跳转的URL
    • 304 Not Modified 不跳转,表示资源未修改,重定向缓存文件
  • 4xx 客户端错误,请求报文有误,服务器无法处理
    • 400 Bad Request 客户端请求报文有误
    • 403 Forbidden 服务器禁止访问资源
    • 404 Not Found 请求的资源在服务器上找不到
  • 5xx 服务器错误,服务器在处理请求时内部发生了错误
    • 500 Internal Server Error 笼统的错误码,表示服务器出错
    • 501 Not Implemented 客户端请求的功能还不支持
    • 502 Bad Gateway 服务器作为网关或者代理时返回的错误码,服务器工作正常,访问后端时发生错误
    • 503 Service Unavailable 服务器当前忙,无法响应客户端

HTTP常见字段

  • Host:发送请求,指定服务器的域名
  • Content-Length:本次回复的数据长度,作为HTTP body的边界,搭配回车符、换行符作为HTTP header的边界,用于解决粘包问题
  • Connection:客户端要求服务器使用 HTTP长连接,指定值为 Keep-Alive
  • Content-Type:用于服务器回应,告诉客户端,本次数据是什么格式
  • Accept:用于请求,表示自己接受哪些数据格式
  • Content-Encoding:表明服务器返回的数据使用了什么压缩格式
  • Accept-Encoding:说明自己可以接收哪些压缩方法

安全和幂等

  • 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源
  • 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的

HTTP缓存实现方式:

  • 强制缓存
    • 只要缓存未过期,就直接使用浏览器本地缓存,浏览器主动决定
    • 实现方式:
      • Cache-Control:相对过期时间(优先级高)
      • Expires:绝对过期时间
  • 协商缓存
    • 客户端与服务器协商后,通过协商结果判断是否使用本地缓存
    • 实现方式:
      • 第一种
        • 请求头 if-Modified-Since,资源过期后,带上Last-Modified的值,用于服务器判断资源是否被修改
        • 响应头 Last-Modified,资源最后修改时间
      • 第二种
        • 请求头 if-None-Match:资源过期,该头带上Etag值,用于服务器判断资源是否过期
        • 响应头 Etag:唯一标识响应资源
      • Etag优先级高于Last-Modified
        • 即便没有修改文件,文件的最后修改日期也可能变
        • 有些文件是以秒为单位修改的,if-Modified-Since只能检测秒为单位的修改,Etag可以检测一秒内的多次修改
        • 有些服务器不能精确获取修改时间
    • 协商缓存需要配合Cache-Control来使用,只有未命中强制缓存,才使用协商缓存

HTTP特点

  • 简单
  • 易于拓展
  • 跨平台
  • 缺点
    • 无状态
    • 明文传输
    • 不安全
  • HTTP 1.1
    • 长连接
    • 管道网络传输
      • 解决了请求的队头阻塞,但没有解决响应的队头阻塞
    • 队头阻塞
      • 服务端响应一个请求被阻塞,后端排队的所有请求也一同被阻塞

HTTP和HTTPS区别

  • TCPHTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输
  • **还需进行 **SSL/TLS 的握手过程,才可进入加密报文传输
  • HTTP 默认端口号是 80,HTTPS 默认端口号是 443
  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的

HTTP问题

  • 窃听风险
    • 信息加密
      • 混合加密的方式实现信息的机密性
  • 篡改风险
    • 检验机制
      • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险
  • 冒充风险
    • 身份证书
      • 将服务器公钥放入到数字证书中,解决了冒充的风险

混合加密

  • 在通信建立前使用非对称加密的方式交换会话密钥,后续不再使用非对称加密
    • 公钥和私钥,公钥可以任意分发,私钥保密,解决了密钥交换问题但速度慢
  • 通信过程中使用对称加密的会话密钥,加密明文数据
    • 运算速度快,无法做到安全的密钥交换

摘要算法和数字签名

  • 使用摘要算法(哈希函数)计算出内容的哈希值,哈希值是唯一的,且无法通过哈希值推导出内容
    • 只能保证内容不会被篡改,但是不能保证内容不能被替换
  • 非对称加密
    • 公钥和私钥,这两个密钥可以双向加解密
      • 公钥加密,私钥解密,保证传输内容的安全
      • 私钥加密,公钥解密,保证消息不会被冒充,如果公钥能正常解密出私钥加密的内容,就可以证明这个消息是持有私钥身份的人发送的
        • 私钥加密不是对内容加密,而是对内容的哈希值加密

数字证书

  • 数字证书认证机构(CA),用自己的私钥,对服务器公钥做数字签名,将 个人信息 + 公钥 + 数字签名 打包为数字证书
  • 拿到服务器的数字证书后,会根据CA的公钥解密证书的签名,得到公钥,和数字证书的公钥对比,来判断数字证书是否合法

SSL/TLS协议基本流程

  • 客户端要服务器索要并验证服务器的公钥
  • 双方协商产生会话密钥
    • 前两部就是TLS/SSL的握手阶段,常用的密钥交换算法有RSA算法和ECODE算法
  • 双方采用会话密钥进行加密通讯

TLS/SSL的握手阶段

  • ClientHello
  • ServerHello
  • 客户端回应
  • 服务器最后回应

数字证书

  • 公钥
  • 持有者信息
  • CA信息
  • CA对这份文件的数字签名以及使用的算法
  • 证书有效期
  • 额外信息
  • 证书签发过程
    • CA将持有者的公钥、用途、颁发者、有效时间打包、对这些信息进行Hash计算,得到一个Hash
    • CA用自己的私钥将该Hash加密,生成Certificate Signature,也就是签名
    • 将Certificate Signature添加到文件证书上,形成数字证书
  • 证书检验过程
    • 使用同样的Hash算法获取该证书的Hash值H1
    • 用系统或者浏览器集成的CA公钥解密Certificate Signature的内容,得到Hash值H2
    • 比较H1和H2如果值相同,则为可信赖证书,否则认为证书不可信

RSA握手过程

  • Client Hello 第一次握手
    • 客户端向服务器发送TLS版本号支持的密码套件列表生成的随机数**(Client Random)
  • Server Hello 第二次握手
    • 确认TLS版本号是否支持从密码套件中选择一个,生成一个随机数**(Server Random)
      • 密码套件的组成:密钥交换算法+签名算法+对称加密算法+摘要算法
    • 发送Server Certificate 给客户端,该消息包含数字证书
    • 发送Server Hello Done,告知本次打招呼完毕
  • 第三次握手
    • 客户端生成一个随机数(pre-master),用服务器RSA*公钥加密该随机数,通过*Client Key Exchange消息传给服务器
    • 用Client Random、Server Random、pre-master生成会话密钥(master secret)后,客户端发送一个Change Cipher Spec 告诉服务端开始使用加密方式发送消息
    • 客户端在发送一个Encrypted Handshake MessageFinished****)把之前发送的数据做个摘要,使用会话密钥master secret加密,让服务器做验证,验证加密通信是否可以,之前的握手信息是否被篡改过
  • 第四次握手
    • 服务器发送 Change Cipher SpecEncrypted HandShake Message消息,如果双方都验证加密和解密没问题,握手正式完成
  • 缺陷:
    • 不支持前向加密
      • 一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通信密文都会被破解。

Linux 接收和发送网络包的流程

Linux接收网络包

当网卡接收到一个网络包后,会通过 DMA 技术,将网络包写入到指定的内存地址,也就是写入到 Ring Buffer ,这个是一个环形缓冲区,接着就会告诉操作系统这个网络包已经到达

那应该怎么告诉操作系统这个网络包已经到达了呢?

  • 最简单的一种方式就是触发中断,也就是每当网卡收到一个网络包,就触发一个中断告诉操作系统
    • 这存在一个问题,在高性能网络场景下,网络包的数量会非常多,那么就会触发非常多的中断
    • 解决方式:
      • NAPI 机制
        • 核心概念就是不采用中断的方式读取数据,而是首先采用中断唤醒数据接收的服务程序,然后 poll 的方法来轮询数据
  • 当有网络包到达时,会通过 DMA 技术,将网络包写入到指定的内存地址
  • 接着网卡向 CPU 发起硬件中断,当 CPU 收到硬件中断请求后,根据中断表,调用已经注册的中断处理函数
  • 硬件中断处理函数:
    • 需要先「暂时屏蔽中断」,表示已经知道内存中有数据了,告诉网卡下次再收到数据包直接写内存就可以了,不要再通知 CPU了,这样可以提高效率,避免 CPU 不停的被中断
    • 接着,发起「软中断」,然后恢复刚才屏蔽的中断
  • 软中断
    • 内核中的 ksoftirqd 线程专门负责软中断的处理,当 ksoftirqd 内核线程收到软中断后,就会来轮询处理数据。
    • ksoftirqd 线程会从 Ring Buffer 中获取一个数据帧,用 sk_buff 表示,从而可以作为一个网络包交给网络协议栈进行逐层处理
  • 网络协议栈
    • 首先,会进入到网络接口层,在这一层会检查报文的合法性,如果不合法则丢弃,合法则会找出该网络包的上层协议的类型,比如是 IPv4,还是 IPv6,接着再去掉帧头和帧尾,然后交给网络层
    • 到了网络层,则取出 IP 包,判断网络包下一步的走向,比如是交给上层处理还是转发出去。当确认这个网络包要发送给本机后,就会从 IP 头里看看上一层协议的类型是 TCP 还是 UDP,接着去掉 IP 头,然后交给传输层
    • 传输层取出 TCP 头或 UDP 头,根据四元组「源 IP、源端口、目的 IP、目的端口」 作为标识,找出对应 的 Socket,并把数据放到 Socket 的接收缓冲区
    • 最后,应用层程序调用 Socket 接口,将内核的 Socket 接收缓冲区的数据「拷贝」到应用层的缓冲区,然后唤醒用户进程

Linux 发送网络包的流程

发送网络包的流程正好和接收流程相反

  • 首先,应用程序会调用 Socket 发送数据包的接口,由于这个是系统调用,所以会从用户态陷入到内核态中的 Socket 层
    • 内核会申请一个内核态的 sk_buff 内存,将用户待发送的数据拷贝到 sk_buff 内存并将其加入到发送缓冲区
  • 接下来,网络协议栈从 Socket 发送缓冲区中取出 sk_buff,并按照 TCP/IP 协议栈从上到下逐层处理
    • TCP 传输协议
      • 先拷贝一个新的 sk_buff 副本 ,这是因为 sk_buff 后续在调用网络层,最后到达网卡发送完成的时候,这个 sk_buff 会被释放掉。而 TCP 协议是支持丢失重传的
        • 在收到对方的 ACK 之前,这个 sk_buff 不能被删除。所以内核的做法就是每次调用网卡发送的时候,实际上传递出去的是 sk_buff 的一个拷贝,等收到 ACK 再真正删除
  • 接着,对 sk_buff 填充 TCP 头。这里提一下,sk_buff 可以表示各个层的数据包,在应用层数据包叫 data,在 TCP 层我们称为 segment,在 IP 层我们叫 packet,在数据链路层称为 frame
    • 为了在层级之间传递数据时,不发生拷贝,只用 sk_buff 一个结构体来描述所有的网络包
    • 通过调整 sk_buff 中 data 的指针
      • 当接收报文时,从网卡驱动开始,通过协议栈层层往上传送数据报,通过增加 skb->data 的值,来逐步剥离协议首部
      • 当要发送报文时,创建 sk_buff 结构体,数据缓存区的头部预留足够的空间,用来填充各层首部,在 经过各下层协议时,通过减少 skb->data 的值来增加协议首部
  • 然后交给网络层,在网络层里会做这些工作:选取路由(确认下一跳的 IP)、填充 IP 头、netfilter 过滤、对超过 MTU 大小的数据包进行分片
    • 网络接口层会通过 ARP 协议获得下一跳的 MAC 地址,然后对 sk_buff 填充帧头和帧尾,接着将 sk_buff 放到网卡的发送队列中
  • 这些工作准备好后,会触发「软中断」告诉网卡驱动程序,这里有新的网络包需要发送,驱动程序会从发送队列中读取 sk_buff,将这个 sk_buff 挂到 RingBuffer 中,接着将 sk_buff 数据映射到网卡可访问的内存 DMA 区域,最后触发真实的发送
  • 当发送完成的时候,网卡设备会触发 一个硬中断来释放内存,主要是释放 sk_buff 内存和清理 RingBuffer 内存
  • 最后,当收到这个 TCP 报文的 ACK 应答时,传输层就会释放原始的 sk_buff

发送网络数据的时候,涉及几次内存拷贝操作?

  • 第一次,调用发送数据的系统调用的时候,内核会申请一个内核态的 sk_buff 内存,将用户待发送的数据 拷贝到 sk_buff 内存,并将其加入到发送缓冲区
  • 第二次,在使用 TCP 传输协议的情况下,从传输层进入网络层的时候,每一个 sk_buff 都会被克隆一个新的 副本出来。副本 sk_buff 会被送往网络层,等它发送完的时候就会释放掉,然后原始的 sk_buff 还保留在 传输层,目的是为了实现 TCP 的可靠传输,等收到这个数据包的 ACK 时,才会释放原始的 sk_buff
  • 当 IP 层发现 sk_buff 大于 MTU 时才需要进行。会再申请额外的 sk_buff,并将原来的 sk_buff 拷贝为多个小的 sk_buff

HTTP 常见面试题

HTTP 基本概念

HTTP常见的状态码:

  • 1xx 协议处理中间状态,还需后续操作
  • 2xx 成功,报文收到,并正确处理
    • 200 OK ,一切正常,如果是非HEAD请求,服务器返回的响应头都会有body数据
    • 204 NO CONTENT 一切正常,响应头无Body数据
    • 206 Partial Content 用于HTTP分块下载或断点续传,表示响应返回的body数据不是资源的全部,而是一部分
  • 3xx 重定向,资源位置发生变动,需要客户端重新请求
    • 301 Moved permanently 永久重定向,请求的资源不在,需要用新的URL再次访问呢
    • 302 Found 临时重定向,请求的资源还在,暂时需要另一个URL访问
      • 301 302 在响应头中的Location字段,指明了后续要跳转的URL
    • 304 Not Modified 不跳转,表示资源未修改,重定向缓存文件
  • 4xx 客户端错误,请求报文有误,服务器无法处理
    • 400 Bad Request 客户端请求报文有误
    • 403 Forbidden 服务器禁止访问资源
    • 404 Not Found 请求的资源在服务器上找不到
  • 5xx 服务器错误,服务器在处理请求时内部发生了错误
    • 500 Internal Server Error 笼统的错误码,表示服务器出错
    • 501 Not Implemented 客户端请求的功能还不支持
    • 502 Bad Gateway 服务器作为网关或者代理时返回的错误码,服务器工作正常,访问后端时发生错误
    • 503 Service Unavailable 服务器当前忙,无法响应客户端

HTTP常见字段

  • Host:发送请求,指定服务器的域名
  • Content-Length: 本次回复的数据长度,作为HTTP body的边界,搭配回车符、换行符作为HTTP header的边界,用于解决粘包问题
  • Connection: 客户端要求服务器使用 HTTP长连接,指定值为 Keep-Alive
  • Content-Type: 用于服务器回应,告诉客户端,本次数据是什么格式
  • Accept: 用于请求,表示自己接受哪些数据格式
  • Content-Encoding: 表明服务器返回的数据使用了什么压缩格式
  • Accept-Encoding: 说明自己可以接收哪些压缩方法

安全和幂等

  • 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源
  • 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的

HTTP缓存实现方式:

  • 强制缓存
    • 只要缓存未过期,就直接使用浏览器本地缓存,浏览器主动决定
    • 实现方式:
      • Cache-Control:相对过期时间(优先级高)
      • Expires:绝对过期时间
  • 协商缓存
    • 客户端与服务器协商后,通过协商结果判断是否使用本地缓存
    • 实现方式:
      • 第一种
        • 请求头 if-Modified-Since,资源过期后,带上Last-Modified的值,用于服务器判断资源是否被修改
        • 响应头 Last-Modified,资源最后修改时间
      • 第二种
        • 请求头 if-None-Match:资源过去,该头带上Etag值,用于服务器判断资源是否过期
        • 响应头 Etag:唯一标识响应资源
      • Etag优先级高于Last-Modified
        • 即便没有修改文件,文件的最后修改日期也可能变
        • 有些文件是以秒为单位修改的,if-Modified-Since只能检测s为单位的修改,Etag可以检测一秒内的多次修改
        • 有些服务器不能精确获取修改时间
    • 协商缓存需要配合Cache-Control来使用,只有未命中强制缓存,才使用协商缓存

HTTP特点

  • 简单
  • 易于拓展
  • 跨平台
  • 缺点
    • 无状态
    • 明文传输
    • 不安全
  • HTTP 1.1
    • 长连接
    • 管道网络传输
      • 客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间(长连接实现)
    • 解决了请求的队头阻塞,但没有解决响应的队头阻塞

HTTP1.0和HTTP1.1的区别

  • 默认连接方式改为长连接
  • 增加了更多了响应状态码
  • 增加了更多的缓存策略,类似Etag
  • 在请求头加入了range,允许只请求资源的某个部分
  • 引入了Host字段,允许在同一IP地址上托管多个域名

HTTP1.1和HTTP2.0的区别

  • 实现了连接的多路复用,解决了队头阻塞的问题
    • 针对不同的 HTTP 请求用独一无二的 Stream ID 来区分,接收端可以通过 Stream ID 有序组装成 HTTP 消息,不同 Stream 的帧是可以乱序发送的,因此可以并发不同的 Stream,也就是HTTP/2可以并行交错地发送请求和响应
  • 使用二进制帧进行数据传输,而HTTP1.1之前采用文本传输
  • 支持头部压缩,使用HPACK算法
  • 支持服务器推送,可以在客户端请求的时候,将相关资源一并推送
    • 客户端和服务器双方都可以建立 Stream,Stream ID 也是有区别的,客户端建立的 Stream 必须是奇数号,而服务器建立的 Stream 必须是偶数号

HTTP2.0和HTTP3.0的区别

  • 使用QUIC传输协议来实现
  • 连接建立更快,只需要0/1个RTT
    • HTTP/3的QUIC协议并不是与TLS分层,而是QUIC内部包含了TLS,它在自己的帧会携带TLS里的“记录”,再加上QUIC使用的是TLS/1.3,因此仅需1个RTT就可以「同时」完成建立连接与密钥协商
  • 使用QUIC,解决了TCP导致的队头阻塞
    • QUIC有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题
  • 可以不依赖TCP的错误恢复机制,更快的进行恢复和重传
  • 使用QUIC进行加密,提供更强的安全性
  • 连接迁移
    • 通过连接 ID 来标记通信的两个端点,客户端和服务器可以各自选择一组ID来标记自己,因此即使移动设备的网络变化后,导致IP地址变化了,只要仍保有上下文信息(比如连接 ID、TLS密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能

HTTP和HTTPS区别

  • TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输
  • 还需进行 SSL/TLS 的握手过程,才可进入加密报文传输
  • HTTP 默认端口号是 80,HTTPS 默认端口号是 443
  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的

HTTP问题

  • 窃听风险
    • 信息加密
      • 混合加密的方式实现信息的机密性
  • 篡改风险
    • 检验机制
      • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险
  • 冒充风险
    • 身份证书
      • 将服务器公钥放入到数字证书中,解决了冒充的风险

混合加密

  • 在通信建立前使用非对称加密的方式交换会话密钥,后续不再使用非对称加密
    • 公钥和私钥,公钥可以任意分发,私钥保密,解决了密钥交换问题但速度慢
  • 通信过程中使用对称加密的会话密钥,加密明文数据
    • 运算速度快,无法做到安全的密钥交换

摘要算法和数字签名

  • 使用摘要算法(哈希函数)计算出内容的哈希值,哈希值是唯一的,且无法通过哈希值推导出内容
    • 只能保证内容不会被篡改,但是不能保证内容不能被替换
  • 非对称加密
    • 公钥和私钥,这两个密钥可以双向加解密
      • 公钥加密,私钥解密,保证传输内容的安全
      • 私钥加密,公钥解密,保证消息不会被冒充,如果公钥能正常解密出私钥加密的内容,就可以证明这个消息是持有私钥身份的人发送的
        • 私钥加密不是对内容加密,而是对内容的哈希值加密

数字证书

CA 签发证书的过程

  • 数字证书认证机构(CA),首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行Hash 计算,得到一个 Hash 值,CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名。最后将 Certificate Signature 添加在文件证书上,形成数字证书

客户端校验服务端的数字证书的过程

  • 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
  • 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密

Certificate Signature 内容,得到一个 Hash 值 H2

  • 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信

SSL/TLS协议基本流程

  • 客户端要服务器索要并验证服务器的公钥
  • 双方协商产生会话密钥
    • 前两部就是TLS/SSL的握手阶段,常用的密钥交换算法有RSA算法和ECODE算法
  • 双方采用会话密钥进行加密通讯

TLS/SSL的握手阶段

  • ClientHello
  • ServerHello
  • 客户端回应
  • 服务器最后回应

数字证书

  • 公钥
  • 持有者信息
  • CA信息
  • CA对这份文件的数字签名以及使用的算法
  • 证书有效期
  • 额外信息
  • 证书签发过程
    • CA将持有者的公钥、用途、颁发者、有效时间打包、对这些信息进行Hash计算,得到一个Hash值
    • CA用自己的私钥将该Hash加密,生成Certificate Signature,也就是签名
    • 将Certificate Signature添加到文件证书上,形成数字证书
  • 证书检验过程
    • 使用同样的Hash算法获取该证书的Hash值H1
    • 用系统或者浏览器集成的CA公钥解密Certificate Signature的内容,得到Hash值H2
    • 比较H1和H2如果值相同,则为可信赖证书,否则认为证书不可信

RSA握手过程

  • Client Hello 第一次握手
    • 客户端向服务器发送TLS版本号、支持的密码套件列表、生成的随机数(Client Random)
  • Server Hello 第二次握手
    • 确认TLS版本号是否支持,从密码套件中选择一个,生成一个随机数(Server Random)
      • 密码套件的组成:密钥交换算法+签名算法+对称加密算法+摘要算法
    • 发送Server Certificate 给客户端,该消息包含数字证书
    • 发送Server Hello Done,告知本次打招呼完毕
  • 第三次握手
    • 客户端生成一个随机数**(pre-master),用服务器RSA公钥加密该随机数,通过Client Key Exchange**消息传给服务器
    • 用Client Random、Server Random、pre-master生成会话密钥(master secret)后,客户端发送一个Change Cipher Spec 告诉服务端开始使用加密方式发送消息
    • 客户端在发送一个Encrypted Handshake MessageFinished****)把之前发送的数据做个摘要,使用会话密钥master secret加密,让服务器做验证,验证加密通信是否可以,之前的握手信息是否被篡改过
  • 第四次握手
    • 服务器发送 Change Cipher SpecEncrypted HandShake Message消息,如果双方都验证加密和解密没问题,握手正式完成
  • 缺陷:
    • 不支持前向加密
      • 一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通信密文都会被破解。

HTTPS 的应用数据是如何保证完整性的

  • 握手协议
    • TLS 握手协议就是我们前面说的 TLS 四次握手的过程,负责协商加密算法和生成对称密钥,后续用此 密钥来保护应用程序数据
  • 记录协议
    • TLS 记录协议负责保护应用程序数据并验证其完整性和来源,所以对 HTTP 数据加密是使用记录协议
    • 具体过程如下:
      • 首先,消息被分割成多个较短的片段,然后分别对每个片段进行压缩
      • 接下来,经过压缩的片段会被加上消息认证码(MAC 值,这个是通过哈希算法生成的这是为了保证完整性,并进行数据的认证
      • 再接下来,经过压缩的片段再加上消息认证码会一起通过对称密码进行加密
      • 最后,上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据。记录协议完成后,最终的报文数据将传递到传输控制协议 (TCP) 层进行传输

TCP

TCP的头部

image-20240811182415087

  • TCP首部结构先是16位的源端口号和目标端口号、接着是32位的序列号和确认号。再下面就是4bit的头部长度和6个bit的保留位及6bit的标志位
    • 序列号:它是TCP报文段的一数字编号,为保证TCP可靠连接,每一个发送的数据段都要加上序列号。建立连接时,两端都会随机生成一个初始序列号。而确认号而是和序列号配合使用的应答某次请求时,则返回一个确认号,它的值等于对方请求序列号加1
    • 6个标志位
      • URG:这是条紧急信息
      • ACK:应答消息
      • PSH:缓冲区尚未填满
      • RST:重置连接
      • SYN:建立连接消息标志
      • FIN:连接关闭通知信息
  • 16位的属性则有窗口大小(控制发送窗口),检验和(校验数据段是否未被修改)及紧急指针。最后是选项,其长度由头部长度决定
    • 窗口大小是接收端用来控制发送端的滑动窗口大小

TCP和UDP有什么区别

  • 连接方面TCP面向连接。UDP是无连接的,发送数据之前不需要建立连接
  • 安全方面
    • TCP提供可靠的服务,保证传送的数据,无差错,不丢失,不重复,且按序到达
    • UDP则是尽最大努力交付,不保证可靠交付
  • 传输效率TCP传输效率相对较低,UDP传输效率高

TCP是可靠的连接,它是怎么实现的

  • TCP的连接是基于三次握手,而断开则是四次挥手
  • 为了保障数据不丢失及错误(可靠性)
    • 报文校验
    • ACK应答
    • 超时重传(发送方)
    • 失序数据重传(接收方)
    • 丢弃重复数据
    • 流量控制(滑动窗口)和拥塞控制等机制

三次握手和四次挥手机制

image-20240811182422377

  • 关闭连接时需要四次挥手,比建立时多一次,是因为被动关闭端或许还有数据没被送出去,不能像握手时一样,第二次握手既是发起握手也是响应握手

如果没有三次握手会有什么问题呢

  • 只有两次握手,client发连接请求后不会再ACK服务端的SYN
  • 此时若客户端因为自身原因判断建立连接失败可能会重复建立TCP连接,而服务端却会认为那些被client丢弃的TCP还是有效,会白白浪费资源

TIME_WAIT和CLOSE_WAIT的区别在哪

image-20240811182432701

  • CLOSE_WAIT是被动关闭形成的;当对方close socket而发送FIN报文过来时,回应ACK之后进入CLOSE_WAIT状态。随后检查是否存在未传输数据,如果没有则发起第三次挥手,发送FIN报文给对方,进入LAST_ACK状态并等待对方ACK报文到来
  • TIME_WAIT是主动关闭连接方式形成的;处于FIN_WAIT_2状态时,收到对方FIN报文后进入TIME_WAIT状态;之后再等待两个MSL(Maximum Segment Lifetime:报文最大生存时间)

TIME_WAIT的作用呢,还有为啥状态时间要保持两个MSL

  • TIME_WAIT的作用是为了保证最后一次挥手的ACK报文能送达给对方,如果ACK丢失,对方会超时重传FIN,主动关闭端会再次响应ACK过去;如果没有TIME_WAIT状态,直接关闭,对方重传的FIN报文则被响应一个RST报文,此RST会被动关闭端被解析成错误
  • 存在两个连接,第一个连接正常关闭,第二相同的连接紧接着建立;如果第一个连接的迷路报文到来,则会干扰第二连接,等待两个MSL则可以让上次连接的报文数据消逝在网络后,防止之后建立的相同的连接收到之前旧连接的响应报文

拥塞控制,TCP协议用什么方式去解决拥塞的

  • 第一方式是慢启动和拥塞避免
    • 慢启动,TCP发送端会维护一个拥塞窗口(congestionwindow),简称为cwnd。拥塞窗口初始为1个报文段,每经过一次RTT(数据完全发送完到确认的时间),窗口大小翻倍(指数增长,只是前期慢)
    • 拥塞避免,它思路是让拥塞窗口cwnd缓慢增大,发送方的cwnd达到阀值ssthresh(初始值由系统决定的)之后,每经过一个RTT就把拥塞窗口加一,而不是加倍(收到两个或四个确认,都是cwnd+1),cwnd呈线性增加(加法增大)
    • 如果遇到网络拥塞,拥塞窗口阀值ssthresh为cwnd减半,cwnd设置为1,重新进入慢启动阶段
    • image-20240811182440303

拥塞控制还有其他什么方式呢

  • 快重传快恢复
    • 快重传是当接收方收到了一个失序的报文,则立马报告给发送方,赶紧重传
      • 假如接收方M1收到了,M2没有收到,之后的M3、M4、M5又发送了,此时接收方一共连续给发送方反馈了3个M1确认报文。那么快重传规定,发送方只要连续收到3个重复确认,立即重传对方发来的M2(重复确认报文的后一个报文)
    • 快恢复
      • 当发送方连续收到三个重复确认,ssthresh减半;由于发送方可能认为网络现在没有拥塞,因此与慢启动不同,把cwnd值设置为ssthresh减半之后的值,然后执行拥塞避免算法,cwnd线性增大
      • image-20240811182454014

客户端和服务端控制滑动窗口的过程是怎样的

  • 收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK报文来通知发送端,滑动窗口是接收端用来控制发送端发送数据的大小,从而达到流量控制
  • 其实发送方的窗口上限,是取值拥塞窗口和滑动窗口两者的最小值

滑动窗口和拥塞窗口有什么区别不

  • 相同点:控制丢包现象,实现机制都是让发送方发得慢一点
  • 不同点在于控制的对象不同
    • 流量控制的对象是接收方,怕发送方发的太快,使得接收方来不及处理
    • 拥塞控制的对象是网络,怕发送方发的太快,造成网络拥塞,使得网络来不及处理

TCP的粘包和拆包问题

  • 程序需要发送的数据大小和TCP报文段能发送MSS(Maximum Segment Size,最大报文长度)是不一样的
  • 大于MSS时,而需要把程序数据拆分为多个TCP报文段,称之为拆包;小于时,则会考虑合并多个程序数据为一个TCP报文段,则是粘包;其中MSS = TCP报文段长度-TCP首部长度
  • 在IP协议层或者链路层、物理层,都存在拆包、粘包现象

解决粘包和拆包的方法都有哪些

  • 在数据尾部增加特殊字符进行分割
  • 数据定为固定大小
  • 数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小

SYN Flood了解吗

  • SYN Flood 伪造 SYN 报文向服务器发起连接,服务器在收到报文后用 SYN_ACK 应答,此应答发出去后,不会收到 ACK 报文,造成一个半连接
  • 若攻击者发送大量这样的报文,会在被攻击主机上出现大量的半连接,耗尽其资源,使正常的用户无法访问,直到半连接超时

一次HTTP请求,程序一般经历了哪几个步骤?

  • 解析域名
  • 发起TCP三次握手,建立连接
  • 基于TCP发起HTTP请求
  • 服务器响应HTTP请求,并返回数据
  • 客户端解析返回数据

image-20240811182501793

HTTP有哪几种响应状态码,列举几个你熟悉的

  • 200:表示成功正常请求
  • 400:语义有误,一般是请求格式不对
  • 401:需求用户验证权限,一般是证书token没通过认证
  • 403:拒绝提供服务
  • 404:资源不存在
  • 500:服务器错误
  • 503:服务器临时维护,过载;可恢复

session和cookie有什么区别

  • 存储位置不同,cookie是保存在客户端的数据;session的数据存放在服务器上
  • 存储容量不同,单个cookie保存的数据小,一个站点最多保存20个Cookie;对于session来说并没有上限
  • 存储方式不同,cookie中只能保管ASCII字符串;session中能够存储任何类型的数据
  • 隐私策略不同,cookie对客户端是可见的;session存储在服务器上,对客户端是透明的
  • 有效期上不同,cookie可以长期有效存在;session依赖于名为JSESSIONID的cookie,过期时间默认为-1,只需关闭窗口该session就会失效
  • 跨域支持上不同,cookie支持跨域名访问;session不支持跨域名访问

了解什么是HTTP分块传送吗

  • 分块传送是HTTP的一种传输机制,允许服务端发送给客户端的数据分成多个部分,该协议在HTTP/1.1提供

什么好处

  • HTTP分块传输编码允许服务器为动态生成的内容维持HTTP持久连接
  • 分块传输编码允许服务器在最后发送消息头字段。对于那些头字段值在内容被生成之前无法知道的情形非常重要,例如消息的内容要使用散列进行签名
  • HTTP服务器有时使用压缩(gzip或deflate)以缩短传输花费的时间。分块传输编码可以用来分隔压缩对象的多个部分。在这种情况下,块不是分别压缩的,而是整个负载进行压缩。分块编码有利于一边进行压缩一边发送数据

HTTP的长连接你怎么理解

  • 长连接是指客户端和服务建立TCP连接后,它们之间的连接会持续存在,不会因为一次HTTP请求后关闭,后续的请求也是用这个连接
  • 长连接可以省去TCP的建立和关闭操作,对于频繁请求的客户端适合使用长连接,但是注意恶意的长连接导致服务受损

HTTP是安全的吗?怎么做到安全的HTTP协议传输

  • 并非安全,HTTP传输的数据都是明文的,容易被第三方截取;要做安全传输数据,可以使用HTTP的升级版HTTPS协议

HTTPS和HTTP的区别,你是怎么理解的

  • http协议的连接是无状态的,明文传输
  • HTTPS则是由SSL/TLS+HTTP协议构建的有加密传输、身份认证的网络协议

SSL/TLS是什么,HTTPS的安全性是怎样实现的?

  • SSL(Secure Socket Layer 安全套接层)是基于HTTPS下的一个协议加密层,保障数据私密性。TLS(Transport Layer Security)则是升级版的SSL
  • https在http基础加了一层安全认证及加密层TLS或者SSL,它首先会通过安全层进行ca证书认证,正确获取服务端的公钥
  • 客户端会通过公钥和服务端确认一种加密算法,后面的数据则可以使用该加密算法对数据进行加密

MTU

  • 最大传输单元,链路层的帧中的数据部分的最大字节数,以太网中的一般为1500字节。

MSS

  • 最大报文段大小,TCP的报文段中的数据部分的最大字节数,MTU减去IPv4的Header和TCP的Header。IPv4的Header和TCP的Header一般都是20字节,则MSS=1500-20-20 = 1460字节

MSL

  • 报文最大生存时间,报文在网络上存在的最长时间,TCP连接必须经过时间2MSL后才真正释放掉。Windows默认MSL为2分钟。

RTT

  • 往返时间。

TTL

  • 表示IP数据报在网络中的寿命,其单位为秒。在目前的实际应用中,常以“跳”为单位。该字段指定IP包被路由器丢弃之前允许通过的最大网段数量。