如果您从事任何类型的技术专业,我相信某人在某个时候已经问过您这个问题。无论您是工程师,开发人员,营销人员还是销售人员,最好先了解浏览器背后的情况以及如何通过互联网将信息传输到我们的计算机上。
我们假设您想要访问maps.google.com以查看您从工作中获得晚餐预订所需的确切时间。
1. 您将maps.google.com键入浏览器的地址栏。
2. 浏览器查询地址栏缓存。
浏览器会根据历史访问,书签等信息给出输入建议。
还会根据默认搜索引擎的搜索记录,去匹配最近的搜索记录。
3. url 解析
4. 浏览器查询重定向缓存。
w3c 规范规定 301 为永久重定向应该被缓存
5. 浏览器查询应用缓存
6. 浏览器检查 HSTS 预加载列表。
有不少网站只通过HTTPS对外提供服务,但用户在访问某个网站的时候,在浏览器里却往往直接输入网站域名(例如www.example.com),而不是输入完整的URL(例如https://www.example.com),不过浏览器依然能正确的使用HTTPS发起请求。这背后多亏了服务器和浏览器的协作
简单来讲就是,浏览器向网站发起一次HTTP请求,在得到一个重定向响应后,发起一次HTTPS请求并得到最终的响应内容。所有的这一切对用户而言是完全透明的,所以在用户眼里看来,在浏览器里直接输入域名却依然可以用HTTPS协议和网站进行安全的通信,是个不错的用户体验。
一切看上去都是那么的完美,但其实不然,由于在建立起HTTPS连接之前存在一次明文的HTTP请求和重定向(上图中的第1、2步),使得攻击者可以以中间人的方式劫持这次请求,从而进行后续的攻击,例如窃听数据,篡改请求和响应,跳转到钓鱼网站等。
既然建立HTTPS连接之前的这一次HTTP明文请求和重定向有可能被攻击者劫持,那么解决这一问题的思路自然就变成了如何避免出现这样的HTTP请求。我们期望的浏览器行为是,当用户让浏览器发起HTTP请求的时候,浏览器将其转换为HTTPS请求,直接略过上述的HTTP请求和重定向,从而使得中间人攻击失效,规避风险。
那么问题来了,浏览器是如何做到这一点的呢?它怎么知道那个网站应该发HTTPS请求,那个网站应该用HTTP请求呢?此时就该HSTS粉墨登场了。
HSTS
HSTS的全称是HTTP Strict-Transport-Security,它是一个Web安全策略机制(web security policy mechanism)。
HSTS最早于2015年被纳入到ThoughtWorks技术雷达,并且在2016年的最新一期技术雷达里,它直接从“评估(Trial)”阶段进入到了“采用(Adopt)“阶段,这意味着ThoughtWorks强烈主张业界积极采用这项安全防御措施,并且ThoughtWorks已经将其应用于自己的项目。
HSTS最为核心的是一个HTTP响应头(HTTP Response Header)。正是它可以让浏览器得知,在接下来的一段时间内,当前域名只能通过HTTPS进行访问,并且在浏览器发现当前连接不安全的情况下,强制拒绝用户的后续访问要求。
HSTS Header的语法如下:
Strict-Transport-Security: <max-age=>[; includeSubDomains][; preload]
其中:
max-age是必选参数,是一个以秒为单位的数值,它代表着HSTS Header的过期时间,通常设置为1年,即31536000秒。
includeSubDomains是可选参数,如果包含它,则意味着当前域名及其子域名均开启HSTS保护。
preload是可选参数,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到它。关于浏览器内置列表,下文有详细介绍。
让浏览器直接发起HTTPS请求
只要在服务器返回给浏览器的响应头中,增加Strict-Transport-Security这个HTTP Header(下文简称HSTS Header),例如:
Strict-Transport-Security: max-age=31536000; includeSubDomains
就可以告诉浏览器,在接下来的31536000秒内(1年),对于当前域名及其子域名的后续通信应该强制性的只使用HTTPS,直到超过有效期为止。
HSTS存在一个比较薄弱的环节,那就是浏览器没有当前网站的HSTS信息的时候,或者第一次访问网站的时候,依然需要一次明文的HTTP请求和重定向才能切换到HTTPS,以及刷新HSTS信息。而就是这么一瞬间却给攻击者留下了可乘之机,使得他们可以把这一次的HTTP请求劫持下来,继续中间人攻击。
针对上面的攻击,HSTS也有应对办法,那就是在浏览器里内置一个列表,只要是在这个列表里的域名,无论何时、何种情况,浏览器都只使用HTTPS发起连接。这个列表由Google Chromium维护,FireFox、Safari、IE等主流浏览器均在使用。
根据官方说明,你的网站在具备以下几个条件后,可以提出申请加入到这个列表里。
具备一个有效的证书
在同一台主机上提供重定向响应,以及接收重定向过来的HTTPS请求
所有子域名均使用HTTPS
在根域名的HTTP响应头中,加入HSTS Header,并满足下列条件:
过期时间最短不得少于18周(10886400秒)
必须包含includeSubDomains参数
必须包含preload参数
当你准好这些之后,可以在HSTS Preload List的官网上(https://hstspreload.org)提交申请,或者了解更多详细的内容。
7. 浏览器检查缓存中的DNS记录,以查找maps.google.com的相应IP地址。
DNS(域名系统)是一个数据库,用于维护网站名称(URL)及其链接的特定IP地址。互联网上的每个URL都有一个唯一的IP地址。IP地址属于托管我们请求访问的网站的服务器的计算机。例如,www.google.com的IP地址为209.85.227.104。因此,如果您愿意,可以在浏览器中输入http://209.85.227.104来访问www.google.com。DNS是一个URL列表及其IP地址,就像电话簿是一个名称列表及其相应的电话号码一样。
DNS的主要目的是人性化导航。您可以通过在浏览器上键入正确的IP地址轻松访问网站,但想象一下,我们必须记住我们经常访问的所有网站的不同数字集?因此,使用URL更容易记住网站的名称,让DNS为我们工作,并将其映射到正确的IP。
为了找到DNS记录,浏览器检查四个缓存。
● 首先,它检查浏览器缓存。浏览器为您之前访问过的网站维护一段固定时间的DNS记录存储库。因此,它是第一个运行DNS查询的地方。
● 其次,浏览器检查操作系统缓存。如果在浏览器缓存中找不到它,浏览器将在底层计算机操作系统上进行系统调用(即Windows上的gethostname)以获取记录,因为操作系统还会维护DNS记录的缓存。
● 第三,检查 hosts 文件中的记录
● 第四,它检查路由器缓存。如果在您的计算机上找不到它,浏览器将与维护其自己的DNS记录缓存的路由器通信。
● 第五,它检查ISP缓存。如果所有步骤都失败,浏览器将转移到ISP(互联网服务提供商 )。您的ISP维护其自己的DNS服务器,其中包括DNS记录的缓存,浏览器将检查该记录,最后希望找到您请求的URL。
您可能想知道为什么在如此多的级别上维护了如此多的缓存。虽然我们在某处缓存的信息并没有让我们感到非常舒服,但在缓存方面,缓存对于调节网络流量和改善数据传输时间非常重要。
8. 如果请求的URL不在缓存中,ISP的DNS服务器将启动DNS查询以查找托管maps.google.com的服务器的IP地址。
如前所述,为了让我的计算机与托管maps.google.com的服务器连接,我需要maps.google.com的IP地址。DNS查询的目的是搜索Internet上的多个DNS服务器,直到找到网站的正确IP地址。这种类型的搜索称为递归搜索,因为搜索将从DNS服务器重复继续到DNS服务器,直到它找到我们需要的IP地址或返回错误响应,说它无法找到它。
在这种情况下,我们将ISP的DNS服务器称为DNS recursor,其职责是通过询问互联网上的其他DNS服务器来寻找答案,从而找到目标域名的正确IP地址。其他DNS服务器称为名称服务器,因为它们基于网站域名的域架构执行DNS搜索。
在没有进一步混淆的情况下,我想使用下图来解释域架构。
我们今天遇到的许多网站网址都包含第三级域名,第二级域名和顶级域名。这些级别中的每一个都包含自己的名称服务器,在DNS查找过程中会对其进行查询。
对于maps.google.com,首先,DNS recursor将联系根名称服务器。根名称服务器将其重定向到.com域名服务器。.com名称服务器会将其重定向到google.com名称服务器。google.com名称服务器将在其“DNS记录”中找到maps.google.com的匹配IP地址,并将其返回到您的DNS recursor,然后将其发送回您的浏览器。
这些请求使用小数据包发送,这些数据包包含诸如请求内容和目的地IP地址之类的信息(DNS recursor的IP地址)。这些数据包在到达正确的DNS服务器之前通过客户端和服务器之间的多个网络设备传输。该设备使用路由表来确定数据包到达其目的地的最快方式。如果这些数据包丢失,您将收到请求失败错误。否则,他们将到达正确的DNS服务器,获取正确的IP地址,然后返回浏览器。
9. 浏览器检查 ARP(地址解析协议)缓存。
通过DNS获取到IP后,目标IP和本机IP分别与子网掩码相与的结果相同,那么它们在一个子网,那么通过ARP协议可以查到目标主机的MAC地址,否则的话,需要通过网关转发,也就是目标MAC是网关的MAC。
当地址解析协议被询问一个已知 IP 地址节点的 MAC 地址时,先在 ARP 缓存中查看,若存在,就直接返回与之对应的MAC地址;若不存在,才发送 ARP 请求查询。
查询请求需要进行编码,生成一个HTTP数据包,依次打上TCP、IP、以太网协议的头部。其中TCP头部主要信息是本机端口和目标端口号等信息,用于标识同一个主机的不同进程,对于HTTP协议,服务器端的默认端口号是80,本机浏览器的话生成一个1024到65535之间的端口号。IP头部主要包含本地IP和目标IP等信息。以太网协议头部主要是双方的MAC地址,目标MAC可以由第一条所诉方法得到。以太网数据包的数据部分,最大长度为1500字节,所以如果IP包太大的话还要拆包,比如IP包5000字节,要分为4包,每一包都包含一个IP头部。
ARP原理
每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系。
当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主机的MAC地址,如果有,则直接发送数据,如果没有,就向本网段的所有主机发送ARP数据包,该数据包包括的内容有:源主机 IP地址,源主机MAC地址,目的主机的IP 地址。
当本网络的所有主机收到该ARP数据包时,首先检查数据包中的IP地址是否是自己的IP地址,如果不是,则忽略该数据包,如果是,则首先从数据包中取出源主机的IP和MAC地址写入到ARP列表中,如果已经存在,则覆盖,然后将自己的MAC地址写入ARP响应包中,告诉源主机自己是它想要找的MAC地址。
源主机收到ARP响应包后。将目的主机的IP和MAC地址写入ARP列表,并利用此信息发送数据。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
10. 浏览器启动与服务器的TCP连接。
一旦浏览器收到正确的IP地址,它将与服务器建立连接,以匹配IP地址以传输信息。浏览器使用Internet协议来构建此类连接。可以使用许多不同的Internet协议,但TCP是用于任何类型的HTTP请求的最常用协议。
为了在您的计算机(客户端)和服务器之间传输数据包,建立TCP连接很重要。此连接是使用名为的进程建立的TCP / IP三次握手。这是一个三步过程,客户端和服务器交换SYN(同步)和ACK(确认)消息以建立连接。
客户机通过互联网向服务器发送SYN数据包,询问它是否为新连接打开。
如果服务器具有可以接受和发起新连接的开放端口,则它将使用SYN / ACK数据包响应SYN数据包的确认。
客户端将从服务器接收SYN / ACK数据包,并通过发送ACK数据包来确认它。
然后建立TCP连接以进行数据传输
建立 TCP 连接这一步也涉及到缓存 —— 浏览器会建立发送和接受缓冲区,用来临时存放双方通信的数据,保证通信数据不会丢包。
11. 浏览器向Web服务器发送HTTP请求。
建立TCP连接后,就可以开始传输数据了!浏览器将发送GET请求,要求提供maps.google.com网页。如果您输入凭据或提交表单,则可能是POST请求。此请求还将包含其他信息,例如浏览器标识(User-Agent标头),它将接受的请求类型(Accept标头),以及连接标头,要求它保持TCP连接为其他请求保持活动状态。它还将传递从浏览器为此域存储的cookie中获取的信息。
(如果您对幕后发生的事情感到好奇,可以使用Firebug等工具来查看HTTP请求。在我们不知情的情况下查看客户端和服务器之间传递的信息总是很有趣)。
12. 服务器处理请求并发回响应。
服务器包含一个Web服务器(即Apache,IIS),它接收来自浏览器的请求并将其传递给请求处理程序以读取和生成响应。请求处理程序是一个程序(用ASP.NET,PHP,Ruby等编写),它读取请求,其标题和cookie以检查请求的内容,并在需要时更新服务器上的信息。然后它将以特定格式(JSON,XML,HTML)组合响应。
负载均衡
网站可能会有负载均衡设备来平均分配所有用户的请求。
负载均衡,即对工作任务进行平衡,分摊到多个操作单元上执行,如图片服务器,应用服务器。可分为链路负载均衡,集群负载均衡,操作系统负载均衡
集群负载均衡又分为硬件负载均衡和软件负载均衡。
CDN
请求的数据可能存储在分布式缓存、静态文件或者数据库中。如果请求的数据是静态文件,如果在CDN上,那么CDN服务器又会处理这个用户的请求。如果在数据库中需要向数据库发起查询请求。
13. 服务器发出HTTP响应。
服务器响应包含您请求的网页以及状态代码,压缩类型(Content-Encoding),如何缓存页面(Cache-Control),要设置的任何cookie,隐私信息等。
如果查看上面的响应,第一行显示状态代码。这非常重要,因为它告诉我们响应的状态。使用数字代码详细说明了五种类型的状态。
●1xx仅表示信息性消息
●2xx表示某种成功
●3xx将客户端重定向到另一个URL
●4xx表示客户端出错
●5xx表示服务器部分出错
因此,如果您遇到错误,可以查看HTTP响应以检查您收到的状态代码类型。
14. 浏览器显示HTML内容(对于最常见的HTML响应)。
浏览器分阶段显示HTML内容。首先,它将呈现裸骨HTML骨架。然后它将检查HTML标记并发送对网页上其他元素的GET请求,例如图像,CSS样式表,JavaScript文件等。这些静态文件由浏览器缓存,因此下次访问该页面时它不必再次获取它们。最后,您会看到maps.google.com出现在您的浏览器上。
虽然这似乎是一个非常繁琐而且漫长的过程,但我们知道在我们按下键盘看见网页所需的时间不到几秒钟。所有这些步骤都在我们甚至没有注意到之前的几毫秒内发生。我真诚地希望本文可以帮助您回答“在浏览器中键入URL并按Enter键时会发生什么?”的问题。