深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 2

备注

因为文章太长,所以将它分为三部分,本文是第二部分。

第一部分深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 1

第二部分深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 2

第三部分深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 3

TCP连接

DNS解析返回域名的IP之后,接下来就是浏览器要和该IP建立TCP连接了。为什么是TCP而不是UDP?那是因为HTTP是基于TCP上的。这里涉及到另外一个话题:TCP/IP 模型。这个已经在大学的课本上学过了,我们再复习一下。
 

TCP/IP模型

TCP/IP模型一般分为4层,下面是我用PPT画的。
在这里不得不说OSI七层参考模型,它和TCP/IP模型的区别和联系,继续用PPT画,见下图:

不多解释,OSI的7/6/5层和TCP/TP的应用层对应,2/1层和链路层对应。在实际的应用中,主要还是TCP/IP概念模型,后面的内容主要讲它。

这些都是课本上的,也许忘了(毕竟不是天天用到这些嘛),没关系,我们以最简单的方式来讲解。为了便于理解每层的含义和作用,先看每层有哪些协议,看看有没有自己熟悉的协议。有熟悉的协议,先体会一下。

应用层
我们可以看到,有常用的HTTP/HTTPS/IMAP/SSH/Telnet等都在应用层上(题外话,这一层你用的协议越多,说明你知识越开阔)。相信每个人都用过HTTP/HTTPS,所以我上面说HTTP/HTTP是基于TCP上的。
Wikipedia 这么解释:
The application layer is the scope within which applications create user data and communicate this data to other applications on another or the same host. The applications, or processes, make use of the services provided by the underlying, lower layers, especially the Transport Layer which provides reliable or unreliable pipesto other processes. The communications partners are characterized by the application architecture, such as the client-server model and peer-to-peer networking. This is the layer in which all higher level protocols, such as SMTP, FTP, SSH, HTTP, operate. Processes are addressed via ports which essentially represent services.
 
传输层
没错,最常见的TCP和UDP就在这里,TCP三次握手也在这里。
Wikipedia 这么解释:
The transport layer performs host-to-host communications on either the same or different hosts and on either the local network or remote networks separated by routers.[22] It provides a channel for the communication needs of applications. UDP is the basic transport layer protocol, providing an unreliable datagram service. The Transmission Control Protocol provides flow-control, connection establishment, and reliable transmission of data.
 
IP层
IP层非常重要,可能这么说还不太懂,看看其他协议。大家知道ICMP吗?估计很多人还是说不上来ICMP是什么东西。大家肯定用过ping命令吧,它就是用的ICMP。说到这里,应该有感性的认识了吧。
Wikipedia 这么解释:
The internet layer exchanges datagrams across network boundaries. It provides a uniform networking interface that hides the actual topology (layout) of the underlying network connections. It is therefore also referred to as the layer that establishes internetworking. Indeed, it defines and establishes the Internet. This layer defines the addressing and routing structures used for the TCP/IP protocol suite. The primary protocol in this scope is the Internet Protocol, which defines IP addresses. Its function in routing is to transport datagrams to the next IP router that has the connectivity to a network closer to the final data destination.
 
链路层
这个非常底层了,ARP,NDP,Ethernet都很常见,如果认真看过HTTP抓包,熟悉LVS,Ngnix等提供的负载均衡,应该对ARP不陌生,是的ARP用来查找设备的MAC地址,在LVS做负载均衡时会用到,因为进来的stream的包MAC地址要和出去的Stream包的MAC地址保持一致,因为做负载均衡,有可能会变化,如何解决这个问题,则不在本文的讨论范围内,如有兴趣可以参看LVS的文档。
Wikipedia 这么解释:
The link layer defines the networking methods within the scope of the local network link on which hosts communicate without intervening routers. This layer includes the protocols used to describe the local network topology and the interfaces needed to effect transmission of Internet layer datagrams to next-neighbor hosts.

 

TCP/IP抓包分析

看了前面的内容,还是觉得抽象吗?如果是,不要紧,也在预期内。让我们抓个包,分析认识一下就清楚了。
 
先访问www.qq.com 这个主页,抓到的包如下:
 
看到这里,应该开始有感觉了吧。
HTTP,即应用层,正在访问js.aq.qq.com.
TCP层,src port是62957, dst port是80端口,因为js.aq.qq.com的端口是80。
IP层,用的是IPV4,我的计算机IP地址是192.168.1.2,目标IP是180.153.105.248.
链路层, 我使用的是Apple电脑,我的MAC地址我隐藏了,对端是ZTE设备。
 
再截几个图大家仔细看一下。
链路层
 
IP层

TCP层
 
应用层(HTTP)

 

在这里不加以详解,后面会对TCP以及HTTP层详详细说明。

TCP三次握手与四次挥手

 
TCP三次握手
 
所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。
·       第一次握手(SYN=1, seq=x):
客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入 SYN_SEND 状态。
·       第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。
·       第三次握手(ACK=1,ACKnum=y+1)
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1
发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED状态,TCP 握手结束。
三次握手的过程的示意图如下:

 

确实比较抽象,让我们继续通过抓包来分析(访问baidu.com)
这里有三个包。
192.168.1.2是我机器的IP,115.239.211.112是baidu的IP,是不是和上图一致。
具体看270包,192.168.1.2 发送SYN到115.239.211.112,seq=0;
如下图:

 

274包图,115.239.211.112返回SYN 和ACK给192.168.1.2, seq =0, 但是ACK等于SYN里的seq(为0)+1,所以为1

275包图,192.168.1.2收到ACK包后,给115.239.211.112再回一个ACK,ACK#为1:

对于协议的理解,还是多观察,多比对,就知道是怎么回事了。

 

TCP四次挥手
TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。
·       第一次挥手(FIN=1,seq=x)
假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。
发送完毕后,客户端进入 FIN_WAIT_1 状态。
·       第二次挥手(ACK=1,ACKnum=x+1)
服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。
发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。
·       第三次挥手(FIN=1,seq=y)
服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。
发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。
·       第四次挥手(ACK=1,ACKnum=y+1)
客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。
服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。
 
四次挥手的示意图如下:

这里就不抓包了,可以自行抓包对比看看。

HTTPS证书

越来越多的网站开始使用HTTPS(Apple要求App都须用HTTPS)。对于HTTPS,需要有一个SSL/TLS的鉴权/认证,才能建立TCP链接。
 
下图描述了HTTP和HTTPS的区别。

 

关于SSL/TLS如何交互等,可以参看阮一峰老师的文章http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html 和http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html,写非常清楚的。
借用一张阮一峰老师的图:

 

 

 

我们还是抓包体会一下。

 

对着阮一峰老师图片的流程看:
273包: Client 发送Client Hello给Server。
278包: Server回Server Hello给Client。
283包: Server继续回Server Certificate给Client,要交换证书。
294包:Server继续回Server Key Exchange,交换key。
295包:Server返回Server Hello Done。
截止这里,Server已经做了不少事,接下来轮到Client了。
298包:Client Key Exchange,Change Cipher Spec,Encrypted Handshake Message。到这里就结束了。
 
我们再仔细看看Client Hello的273包,注意标记部分.
接下来再看看Extension,有很多对不对。这里专门说一下 SNI(Server Name Indication), server_name, 我们可以看见它的值是www.baidu.com. 也就是说浏览器发送过来的证书是给baidu这个域名签发的。SNI用来校验该证书是不是为server name提供的域名签发的。如果不是,就会报错。
 
有一种情况特别需要注意,在早期版本的浏览器或者HTTP客户端,SNI可能不包含在该包里的,那么怎么处理呢?如果Server端只有一个证书部署,那简单,就是按照部署的那个证书去判断。如果有多个证书部署呢?比如部署了aaa.com bbb.com ccc.com 三个域名的证书,那么就会按照缺省的去匹配,取决于软件(Apache,Tomcat等)和硬件(F5,Netscaler)怎么配置了。
但是如果已经商用,去改默认配置,会对商用服务有影响,那么可不可以在Client有一些改进呢?如果您正在使用某个HTTP library,可以考虑升级版本是否支持。
 

 

278包的Server Hello

继续看看Server Certificate,即283包
我们看看baidu的证书,打开Chrome就可以看到了,对比一下两图的基本信息,这时是不是觉得更容易理解?我相信答案是肯定的。
294包,Server key Exchange

 

 
295包,Server Hello Done。

 

298包,Client Key Exchange/Change Cipher Spec/Encrypted Handshake Message。

TCP/IP其他

上面都是最基本的东西,在实际的过程中还有包重试,包拼装等,太底层了,大家有兴趣可以找资料看看。

TCP/IP 10问

以下几个问题大部分都可以找到答案。
  1. TCP/IP的4层模型了解吗?每层有哪些常见协议?
  2. TCP/IP的三次握手了解吗?四次挥手是什么,了解多少?
  3. HTTP和HTTPS在TCP握手上有什么不同?SSL/TLS握手流程了解吗?
  4. SSL/TLS的版本有哪些?当前浏览器支持哪些版本?
  5. SNI了解多少?如果SNI没有,该如何校验证书?
  6. TCP与UDP区别在哪里?
  7. 为什么TCP经常会组装包?如何保证包的完整性?
  8. TCP滑动窗口原理是什么?TCP有哪些状态?
  9. MAC地址的是如何定义的?(这个问题太Edge了)
  10. SSL/TLS证书和端口有关系吗?为什么?

今天把TCP/IP, SSL/TLS介绍完了,下一部分是最后一部份了,左右介绍HTTP和Broswer的机制。

posted @ 2018-12-04 08:52 张太国 阅读(...) 评论(...) 编辑 收藏