前言
通常使用的网络(包括互联网)是在TCP/IP协议族的基础上运作的。而HTTP属于它内部的一个子集。在整个网络通行过程中,先通过TCP的三次握手建立连接,连接建立后再通过HTTP进行通信,通信完毕后通过TCP的四次挥手断开连接。整个流程如下图:
一、TCP/IP协议
计算机与网络设备要相互通信,双方必须基于相同的通信规则,我们把这种规则成为协议。TCP/IP是互联网相关的各类协议族的总称。协议中存在各式各样的内容,从电缆的规格到IP地址的选定方法、寻找异地用户的方法、双方建立通信的顺序等等。
ARP:ARP(Address Resolution Protocol)地址解析协议,根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
RARP:反向地址转换协议(RARP:Reverse Address Resolution Protocol) 反向地址转换协议(RARP)允许局域网的物理机器从网关服务器的 ARP 表或者缓存上请求其 IP 地址。网络管理员在局域网网关路由器里创建一个表以映射物理地址(MAC)和与其对应的 IP 地址。当设置一台新的机器时,其 RARP 客户机程序需要向路由器上的 RARP 服务器请求相应的 IP 地址。假设在路由表中已经设置了一个记录,RARP 服务器将会返回 IP 地址给机器,此机器就会存储起来以便日后使用。
ICMP:ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
1、TCP/IP的分层管理
TCP/IP协议族里最重要的一点就是分层。TCP/IP协议族按层次分为4层:应用层、传输层、网络层、链路层。
应用层:提供应用程序网络接口;
传输层:建立端到端连接;
网络层:选址和路由选择,该层规定了通过什么样的传输线路到达对方计算机,并把数据包传送给对方;
链路层:用来处理连接网络的硬件部,包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网卡),及光线等物理可见部分,硬件上的范畴均在链路层的作用范围之内;
2、TCP/IP通信传输流
1、客户端在应用层发出一个HTTP请求;
2、在传输层(TCP协议)把从应用层接收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后传给网络层;
3、在网络层(IP协议),添加作为通信目的的MAC地址后转发给链路层;(至此,发往网络的通信请求就准备齐全了)
4、接收端的服务器在接收到链路层的数据后,按序往上层发送并一层一层解析,一直到应用层;
发送端在层与层之间传输数据时,每经过一层是必定会被打上一个该层所属的首部信息。反之、接收到层与层传输的数据时,每经过一层会把对应的首部消去。
3、TCP/IP三次握手
TCP(Transmission Control Protocol)传输控制协议。
为了准确无误地将数据送达目标处,TCP协议采用了三次握手策略,TCP会向对方确认发送出去的数据是否成功到达。握手过程中使用了TCP的标志(flag),有6种标志:
SYN(建立联机)、ACK(确认)、PSH(传送)、FIN(结束)、RST(重置)、URG(紧急)
Sequence number(顺序号码) Acknowledge number(确认号码)
使用 connect() 建立连接时,客户端和服务器端会相互发送三个数据包,请看下图:
客户端调用 socket() 函数创建套接字后,因为没有建立连接,所以套接字处于CLOSED状态;服务器端调用 listen() 函数后,套接字进入LISTEN状态,开始监听客户端请求。
这个时候,客户端开始发起请求:
1) 当客户端调用 connect() 函数后,TCP协议会组建一个数据包,并设置 SYN 标志位,表示该数据包是用来建立同步连接的。同时生成一个随机数字 1000,填充“序号(Seq)”字段,表示该数据包的序号。完成这些工作,开始向服务器端发送数据包,客户端就进入了SYN-SEND状态。
2) 服务器端收到数据包,检测到已经设置了 SYN 标志位,就知道这是客户端发来的建立连接的“请求包”。服务器端也会组建一个数据包,并设置 SYN 和 ACK 标志位,SYN 表示该数据包用来建立连接,ACK 用来确认收到了刚才客户端发送的数据包。
服务器生成一个随机数 2000,填充“序号(Seq)”字段。2000 和客户端数据包没有关系。
服务器将客户端数据包序号(1000)加1,得到1001,并用这个数字填充“确认号(Ack)”字段。
服务器将数据包发出,进入SYN-RECV状态。
3) 客户端收到数据包,检测到已经设置了 SYN 和 ACK 标志位,就知道这是服务器发来的“确认包”。客户端会检测“确认号(Ack)”字段,看它的值是否为 1000+1,如果是就说明连接建立成功。
接下来,客户端会继续组建数据包,并设置 ACK 标志位,表示客户端正确接收了服务器发来的“确认包”。同时,将刚才服务器发来的数据包序号(2000)加1,得到 2001,并用这个数字来填充“确认号(Ack)”字段。
客户端将数据包发出,进入ESTABLISED状态,表示连接已经成功建立。
4) 服务器端收到数据包,检测到已经设置了 ACK 标志位,就知道这是客户端发来的“确认包”。服务器会检测“确认号(Ack)”字段,看它的值是否为 2000+1,如果是就说明连接建立成功,服务器进入ESTABLISED状态。
至此,客户端和服务器都进入了ESTABLISED状态,连接建立成功,接下来就可以收发数据了。
最后说明:三次握手的关键是要确认对方收到了自己的数据包,这个目标就是通过“确认号(Ack)”字段实现的。计算机会记录下自己发送的数据包序号 Seq,待收到对方的数据包后,检测“确认号(Ack)”字段,看Ack = Seq + 1是否成立,如果成立说明对方正确收到了自己的数据包。
思考:为什么要三次握手呢,两次握手不就可以了吗?
客户端发送了第一个连接的请求报文,但是由于网络不好,这个请求没有立即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达服务端,本来这已经是一个失效的报文,但是服务端接收到这个请求报文后,还是会向客户端发出确认的报文,表示同意连接。假如不采用三次握手,那么只要服务端发出确认,新的连接就建立了,但其实这个请求是失效的请求,客户端是不会理睬服务端的确认信息,也不会向服务端发送确认的请求,但是服务端认为新的连接已经建立起来了,并一直等待客户端发来数据,这样,服务端的很多资源就没白白浪费掉了,采用三次握手就是为了防止这种情况的发生,服务端会因为收不到确认的报文,就知道客户端并没有建立连接。这就是三次握手的作用。
4、TCP/IP四次挥手
下图演示了客户端主动断开连接的场景:
建立连接后,客户端和服务器都处于ESTABLISED状态。这时,客户端发起断开连接的请求:
1) 客户端调用 close() 函数后,向服务器发送 FIN 数据包,进入FIN_WAIT_1状态。FIN 是 Finish 的缩写,表示完成任务需要断开连接。
2) 服务器收到数据包后,检测到设置了 FIN 标志位,知道要断开连接,于是向客户端发送“确认包”,进入CLOSE_WAIT状态。
注意:服务器收到请求后并不是立即断开连接,而是先向客户端发送“确认包”,告诉它我知道了,我需要准备一下才能断开连接。
3) 客户端收到“确认包”后进入FIN_WAIT_2状态,等待服务器准备完毕后再次发送数据包。
4) 等待片刻后,服务器准备完毕,可以断开连接,于是再主动向客户端发送 FIN 包,告诉它我准备好了,断开连接吧。然后进入LAST_ACK状态。
5) 客户端收到服务器的 FIN 包后,再向服务器发送 ACK 包,告诉它你断开连接吧。然后进入TIME_WAIT状态。
6) 服务器收到客户端的 ACK 包后,就断开连接,关闭套接字,进入CLOSED状态。
思考:那么为什么是4次挥手呢?
可能有人会有疑问,TCP我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢.因为建立连接时,当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有等到我服务端所有的报文都发送完了,才能发送FIN报文,因此不能一起发送。故需要四步握手。
二、负责域名解析的DNS服务
DNS(Domain Name System)域名系统,作为域名和IP地址相互映射的一个分布式数据库。它提供通过域名查找IP地址,或逆向从IP地址反查域名的服务,使用户更方便的访问互联网。DNS协议运行在UDP(User Datagram Protocol )用户数据报协议之上,使用端口号53。和HTTP协议一样也是位于应用层的协议。
三、使用Cookie的状态管理
1、关于Cookie
HTTP是无状态协议。
优点:由于不必保留状态,自然可减少服务器的CPU及内存资源的消耗;
缺点:它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
假设要求登录认证的web页面本身无法进行状态管理(不记录登录状态),那么每次跳转新页面不是要再次登录,就是要在每次请求报文中附加参数来管理登录状态。要想保留无状态协议特征的同时,又要解决类似的矛盾问题,于是引入了Cookie技术。Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。
Cookie会根据从服务器发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下一次客户端在往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。
服务端发现客户端发送过来的Cookie后,会去检查究竟是从哪个客户端发送过来的请求,然后对比服务器上的记录,最后得到之前的状态信息。
2、为Cookie服务的首部字段
expires属性:Cookie的有效期(若不明确指定,则默认为浏览器关闭前为止)
path属性:将服务器上的文件目录作为Cookie的适用对象(若不指定,则默认为文档所在的文件目录)
domain属性:作为Cookie适用对象的域名(若不指定,则默认为创建Cookie的服务器的域名)
secure属性:仅在HTTPS安全通信时才会发送Cookie
HttpOnly属性:加以限制,使Cookie不能被JavaScript脚本访问
四、HTTP协议
1、HTTP协议进化史
HTTP 0.9
HTTP于1990年问世。那时的HTTP并没有作为正式的标准被建立。现在的HTTP其实含有HTTP 1.0之前版本的意思,因此被称为HTTP 0.9。HTTP 0.9作为HTTP协议的第一个版本,是非常弱的。请求(Request)只有一行,比如:GET www.baidu.com
如此简单的请求体,没有POST方法,没有HTTP请求头,并且,如果得不到所求的信息也不会报404 500等错误。那个时代的HTTP客户端只能接收纯文本类型。虽然HTTP 0.9看起来如此弱,但已经能满足那个时代的需求了。
HTTP 1.0
HTTP正式作为标准被公布是在1996年5月,版本命名为HTTP 1.0。HTTP 1.0最大的改变是引入了POST方法,使得客户端可以向服务器发送数据。另一个重大的改变是引入了HTTP头,使得HTTP不仅能返回错误代码,并且HTTP协议所传输的内容不仅限于纯文本,还可以是图片、动画等一系列格式。除此之外,还允许保持连接,即一次TCP连接后,可以多次通信,虽然HTTP 1.0默认是传输一次数据后就关闭。
HTTP 1.1
1997年1月发布的HTTP 1.1版本是目前主流的HTTP协议版本。HTTP 1.1并不像HTTP 1.0对于HTTP 0.9那样的革命性。但也有很多增强。
默认持久连接;
增加了Host头,比如:
GET /Careyson HTTP/1.1
Host: www.imooc.com
Get后面仅仅需要相对路径即可。这个提升使得在Web上的一台主机可以存在多个域。否则多个域名指向同一个IP会产生混淆。
此外,还引入了Range头,使得客户端通过HTTP下载时只下载内容的一部分,这使得线程下载成为可能。
另外,HTTP 1.1默认连接是一致保持的。
HTTP 2.0
HTTP 2.0在2013年8月进行首次合作共事性测试。HTTP 2.0采用二进制格式而非文本格式。HTTP 2.0的目的是通过支持请求与响应的多路复用来减少延迟,通过压缩HTTPS首部字段将协议开销降低,同时增加请求优先级和服务器端对推送功能的支持。
2、HTTP简介
1、HTTP协议(Hypertext transfer protocol 超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议。默认端口号为8080,HTTPS端口号为443;
2、HTTP协议承载于TCP协议之上,或者承载于SSL或TLS协议层之上(即HTTPS),如下图:
3、HTTP协议简单,客户向服务器请求服务时,只需传送请求方法和路径。因此,HTTP服务器的程序规模小,通信速度很快。
4、HTTP协议允许传输任意类型的数据对象,正在传输的类型由Content-Type字段标记;
3、HTTP之请求消息Request
1、关于URI(统一资源标识符)
URI就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。
http://host[":"port][abs_path]
http表示要通过HTTP协议来定位网络资源;
host表示合法的Internet主机域名或者IP地址;
port指定一个端口号,为空则使用缺省端口80;
abs_path指定请求资源的URI;如果URL中没有给出abs_path,那么当它作为请求URI时,必须以“/”的形式给出
例如:
2、HTTP请求方法:
GET请求:获取资源(浏览网页、下载应用、观看视频等)
POST请求:传输实体的主体(提交登录信息、上传文件到公有云等)
PUT请求:传输文件(鉴于HTTP 1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般不使用该方法)
HEAD请求:获得报文首部(和GET方法一样,但不返回报文主体,用于确认URI的有效性、资源更新日期、获取文件大小、做可用性探测等)
DELETE请求:删除文件(HTTP 1.1的DELETE方法和PUT方法一样不带验证机制,所以一般不使用该方法)
OPTIONS请求:用来查询请求URI资源时,服务器支持的方法(返回服务器支持的方法)
TRACE请求:追踪路径(发送请求时,在Max-Forwards首部字段中填入数值,每经过一个服务器就将该数字减1,当数值刚好减到0时,就停止继续传输,最后接受请求的服务器返回200 OK响应。客户端通过TRACE方法可以查询发送出去的请求是怎么被加工修/篡改的。TRACE方法容易引起跨站追踪攻击,所以一般不会用)
3、请求报文结构:
Host:请求资源所在的服务器(HTTP 1.1版本添加的字段。当多台虚拟主机运行在同一个IP上时,用Host加以区分)
User-Agent:HTTP客户端程序的信息(User-Agent会将创建请求的浏览器和用户代理的名称等信息传给服务器)
Accept:可接受的媒体类型
Accept-Language:接受的语言(如:en-us;q=0.7 表示美式英语,q是优先级权重值,在0-1.0之间,1优先级最高,不写q值则使用默认优先级1)
Accept-Encoding:接受的编码
DNT:禁止追踪(Do Not Track),1代表用户不想被第三方网站追踪,0代表接受追踪,null代表用户不置可否
Connection:Keep-Alive 持久连接
Pragma:要求所有的中间服务器不返回缓存的资源(Pragma是HTTP 1.1之前版本的历史遗留字段,仅作为与HTTP 1.0的向后兼容而定义)
Cache-Control:no-cache 要求所有的中间服务器不返回缓存的资源(HTTP 1.1版本的字段,由于要整体掌握全部中间服务器使用的HTTP版本是不现实的,所以,发送请求会同时含有Pragma和Cache-Control字段)
Via:代理服务器的相关信息(列出从客户端到源服务器经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添加 Via 头部,并填上自己的相关信息,当下一个代理服务器收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via部,并把自己的相关信息加到后面,以此类推,当源服务器收到最后一个代理服务器的请求时,检查 Via 头部,就知道该请求所经过的路由)
If-Match:比较实体标记ETag(只有当If-Match的字段值跟ETag值匹配一致时,服务器才会接受请求)
If-Modified-Since:比较资源的更新时间(如果在If-Modified-Since字段指定日期时间后,资源发生了更新,服务器会接受请求)
Refere:只要查看Refere就能知道请求的URI是从哪个web页面发起的
通用首部字段:
请求首部字段:
4、HTTP之响应消息Response
1、响应状态码:
2xx:成功
200:请求成功
204:该状态码表示服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分(一般只在需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用)
206:该状态码表示客户端进行了范围请求,而服务器成功执行了这部分GET请求。响应报文中包含由Content-Range指定范围的实体内容。
3xx:重定向
301:永久性重定向
302:临时重定向
304:文件未更新
4xx:客户端错误
401:该状态码表示发送的请求需要有通过HTTP认证的认证信息。另外若之前已进行1次请求了,则表示用户认证失败。
403:该状态码表明对请求资源的访问被服务器拒绝了。
404:该状态吗表明服务器上无法找到请求的资源。
5xx:服务器错误
500:该状态码表明服务器在执行请求时发生了错误。
502:执行请求时,从上游服务器接收到无效的响应
503:该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求
504:执行请求时,未能及时从上游服务器或者辅助服务器(例如DNS)收到响应
2、响应报文结构:
Date:日期和时间
Server:服务器上安装的HTTP服务器应用程序信息(软件名称、版本号、启用时间等)
Last-Modified:资源的最后修改日期和时间
ETag:实体标识(服务器为每一份资源分配对应的ETag值,将资源以字符串形式做唯一性标识的方式,资源更新时,ETag值也需要更新)
Accept-Ranges:告知客户端服务器是否能处理范围请求(bytes:可以处理范围请求;none:服务器不能处理范围请求)
Content-Length:表明实体主体部分的大小(单位是字节)
Connection:keep-alive 或 close 开启或关闭HTTP持久连接
Content-Type:实体主体的媒体类型
Vary:代理服务器缓存的管理信息
Content-Range:bytes 5001-10000/10000 告知客户端响应返回的实体范围
Content-Length:实体主体部分的大小(单位是字节)
Content-Encoding:实体的主体部分适用的编码方式
响应首部字段:
实体首部字段:
5、HTTP的缺点
1、明文通信(不加密),可能遭窃听;
2、不验证通信方身份,可能遭伪装;
3、无法证明报文完整性,可能遭篡改;
为了解决以上这些问题,需要在HTTP上再加入加密处理和认证等机制。我们把添加了加密机认证机制的HTTP称为HTTPS。
五、HTTPS
1、关于HTTPS
1、HTTP + 加密 + 认证 + 完整性保护 = HTTPS
2、HTTPS是身披SSL外壳的HTTP
HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL(Secure Socket Layer 安全套接层)和TLS(Transport Layer Security 传输层安全性协议)协议代替而已。
通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信。采用SSL后,HTTP就有了加密、证书校验和数据完整性保护等功能。
2、HTTPS的加密方式
1、非对称加密
非对称加密算法需要两个密钥:公钥(publickey)和私钥(privatekey)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对秘钥并将其中的公钥向其它方公开;得到该公钥的乙方使用该公钥对机密信息进行加密后再发送给甲方;甲方再用自己保存的私钥对加密后的信息进行解密。
非对称加密的优点:算法强度复杂、而使得加密解密速度没有对称加密解密的速度快。
2、对称加密
只有一把秘钥,采用单秘钥加密方法,同一个秘钥可用于信息的加解密。
对称加密的优点:加密速度快、加密效率高。
3、HTTPS的混合加密机制
HTTTPS采用非对称加密和对称加密并用的混合加密机制。非对称加密主要用于交换对称加密的秘钥。即在交换秘钥环节使用非对称加密,之后的建立通信交换报文阶段则使用对称加密方式。这样充分利用了两种加密方式各自的优势。
3、证明服务器颁发的公钥正确性的证书
1、CA证书的生成过程
公开秘钥加密方式还是存在一些问题的。那就是无法证明公钥本身就是货真价实的公开秘钥。可能不是预想的那台服务器发行的公钥,可能传输中被攻击者调包了等等。
为了解决上述问题,可以使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开秘钥证书。数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。其业务流程如下:
1、服务端的运营人员向数字证书认证机构提出公开秘钥的申请;
2、数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开秘钥做数字签名,然后分配这个已签名的公开秘钥,并将该公开秘钥放入公钥证书后绑定一起;
3、服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,用于非对称加密方式通信;
4、接到数字证书的客户端使用数字证书认证机构的公开秘钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:1、认证服务器的公开秘钥是真实有效的数字证书认证机构;2、服务器的公钥是值得信赖的;
此处认证机关的公开秘钥必须安全地转移到客户端。使用通信方式时,如何安全转交是一件很困难的事,因此,多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的认证证书。
2、CA证书一般会包含以下内容:
1、证书的颁发机构、版本;
2、证书的使用者;
3、证书的公钥;
4、证书的有效时间;
5、证书的数字签名Hash值和签名Hash算法
3、客户端如何校验CA证书
CA证书中的Hash值,其实是用证书的私钥进行加密后的值(证书的私钥不在CA证书中)。然后客户端得到证书后,利用证书中的公钥去解密该Hash值,得到Hash-a;然后再利用证书内的签名Hash算法去生成一个Hash-b。最后比较Hash-a和Hash-b这两个的值。如果相等,那么证明了该证书是对的,服务端是可以被信任的;如果不相等,那么就说明该证书是错误的,可能被篡改了,浏览器会给出相关提示,无法建立起HTTPS连接。除此之外,还会校验 CA 证书的有效时间和域名匹配等。
4、HTTPS 中的 SSL 握手建立过程
1、客户端通过发送ClientHello报文开始SSL通信。报文中包含客户端支持的SSL版本、加密组件列表(所使用的加密算法及秘钥长度等);
2、服务端可进行SSL通信时,会以ServerHello报文作为应答。和客户端一样,在报文中包含SSL版本及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的;
3、之后服务器发送Certificate报文。报文中包含公开秘钥证书;
4、最后服务器发送ServerHelloDone报文,通知客户端,最初阶段的SSL握手协商部分结束;
5、SSL第一次握手结束之后,客户端以ClientKeyExchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公开秘钥进行加密;
6、接着客户端继续发生Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret秘钥加密;
7、客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解码该报文作为判定标准;
8、服务器同样发送Change Cipher Spec报文;
9、服务器同样发送Finished报文;
10、服务器和客户端的Finished报文交换完毕后,SSL连接就算建立完成。之后的通信会受到SSL保护。从此处开始进行应用层协议的通信,即发送HTTP请求;
11、应用层协议通信,即发送HTTP响应;
12、最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,这步之后再发送TCP FIN报文来关闭与TCP的通信;
以上流程中,应用层发送数据是会附加一种叫做MAC(Message Authentication Code)的报文摘要。MAC能够查知报文是否遭篡改,从而保护报文的完整性。
下面是对整个流程的图解。图中说明了使用服务器的公开秘钥证书建立HTTPS通信的整个过程。
六、通信数据转发程序:代理、网关、隧道
HTTP通信时,除客户端和服务器外,还有一些用于通信数据转发的应用程序,如:代理、网关、隧道。它们配合服务器工作。这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。
1、代理
代理是一种有转发功能的应用程序,它扮演了位于服务器与客户端“中间人”的角色,接收客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。
使用代理的理由有:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的等等。
代理分为缓存代理和透明代理
缓存代理:代理转发响应时,缓存代理会预先将资源的副本(缓存)保存在代理服务器上。当代理再次接收到相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应。
透明代理:转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理。反之,对报文内容进行加工的代理称为非透明代理。
2、网关
网关是转发其他服务器通信数据的服务器,接收从客户端发送的请求时,它就像自己拥有资源一样对请求进行处理。有时客户端可能都察觉不到,自己的通信目标是一个网关。网关能使通信线路上的服务器提供非HTTP协议服务。
利用网关能提高通信的安全性,因为可以在客户端和弯管之间的通信线路上加密以确保连接的安全。比如:在web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。
3、隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。隧道可以按要求建立一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端与服务器进行安全的通信。隧道本身不去解析HTTP请求。也就是说请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。
八、HTTP CONNECT通道
1、关于CONNECT
为了确保数据通信的安全,浏览器与源服务器之间是通过HTTPS加密通信的。代理服务器自身无法读取通信内容。然而当浏览器需要通过代理服务器发起HTTPS请求时,由于请求的站点地址和端口号都保存于HTTPS请求头中,代理服务器是如何既确保通信是加密的又知道该往哪里发送请求呢?
为了解决这个问题,浏览器需要先通过明文HTTP形式向代理服务器发送一个CONNECT请求告诉它目标站点地址及端口号。当代理服务器收到这个请求后,会在对应的端口上与目标站点建立一个TCP连接,连接建立成功后返回一个HTTP 200状态码告诉浏览器与该站点的加密通道已建成(此时的状态码虽然是200,但状态码信息不是OK ,而是Connection Established)。接下来进行通信时,代理服务器仅仅是以中转的角色来回传输浏览器与该服务器之间的加密数据包,并不对数据包进行解密,以保证HTTPS加密通信的安全性。
2、CONNECT通道建立流程
1、浏览器向代理服务器发送CONNECT请求:
2、代理服务器返回HTTP 200状态台码表示连接已建立:
与普通的HTTP响应不同的是,这个响应不需要包含Content-Type首部。此时连接的是对原始字节进行转接,不在是报文的承载者,所以不需要使用内容类型。
3、浏览器和服务器开始HTTPS握手并交换加密数据,代理服务器只负责传输彼此的数据包,并不能读取具体数据内容。从Wireshark抓包中可以看出,在第12贞HTTP/1.0 200返回后,浏览器和服务器开始进行SSL握手。
九、隧道(tunnel)
1、介绍
用户使用隧道方式,可以通过HTTP应用程序访问使用非HTTP协议的应用程序。这样就可以在HTTP上捎带其他协议数据。
2、用途
隧道的常见用途是通过HTTP连接承载安全套接层的加密数据流,这样SSL数据流就可以穿过只允许web数据流通过的防火墙。
例如:隧道收到一条HTTP请求,要求建立一条到目标地址和端口的输出连接,然后在HTTP信道上通过隧道传输加密的SSL数据流,这样就可以将其盲转发到目标服务器上。
3、隧道分为不使用CONNECT的隧道和使用CONNECT的隧道
1.不使用CONNECT的隧道
代理服务器收到客户端的HTTP请求后,会重新创建Request请求,并发送到目标服务器。当目标服务器返回Response给代理后,代理会对Response进行解析,然后重装Response发给客户端。
可以看出,在不使用CONNECT的情况下,代理服务器完全可以对数据进行修改,而且还有一个弊端是代理HTTPS时,代理服务器由于没有密钥因此无法解密,从而无法实现数据包的重组与转发。
2、使用CONNECT的隧道
客户端向代理发起CONNECT时,就是告诉代理,先在代理和目标服务器之间建立起连接,在连接建立后,目标服务器会返回一个响应给代理,代理创建并返回一个连接就绪的报文给客户端。(状态码为200,状态码信息为Connection Established)。在此之后,客户端跟目标服务器的所有通信将使用之前建立起来的连接进行通信。
在这种情况下的隧道,代理仅仅实现盲转发,而不会去关心转发的数据。
4、CONNECT建立一条SSL隧道的流程
1、图中a,客户端发送一条CONNECT请求给隧道网关。客户端的CONNECT方法请求隧道网关打开一条TCP连接(在这里打开的是到主机orders.joes-hardware.com的标准SSL端口443的链接);
2、图中b和c创建TCP连接;
3、一旦建立了TCP连接,网关就会发送一条HTTP 200 Connection Established响应来通知客户端(如图d);
4、此时,隧道就建立起来了。客户端通过HTTP隧道发送的所有数据都会被直接转发给输出TCP连接,服务器发送的所有数据都会通过HTTP隧道转发给客户端;