当你在浏览器中输入了网址访问时产生了哪些技术步骤
前段时间在知乎上了看一些网络方面的知识,刚好小编自己也是从事这一块的相关工作由对网络方面有一定的了解。今天我们来讲讲,当你在浏览器中输入本站域名并回车后,这背后到底发生来什么事情?
(因平台原因本文中www即为xxx ,com即为zzz,http/ccccc即为cccc/ccccc)
大致总结归纳了下,发生的事情如下图:
看到这里,大部分人都是蒙的。哪怕你有一点网络知识的基础,看起来也是蒙的。为了跟大家生动形象地说明原理,下面,我们用拟人的手法,讲述从输入一个网址,到最终显示出页面,这背后所发生的事情。
某天,小明心血来潮,想去艾西服务器论坛看一下有没有更新的博文,于是他打开了chrome浏览器,稍微回忆了一下网址,输入了:27server.zzz,并按下了回车。
一,浏览器格式化检查
chrome检查了一下,嗯?这好像是一个蛮标准的网址。但如果小明输入的是27server@zzz或者27server.zzz1这样的,chrome就会无情的拒绝小明的提议,并提示他网址出错。
所以在第一步,浏览器对网址进行了格式化检验,确定这是一个有效的网址,才会进入下一步。但是,在访问之前,浏览器必须知道,用了什么协议,是http呢,还是https呢?显然chrome对这种事情已经见怪不怪了,他有自己的一套方案,这里小明没有给定是什么协议的,于是chrome默认用了http协议,于是将网址修改成了:cccc://27server.zzz
二
在互联网上,有一家名叫TCP/IP的快递公司,专门负责运送用户的包裹。
于是chrome联系了TCP/IP快递公司,但却被告知:需要知道对方的IP地址,才能把包裹寄给对方!chrome并不是一个灰心的孩子,于是它找到了“黄页公司”-DNS。
求DNS帮忙查询下“27server.zzz”的IP地址是多少?DNS于是着手开始查找。首先看了下本地的hosts文件,没有找到对应!然后看了下本地内存,也没有!没办法,DNS只好联系了村口的一家名叫路由器的公司,192.168.1.1。路由器查看了下,最近村里没人访问过这个域名呀,要不你去市里的DNS公司问问?这是市里的DNS公司地址:114.114.114.114
于是DNS又联系了市里的DNS公司,却被告知最近市里最近也没人访问过这个域名。但是市里的DNS公司毕竟是专业的DNS公司,不会随便推卸责任,对DNS说,你等一等,我找我的上级查询下。于是市里的DNS公司联系了它的上级,根域名服务器。这个根域名服务器可了不得,全球只有13台,掌控着全球的DNS根域名查询。市里的DNS公司找到了离他最近的根域名服务器,说:“老哥,麻烦帮我查下.com顶级域名的服务器地址。”
没过一会儿,根域名服务器回复道:“你好,你要查询的地址是1.2.3.4。”
于是市里的DNS公司又联系到了1.2.3.4,询问 27server这个二级域名的域名服务器地址。
同样,1.2.3.4回复给了市里的DNS公司,地址是2.3.4.5。
市里的DNS公司又找2.3.4.5问了下,地址是:27server.zzz.w.kunluncan.zzz。等等,这怎么是一个别名(CNAME)?
于是市里的DNS公司又不厌其烦的重复了上面的几个步骤,一级一级地查找了 com > kunluncan > w > com > 27server的域名服务器地址,一直找到了驰网云的CDN域名服务器,DNS联系了对方,对方回复道:“查询到25个IP地址,分别是xxxxxxxx,帮你找到了离你最近的地址,3.4.5.6,已经打包,收件人地址:114.114.114.114 发件人地址:3.3.3.3,已委托TCP/IP快递公司的UDP小哥发送给你。”
三,网关
UDP是这一行的老司机,随手在包裹上写着:
收件人门牌号:53
发件人门牌号:56002
因为UDP知道,同一个地址会有很多的门牌号,为了避免混淆,必须要写。
UDP随手联系了TCP/IP公司的货车司机,让他捎带一下这个包裹。
司机来了,把包裹放进了驾驶室,坐上车准备开车。
司机打开了导航(路由表),发现要出关(网关),但是要知道关口的编号(mac地址)。但是导航信息里并没有关口的编号。于是司机找到了当地的向导ARP,问这个关口的编号是多少?ARP吼了一嗓子,关口回复说:“我的编号是xxxxx”。司机很快就到达了关口,关口放行,载着快递,上了Internet高速公路,一路狂奔不止。
四,建立DNS缓存
市里的DNS公司收到结果后,又通过村口的路由器公司联系到了DNS,并把结果告诉给了对方。同时村口的路由器公司和DNS都在自己的小本本上默默地记下了这个对应关系。
最后,DNS又把结果告诉给了已经等得不耐烦的chrome了。
五,TCP的三次握手
知道了27server.zzz的IP地址,chrome又立即联系了TCP/IP快递公司,快递公司派出了TCP小哥来接洽此时。和UDP小哥不同的是,TCP小哥是一个做事一丝不苟的人,知道chrome想要去拜访3.4.5.6,就要先和对方联系一下,确定在不在,这是通过TCP三次握手实现的。
TCP小哥:在吗?有人想要去拜访您。
对方:在啊,随时欢迎。
TCP小哥:马上到。
这三次消息,要通过TCP/IP公司的司机来来回回运输三次。DNS查询也是同样的道理,这里就不赘述了。
通过这三次握手,TCP小哥建立起了一条chrome到3.4.5.6的通道。
chrome将http请求消息(我是谁,要找谁等),打包给了TCP小哥,寄件人IP地址:2.2.2.2 门牌号:23755。收件人IP地址:3.4.5.6 门牌号:80
然后TCP小哥联系了司机,将包裹送到了3.4.5.6的80门牌号上。
六
3.4.5.6的80门牌号的门卫是nginx老大爷。老大爷一看,是送给家里的27server.zzz的。
路上老大爷看了下nginx.conf里找人的顺序:首先找index.php,如果找不到就找index.htm,再找不到就找index.html。
于是敲开了27server.zzz的门,里面只有index.html在家。index.html头也不回地告诉nginx老大爷,告诉chrome,我们已经搬家了,去找ccccc://xxx.27server.zzz(强制跳转)。
七
chrome收到了这个消息,立马又重复了上面的所有步骤,联系了“黄页公司”DNS,费了很大一番周折,找到了 xxx.27server.zzz的IP地址。
其实这两次访问,整体流程相似,不一样的地方如下:
查找到xxx.27server.zzz的IP地址后,chrome这回没有直接把包裹给TCP小哥,而是联系了TLS安保大叔,让他全权负责包裹的安全问题,确保包裹在运输过程中的安全,即包裹的内容保密,包裹内容不能被篡改、替换。
TLS大叔需要先和对方沟通安保措施,沟通的渠道,就是上文三次握手建立的渠道。
TLS大叔先发言:你好,我支持TLS版本1.2,以及我的认证算法、加密算法、数据校验算法,此外还有我的随机码,收到请回复。
TLS服务器回复:你好,我也支持1.2版本,那我们就使用xx认证算法、xx加密算法、xx数据校验算法,我的随机码是xx,来实现安保措施,你看好吗?
TLS大叔:没问题啊,能出示一下你的证件(数字证书)吗?
TLS服务器:okay,这是我的证件,请过目。
TLS大叔发现对方发过来的证书:
TLS大叔不放心,验证了下证书,过程如下:
1. 用DigiCert Global Root CA的公钥解密证书Encryption Everywhere DV的签名
作为一个权威CA,已经被浏览器预先安装在可信任根证书列表,那么我们信任该CA的一切,当然包括其公钥,在该证书里包含了明文的公钥。
解开了,证明是该CA私钥加密的,由于CA私钥只有CA知道,证书有效,并信任Encryption Everywhere DV的公钥。
2. 同样原理用Encryption Everywhere DV的公钥解密DigiCert Global Root CA的签名。
如果上述2个步骤都成功了,就有了27server.zzz的公钥。
3. 再检查下证书的有效期,如果没有过期,那么进入下一个步骤。
TLS大叔用“27server.zzz“公钥加密一段随机的字符串,发送给TLS服务器。
TLS服务器用自己的私钥解密,得到明文字符串。
至此,双方分享了这个神秘的字符串,双方还有早前分享的随机码(nonce),双方使用同样的算法,可以推导出相同的master key,进而推导出session key、HMAC key。
Session Key用于加密/解密数据, HMAC Key主要用于保护数据的完整性,以防被第三方篡改。
整个TLS沟通过程就算完成了,TLS大叔把浏览器扔给自己的包裹,外面加了一层保险箱,密码锁(session key)只有TLS大叔、TLS服务器知道。
然后TLS大叔把包裹给了TCP小哥,TCP小哥看了下包裹,没啥两样,就是收件人的门牌号从80变成了443。
包裹到达后,443门牌号的门卫是TLS服务器,TLS服务器用自己的密码打开了包裹,包裹里有个小纸条,上面写着“Application Data =http”,知道这是http的东西,于是转手又让nginx老大爷把包裹送到 xxx.27server.zzz的房间。
八
这回nginx老大爷一看index.php不在家,但是留了个字条,说对方如果要图片这些静态资源,那么直接给他,如果要找我们,请到IP地址:5.6.7.8来找我。没办法,nginx老大爷又委托TLS大叔跟对方的服务器5.6.7.8的TLS对接了下,商量下包裹加密,又TCP/IP快递公司,把包裹寄到了5.6.7.8的443门牌,送给了index.php。index.php发现需要主页,这需要进行计算。于是找来了php家族,计算完了又把主页打包成了html样式,返回给了chrome。
chrome收到了html样式的包裹,这是一种标记语言,需要经过解释才能把原来的页面还原出来。
于是chrome又埋头计算,终于通过里面写的规则,把图片文字拼拼凑凑,拼成了一个完整的页面,展示给了小明。
小明怎么也不会想到,按下了一次回车,在后台居然触发了这么大的计算量。。。
对于以上的内容,这里我们用稍微专业点的语言解释一下:
访问网址,首先通过域名查询IP地址。
浏览器会先查询hosts文件,然后查询内存中是否有对应的DNS缓存。如果电脑连接路由器上网,而DNS又是自动获取的话,DNS服务器就会被指定为路由器(局域网网关),如果局域网中没人访问过这个地址,那么在路由器的内存中不会存在这条DNS解析记录。于是又往上查找各层级的DNS服务器,从家里到区,到城市的DNS服务器,能不能找到缓存,取决于这个区域有没有人访问过这个域名。一直查到最上层,如果都没有找到的话,就会请求根域名服务器,从找到com域名服务器地址,再从com上找到27server二级域名服务器地址….以此类推,最终找到完整域名的服务器地址。
找到地址后,是一个CNAME形式,解析到了阿里云CDN的DNS服务器上,阿里云的DNS服务器又通过用户的访问IP判断出用户的地理位置,返回最靠近用户的CDN服务器地址。CDN通俗点说,就是把你的网站资源镜像到全国各地的服务器上,从而实现不同地区用户的访问加速。
用户通过这两层DNS查询后,得到了离自己最近的CDN服务器地址,访问这个地址,CDN服务器根据配置的缓存规则,返回了静态资源,其他则通过访问源服务器进行返回(CDN回源)。
因为对应27server.zzz这个地址,我只放了一个index.html。访问这个页面,会自动跳转到 ccccc://xxx.27server.zzz。浏览器访问27server.zzz后,又继续访问ccccc://xxx.27server.zzz,此时通过两次DNS查询,CDN返回图片,js,css等静态资源,然后php的内容则通过CDN回源,源服务器的php计算后,转化为html样式,返回给访问者。
你对27server.zzz的一次访问,一共触发了4次完整的DNS查询,1次www强行跳转,1次https强行跳转,1次CDN回源,2次CDN地址解析,更有数不清的资源文件从各个地方被传输到了你的电脑。这些都是通过TCP的三次握手协议,网关,ARP,UDP,nginx,CDN,DNS服务器联合工作。
我是艾西,今天的分享就到这里啦希望对有需要的小伙伴有帮助我们下期见
拥有一台服务器可以做很多有趣的事情!