应用层

HTTPS

https是如何防范中间人的攻击?

  • 加密:https 握手期间会通过非对称加密的方式来协商出对称加密密钥。
  • 身份校验:服务器会向证书颁发机构申请数字证书,证书中包含了服务器的公钥和其他相关信息。当客户端与服务器建立连接时,服务器会将证书发送给客户端。客户端会验证证书的合法性,包括检查证书的有效期、颁发机构的信任等。如果验证通过,客户端会使用证书中的公钥来加密通信数据,并将加密后的数据发送给服务器,然后由服务端用私钥解密。

中间人攻击的关键在于攻击者冒充服务器与客户端建立连接,并同时与服务器建立连接。但由于攻击者无法获得服务器的私钥,因此无法正确解密客户端发送的加密数据。同时,客户端会在建立连接时验证服务器的证书,如果证书验证失败或存在问题,客户端会发出警告或中止连接。

讲一下 TLS RSA 四次握手过程

HTTPS 在 HTTP 与 TCP 层之间加入了 TLS

  • 第一次
    • 客户端发送 Client Hello,消息包含 TLS 版本,支持的密码套件列表和生成的随机数(Client Random)
  • 第二次
    • 服务端收到后会确认 TLS 版本,给出随机数(Server Random),选择合适的密码套件,并返回 Server Hello
    • 服务端发送 Server Certificate 含有数字证书证明身份
    • 服务端发送 Server Hello Done 握手完毕
  • 客户端验证
  • 第三次
    • 客户端生成新随机数(Pre-master),用服务器公钥加密,发送 Client Key Exchange
    • 服务器私钥解密 Pre-master
    • 客户端发送 Change Cipher Spec 告诉服务端开始加密消息
    • 客户端发送 Encrypted Handshake Message (Finished),把之前的消息做一个摘要让服务端验证
  • 第四次
    • 服务端发送 Change Cipher SpecEncrypted Handshake Message

HTTP/*

HTTP/2 有什么变化

  • 头部压缩:静态/动态压缩 Headers
  • 二进制帧
  • 并发传输
  • 服务器主动推送资源

传输层

TCP 的三次握手过程说一下

  • 一开始,客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态
  • 客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态。
  • 服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。
  • 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务端的数据,之后客户端处于 ESTABLISHED 状态。
  • 服务端收到客户端的应答报文后,也进入 ESTABLISHED 状态。

为什么是三次握手?不是两次、四次?

  • 三次握手才可以阻止重复历史连接的初始化(主要原因)
    • 对比期望受到的 ACK NUM 即可
  • 三次握手才可以同步双方的初始序列号
  • 三次握手才可以避免资源浪费

四次挥手的各个状态说一下

  • 客户端主动调用关闭连接的函数,于是就会发送 FIN 报文,这个 FIN 报文代表客户端不会再发送数据了,进入 FIN_WAIT_1 状态;
  • 服务端收到了 FIN 报文,然后马上回复一个 ACK 确认报文,此时服务端进入 CLOSE_WAIT 状态。在收到 FIN 报文的时候,TCP 协议栈会为 FIN 包插入一个文件结束符 EOF 到接收缓冲区中,服务端应用程序可以通过 read 调用来感知这个 FIN 包,这个 EOF 会被放在已排队等候的其他已接收的数据之后,所以必须要得继续 read 接收缓冲区已接收的数据;
  • 接着,当服务端在 read 数据的时候,最后自然就会读到 EOF,接着 read() 就会返回 0,这时服务端应用程序如果有数据要发送的话,就发完数据后才调用关闭连接的函数,如果服务端应用程序没有数据要发送的话,可以直接调用关闭连接的函数,这时服务端就会发一个 FIN 包,这个 FIN 报文代表服务端不会再发送数据了,之后处于 LAST_ACK 状态;
  • 客户端接收到服务端的 FIN 包,并发送 ACK 确认包给服务端,此时客户端将进入 TIME_WAIT 状态;
  • 服务端收到 ACK 确认包后,就进入了最后的 CLOSE 状态;
  • 客户端经过 2MSL 时间之后,也进入 CLOSE 状态;

为什么断开连接是四次挥手?

服务器收到客户端的 FIN 报文时,内核会马上回一个 ACK 应答报文,但是服务端应用程序可能还有数据要发送,所以并不能马上发送 FIN 报文,而是将发送 FIN 报文的控制权交给服务端应用程序

  • 如果服务端应用程序有数据要发送的话,就发完数据后,才调用关闭连接的函数;
  • 如果服务端应用程序没有数据要发送的话,可以直接调用关闭连接的函数,

从上面过程可知,是否要发送第三次挥手的控制权不在内核,而是在被动关闭方的应用程序,因为应用程序可能还有数据要发送,由应用程序决定什么时候调用关闭连接的函数,当调用了关闭连接的函数,内核就会发送 FIN 报文了,所以服务端的 ACK 和 FIN 一般都会分开发送。

SYN

  • SYN 攻击 / SYN Flood:当服务端接收到客户端的 SYN 报文时,会创建一个半连接的对象,然后将其加入到内核的「 SYN 队列」
  • SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满,这样当 TCP 半连接队列满了,后续再在收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接。
  • 防止措施
    • 调大 netdev_max_backlog
    • 增大 TCP 半连接队列:
    • 开启 tcp_syncookies
    • 减少 SYN+ACK 重传次数:

网络层

网络层的主要作用是:实现主机与主机之间的通信,也叫点对点(end to end)通信。

IP

IP 的作用是主机之间通信用的,而数据链路层 MAC 的作用则是实现「直连」的两个设备之间通信,而 IP 则负责在「没有直连」的两个网络之间进行通信传输。

无分类地址 CIDR

网络号和主机号

子网掩码 网络号 主机号

表示形式 a.b.c.d/x,其中 /x 表示前 x 位属于网络号, x 的范围是 0 ~ 32

将子网掩码和 IP 地址按位计算 AND,就可得到网络号。

子网掩码怎么算

子网掩码 CIDR

Misc

描述一下打开百度首页后发生的网络过程

  • URL 进行解析,解析出域名、方法、资源等,然后生成 http 请求报文。

  • 对域名进行 dns 解析,首先会看浏览器和操作系统是否有 dns 解析的缓存,如果没有的话,就会通过dns 解析,dns 解析过程:

  • 发起DNS查询:当用户在浏览器中输入一个域名(如www.baidu.com)后,操作系统会首先检查本地的DNS缓存,如果有对应的IP地址,则直接返回结果。如果缓存中没有对应的IP地址,操作系统会向本地DNS服务器发送一个DNS查询请求。

  • 本地DNS服务器查询:本地DNS服务器收到DNS查询请求后,会先检查自己的缓存,如果有对应的IP地址,则直接返回结果给操作系统。如果本地DNS服务器没有缓存对应的IP地址,它会向根DNS服务器发送一个迭代查询请求。

  • 根DNS服务器查询:根DNS服务器是顶级DNS服务器,它存储了全球顶级域名服务器的信息。当根DNS服务器收到迭代查询请求后,它会根据请求的顶级域名(如.com)返回对应的顶级域名服务器的IP地址给本地DNS服务器。

  • 顶级域名服务器查询:本地DNS服务器收到根DNS服务器返回的顶级域名服务器的IP地址后,会向顶级域名服务器发送查询请求。顶级域名服务器根据请求的域名(如baidu.com)返回该域名对应的权威域名服务器的IP地址。

  • 权威域名服务器查询:本地DNS服务器收到顶级域名服务器返回的权威域名服务器的IP地址后,会向权威域名服务器发送查询请求。权威域名服务器是负责管理该域名下所有主机记录的服务器,它会根据请求的域名返回对应的主机记录的IP地址。

  • 返回结果:本地DNS服务器收到权威域名服务器返回的主机记录的IP地址后,会将结果返回给操作系统。操作系统将IP地址返回给浏览器,浏览器根据IP地址建立与服务器的TCP连接,并发起HTTP请求。

  • 建立TCP连接:浏览器使用HTTP协议通过TCP/IP建立与百度服务器的连接。它会向百度服务器发送一个SYN(同步)包,然后等待百度服务器的确认响应。

  • 三次握手:百度服务器收到浏览器发送的SYN包后,会发送一个SYN+ACK(同步确认)包给浏览器,表示接受连接请求。浏览器收到百度服务器的响应后,会发送一个ACK(确认)包给服务器,完成三次握手,建立可靠的连接。

  • 发送HTTP请求:浏览器向百度服务器发送一个HTTP请求,请求百度首页的HTML文档。请求中包含了请求方法、请求头和其他相关信息。

  • 服务器处理请求:百度服务器接收到浏览器发送的HTTP请求后,会根据请求的内容进行处理。它可能会读取数据库、执行相关的业务逻辑,并生成响应数据。

  • 发送HTTP响应:百度服务器将生成的响应数据封装成HTTP响应报文,并发送回浏览器。响应报文中包含了响应状态码、响应头和响应体等信息。

  • 接收响应和渲染页面:浏览器接收到百度服务器发送的HTTP响应后,会解析响应报文,提取出HTML文档和其他相关资源。浏览器会根据HTML文档的结构和CSS样式,渲染出页面的可视化效果。

  • 关闭TCP连接:当浏览器完成页面渲染后,会关闭与百度服务器的TCP连接。它会发送一个FIN(结束)包给服务器,表示关闭连接请求。百度服务器收到请求后,会发送一个ACK包给浏览器,表示接受关闭连接请求。最终,浏览器和服务器都关闭了TCP连接。