浏览器输入url的过程
URL解析
DNS 解析:缓存判断 + 查询IP地址
TCP 连接:TCP 三次握手
SSL/TLS四次握手(只有https才有这一步)
浏览器发送请求
服务器响应请求并返回数据
浏览器解析渲染页面
断开连接:TCP 四次挥手
URL解析
浏览器先会判断输入的字符是不是一个合法的URL结构,如果不是,浏览器会使用搜索引擎对这个字符串进行搜索
URL结构组成
https://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#anchor
协议:https://
互联网支持多种协议,必须指明网址使用哪一种协议,默认是 HTTP 协议。
也就是说,如果省略协议,直接在浏览器地址栏输入www.example.com,那么浏览器默认会访问http://www.example.com。
HTTPS 是 HTTP 的加密版本,出于安全考虑,越来越多的网站使用这个协议。
主机:www.example.com
主机(host)是资源所在的网站名或服务器的名字,又称为域名。上例的主机是www.example.com。
有些主机没有域名,只有 IP 地址,比如192.168.2.15。
端口:https://
同一个域名下面可能同时包含多个网站,它们之间通过端口(port)区分。
“端口”就是一个整数,可以简单理解成,访问者告诉服务器,想要访问哪一个网站。
默认端口是80,如果省略了这个参数,服务器就会返回80端口的网站。
端口紧跟在域名后面,两者之间使用冒号分隔,比如www.example.com:80。
路径:/path/to/myfile.html
路径(path)是资源在网站的位置。比如,/path/index.html这个路径,指向网站的/path子目录下面的网页文件index.html
互联网的早期,路径是真实存在的物理位置。现在由于服务器可以模拟这些位置,所以路径只是虚拟位置
路径可能只包含目录,不包含文件名,比如/foo/,甚至结尾的斜杠都可以省略
这时,服务器通常会默认跳转到该目录里面的index.html文件(即等同于请求/foo/index.html),但也可能有其他的处理(比如列出目录里面的所有文件),这取决于服务器的设置
一般来说,访问www.example.com这个网址,很可能返回的是网页文件www.example.com/index.html
查询参数:?key1=value1&key2=value2
查询参数(parameter)是提供给服务器的额外信息。参数的位置是在路径后面,两者之间使用?分隔
查询参数可以有一组或多组。每组参数都是键值对(key-value pair)的形式,同时具有键名(key)和键值(value),它们之间使用等号(=)连接。比如,key1=value就是一个键值对,key1是键名,value1是键值
多组参数之间使用&连接,比如key1=value1&key2=value2
锚点:#anchor
锚点(anchor)是网页内部的定位点,使用#加上锚点名称,放在网址的最后,比如#anchor
浏览器加载页面以后,会自动滚动到锚点所在的位置
锚点名称通过网页元素的id属性命名
DNS解析
DNS(Domain Names System),域名系统,是互联网一项服务,是进行域名和与之相对应的 IP 地址进行转换的服务器
dns 解析 是 递归 + 迭代的过程
DNS 是:
一个由分层的 DNS 服务器实现的分布式数据库
一个使得主机能够查询分布式数据库的应用层协议
DNS 是一个分布式数据库,整个 DNS 系统由分散在世界各地的很多台 DNS 服务器组成,每台 DNS 服务器上都保存了一些数据,这些数据可以让我们最终查到主机名对应的 IP。
什么是分布式?
这个世界上没有一台 DNS 服务器拥有因特网上所有主机的映射,每台 DNS 只负责部分映射。
什么是层次?
DNS 服务器有 3 种类型:根 DNS 服务器、顶级域(Top-Level Domain, TLD)DNS 服务器和权威 DNS 服务器。它们的层次结构如下图所示:

第一步:缓存判断
判断是正确的URL格式之后,DNS会在我们的缓存中查询是否有当前域名的IP地址
基本步骤:
浏览器缓存:浏览器检查是否在缓存中(chrome 浏览器 chrome://net-internals/#dns)
操作系统缓存:操作系统DNS缓存,去本地的hosts文件查找
路由器缓存:路由器DNS缓存
ISP 缓存: ISP DNS缓存(ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器,又称本地的DNS服务器)
在经历上述缓存查找还没有找到的话,就进行下一步查询操作
根 DNS 服务器
首先我们要明确根域名是什么,比如 www.baidu.com,有些同学可能会误以为 com 就是根域名,其实 com 是顶级域名,www.baidu.com 的完整写法是 www.baidu.com.,最后的这个 . 就是根域名。
根 DNS 服务器的作用是什么呢?就是管理它的下一级,也就是顶级域 DNS 服务器。通过询问根 DNS 服务器,我们可以知道一个主机名对应的顶级域 DNS 服务器的 IP 是多少,从而继续向顶级域 DNS 服务器发起查询请求。
顶级域 DNS 服务器
除了前面提到的 com 是顶级域名,常见的顶级域名还有 cn、org、edu 等。顶级域 DNS 服务器,也就是 TLD,提供了它的下一级,也就是权威 DNS 服务器的 IP 地址。
权威 DNS 服务器
权威 DNS 服务器可以返回主机 - IP 的最终映射。
本地 DNS 服务器
严格来说,本地 DNS 服务器并不属于 DNS 的层次结构,但它对 DNS 层次结构是至关重要的。
每个 ISP 都有一台本地 DNS 服务器,比如一个居民区的 ISP、一个大学的 ISP、一个机构的 ISP,都有一台或多台本地 DNS 服务器。当主机发出 DNS 请求时,该请求被发往本地 DNS 服务器,本地 DNS 服务器起着代理的作用,并负责将该请求转发到 DNS 服务器层次结构中。
递归查询、迭代查询
假设主机 m.n.com 想要获取主机 a.b.com 的 IP 地址,会经过以下几个步骤:
首先,主机 m.n.com 向它的本地 DNS 服务器发送一个 DNS 查询报文,其中包含期待被转换的主机名 a.b.com;
本地 DNS 服务器将该报文转发到根 DNS 服务器;
该根 DNS 服务器注意到 com 前缀,便向本地 DNS 服务器返回 com 对应的顶级域 DNS 服务器(TLD)的 IP 地址列表。意思就是,我不知道 a.b.com 的 IP,不过这些 TLD 服务器可能知道,你去问他们吧;
本地 DNS 服务器则向其中一台 TLD 服务器发送查询报文;
该 TLD 服务器注意到 b.com 前缀,便向本地 DNS 服务器返回权威 DNS 服务器的 IP 地址。意思就是,我不知道 a.b.com 的 IP,不过这些权威服务器可能知道,你去问他们吧;
本地 DNS 服务器又向其中一台权威服务器发送查询报文;
终于,该权威服务器返回了 a.b.com 的 IP 地址;
本地 DNS 服务器将 a.b.com 跟 IP 地址的映射返回给主机 m.n.com,m.n.com 就可以用该 IP 向 a.b.com 发送请求啦。
主机 m.n.com 向本地 DNS 服务器 dns.n.com 发出的查询就是递归查询,这个查询是主机 m.n.com 以自己的名义向本地 DNS 服务器请求想要的 IP 映射,并且本地 DNS 服务器直接返回映射结果给到主机。
而后继的三个查询是迭代查询,包括本地 DNS 服务器向根 DNS 服务器发送查询请求、本地 DNS 服务器向 TLD 服务器发送查询请求、本地 DNS 服务器向权威 DNS 服务器发送查询请求,所有的请求都是由本地 DNS 服务器发出,所有的响应都是直接返回给本地 DNS 服务器。
那么问题来了,所有的 DNS 查询都必须遵循这种递归 + 迭代的模式吗?
当然不是。
从理论上讲,任何 DNS 查询既可以是递归的,也可以是迭代的。
递归查询
在递归查询中,客户端向DNS服务器发送一个查询请求,然后DNS服务器负责处理整个查询过程,直到获取到最终的结果。如果这个服务器没有所需的信息,它会代表客户端向其他DNS服务器进行查询,直到找到答案。然后,这个DNS服务器将最终的结果返回给客户端
迭代查询
在迭代查询中,客户端向DNS服务器发送查询请求。如果该服务器没有所需的完整信息,它不会代表客户端进行进一步的查询,而是返回给客户端一个指向更权威的DNS服务器的引用。然后,客户端根据这个引用直接向权威服务器发起新的查询请求。这个过程重复进行,直到找到最终的答案。
tcp建立连接

三次握手原理:
第一次握手:客户端发送一个带有 SYN(synchronize同步)标志的数据包给服务端。 第二次握手:服务端接收成功后,回传一个带有 SYN/ACK 标志的数据包传递确认信息,表示我收到了。 第三次握手:客户端再回传一个带有 ACK 标志的数据包,表示我知道了,握手结束。
其中:SYN标志位数置1,表示建立TCP连接;ACK表示响应,置1时表示响应确认。
三次握手过程详细说明: 刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。
第一次握手: 客户端发送标识位SYN = 1,随机产生序列号seq = x的数据包到服务端,服务端由SYN = 1知道客户端要建立连接,并进入SYN_SENT状态,等待服务器确认;(SYN=1,seq=x,x为随机生成的数值)
第二次握手: 服务器收到请求并确认联机信息后,向客户端发送标识位SYN = 1,ACK = 1和随机产生的序列号seq = y, 确认码ack number = x+1(客户端发送的seq+1)的数据包,此时服务器进入SYN_RCVD状态;(SYN=1,ACK=1,seq=y,y为随机生成的数值,确认号 ack=x+1)这里ack加1可以理解为时确认和谁建立连接。
第三次握手:客户端收到后检查确认码ack number是否正确,即和第一次握手发送的序列号加1结果是否相等,以及ACK标识位是否为1;若正确,客户端发送标识位ACK = 1、seq = x + 1和确认码ack = y + 1(服务器发送的seq+1)到服务器,服务器收到后确认ACK=1和seq是否正确,若正确则完成建立连接,此包发送完毕,客户端和服务器进入ESTAB_LISHED状态。完成三次握手,客户端与服务器开始传送数据.。(ACK=1,seq=x+1,ack=y+1)
TCP 三次握手的建立连接的过程就是相互确认初始序号的过程。告诉对方,什么样序号的报文段能够被正确接收。 第三次握手的作用是:客户端对服务器端的初始序列号的确认,如果只使用两次握手,那么服务器就没有办法知道自己的序号是否已被确认。同时这样也是为了防止失效的请求报文被服务器接收,而出现错误的情况。
2. 四次挥手
四次挥手原理:
第一次挥手:客户端发送一个FIN,用来关闭客户端到服务器的数据传送,并且指定一个序列号。客户端进入FIN_WAIT_1状态。 第二次挥手:服务器收到FIN后,发送一个ACK给客户端,确认序号为客户端的序列号值 +1 ,表明已经收到客户端的报文了,此时服务器处于 CLOSE_WAIT 状态。 第三次挥手:服务器发送一个FIN,用来关闭服务器到客户端的数据传送,服务器进入LAST_ACK状态。 第四次挥手:客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务器,确认序号为收到序号+1 ,服务器收到确认后进入CLOSED状态,完成四次挥手。
其中:FIN标志位数置1,表示断开TCP连接。
四次挥手过程详细说明:
刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。
第一次挥手:客户端发送一个FIN = 1、初始化序列号seq = u,到服务器,表示需要断开TCP连接,客户端进入FIN_WAIT_1状态,等待服务器的确认。(FIN = 1,seq = u,u由客户端随机生成)
第二次挥手:服务器收到这个FIN,它发回ACK = 1、seq序列号(由回复端随机生成)、确认序号ack为收到的序号加1(ack = u+1);以便客户端收到信息时,知晓自己的TCP断开请求已经得到验证。服务器进入CLOSE_WAIT,等待关闭连接;客户端进入FIN_WAIT_2,稍后关闭连接。(ACK = 1,seq = v,ack = u+1)
第三次挥手:服务器在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开。服务器会先确保断开前,所有传输到客户端的数据是否已经传输完毕,一旦确认传输完毕,就会发回FIN = 1,ACK = 1,seq = w和确认码ack = u+1给客户端,服务器进入LAST_ACK 状态,等待最后一次ACK确认;(FIN = 1,ACK = 1,seq = w,ack = u+1 ,w由服务器端随机生成)
第四次挥手:客户端收到服务器的TCP断开请求后,会回复服务器的断开请求。包含ACK = 1、随机生成的seq = u+1,并将确认序号设置为收到序号加1(ack = w+1)到服务器,从而完成服务器请求的验证回复。客户端进入TIME-WAIT 状态,此时 TCP 未释放掉,需要等待 2MSL 以确保服务器收到自己的 ACK 报文后进入CLOSE状态,服务端进入CLOSE状态。(ACK = 1,seq = u+1,ack = w+1)
注意:为什么 TIME_WAIT 等待的时间是 2MSL? 1)MSL 是 报文最大生存时间,一来一回需要等待 2 倍的时间。 2)最后一次挥手中,客户端会等待一段时间再关闭的原因,是为了防止发送给服务器的确认报文段丢失或者出错,从而导致服务器 端不能正常关闭。
网络层:IP 协议查询 MAC 地址
将数据段打包,并加入源及目标的 IP 地址,并且负责寻找传输路线。判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。
链路层:以太网协议
根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:
标头:数据包的发送者、接受者、数据类型
数据:数据包具体内容
SSL/TLS四次握手
HTTPS 建立连接的过程,先进行 TCP 三次握手,再进行 TLS 四次握手(仅对https)
因为 HTTPS 都是基于 TCP 传输协议实现的,得先建立完可靠的 TCP 连接才能做 TLS 握手的事情。
加密套件列表
加密套件列表一般由客户端发送,供服务器选择。用 openssl 查看列表:
scss
复制代码➜ openssl ciphers -v
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256
...
... Cipher Suites(17 suites)

意思是:
TLS 握手过程中,使用 ECDHE 算法生成 pre_random。
身份验证 (签名) 使用 RSA 算法。
128 位的 AES 算法进行对称加密,在对称加密的过程中使用主流的 GCM 分组模式,可以让算法用固定长度的密钥加密任意长度的明文。
最后是用于数据完整性校验的哈希摘要算法,采用 SHA256 算法。
1.浏览器向服务器发送随机数 client_random,TLS 版本和供筛选的加密套件列表。
2.服务器接收到,立即返回 server_random,确认好双方都支持的加密套件
以及数字证书 (证书中附带公钥 Public key certificate)。
3.浏览器接收,先验证数字证书。若通过,接着使用加密套件的密钥协商算法 RSA
算法生成另一个随机数 pre_random,并且用证书里的公钥加密,传给服务器。
4.服务器用私钥解密这个被加密后的 pre_random,参考 “非对称加密”。
认证机构的工作
认证机构会生成一对秘钥, 公钥和私钥 公钥证书的生成包括了两部分内容
数字签名
服务器公钥
其中数字签名的生成过程是:
服务器公钥 经过数字摘要算法 生成数字指纹
把生成的数字指纹 在用认证机构的私钥加密 生成数字签名
https中客户端验证公钥证书的过程
服务器将公钥证书发送给客户端 客户端验证公钥证书 从而确保公钥的合法性
客户端取出提前内置在手机内部的认证机构的公钥
用认证机构的公钥去解密公钥证书里的数字签名 从而得到数字指纹
客户端对公钥证书的服务器公钥进行 数字摘要算法 从而生成数字指纹
对比客户端自己生成的数字指纹(第3步)和解密得到的数字指纹(第2步)是否一致 如果一致则公钥证书验证通过 就可以进行接下来的握手步骤了
第一次握手:客户端发出请求Client Hello
首先,客户端先向服务器发出加密通信的请求,这被叫做clienthello请求。
在这一步,客户端主要向服务器提供以下信息:
支持的协议版本,比如TLS1.0版本
支持的加密方法,比如RSA公钥加密
一个客户端生成的随机数(client random), 稍后用于生成对话密钥(session key)
第二次握手:服务器回应Server Hello
服务器收到客户端请求后,向客户端发出回应,这叫做serverhello
这一步服务器主要干三件事:
确认使用的加密通信协议版本,比如TLS1.00版本。如果游览器与服务器支持的版本不一致,服务器关闭加密通信
确认使用的加密方法(客户端所支持),比如RSA公钥加密
将服务器证书、非对称加密的公钥,以及一个随机数(Server random)发送给客户端游览器
客户端验证证书
客户端收到服务器回应以后,首先验证服务器证书,验证手段就是执行如下三种检查:
检查证书是否已过期;
检查证书中的域名与实际域名是否一致
检查证书是否是可信机构颁布的
如果,上述过程中有任何一个环节发现问题,那么浏览器就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串新的随机数(Premaster secret )。
第三次握手:客户端回应
此时,浏览器会根据前三次握手中的三个随机数:
Client random
Server random
Premaster secret
通过一定的算法来生成 “会话密钥” (Session Key),这个会话密钥就是接下来双方进行对称加密解密使用的密钥!
第四次握手:服务端回应
服务端收到客户端的回复,利用已知的加密解密方式进行解密,服务器收到客户端的第三个随机数( Premaster secret) 之后,使用同样的算法计算出 “会话密钥” (Session Key)。
至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用 “会话密钥” 加密内容。(非对称加密解密将不再使用,接下来完全由对称加密接手了,因为密钥已经安全的传送给了通信的双方)
总结
客户端请求建立SSL链接,并向服务发送一个随机数–Client random和客户端支持的加密方法,比如RSA公钥加密,此时是明文传输
服务端回复一种客户端支持的加密方法、一个随机数–Server random、授信的服务器证书和非对称加密的公钥
客户端收到服务端的回复后利用服务端的公钥,加上新的随机数–Premaster secret 通过服务端下发的公钥及加密方法进行加密,发送给服务器
服务端收到客户端的回复,利用已知的加解密方式进行解密,同时利用Client random、Server random和Premaster secret通过一定的算法生成HTTP链接数据传输的对称加密key – session key
Last updated