前言
http 协议是一个在计算机世界里专门用于两点之间传输文字、图片、音频、视频等超文本
数据的约定和规范。到目前为止,http 常见版本有 HTTP/1.1,HTTP/2.0,HTTP3.0,不同版本的 HTTP 特性是不一样的。
以最常用的 HTTP1.1 版本为例,它最突出的优点就是简单、灵活、易于扩展、应用广泛和跨平台。简单体现在 http 基本报文格式实际上就是消息头加上消息体,头部信息字段也是key-value
形式的简单文本,学习和理解成本较低;灵活和易于扩展体现在 http 协议里的各类请求方法、uri/url、状态码、头字段等组成要求没有被固定死,允许开发人员根据自己需要进行二次开发
,而且 http 协议工作在应用层(osi 第七层),这意味着它的下层可以任意变化。
至此就引出了本文要介绍的第一个协议: https,它就是在 http 与 tcp 层之间增加了 SSL/TLS 安全传输层。
在正式介绍之前需要先回答一个问题:http 协议明明可以工作的很好,为什么还需要重新设计 https 协议呢?这个问题的等价问题是:HTTP/1.1 协议的缺点是什么?
HTTP 协议拥有优缺点共存的特性,分别是无状态、明文传输、不安全
。
- 无状态:无状态的好处是服务器不需要记忆 http 的状态,因此省去了用于记录状态信息的这部分资源开销,可以减轻服务器的压力从而将更多的 cpu 和内存用来对外提供有效服务;而无状态的坏处也很明显,由于服务器不记录任何状态信息,那么意味着每次关联性操作时都需要重新验证用户的身份(解决技术:Cookie 技术,它在请求和响应报文中写入 Cookie 信息来控制客户端状态)。
- 明文传输:明文意味着对人类阅读友好,比如使用 wirkshark 抓包后可以直接阅读自己感兴趣的内容,为调试工作带来极大的便利;而另一方面明文传输意味着客户端和服务器通信中的数据相当于在不安全信道中"裸奔",毫无隐私可言,敏感信息极易泄露(如果有)。
- 不安全:http 协议不使用复杂密码学对通信内容进行加密,这意味着可以省去这部分资源消耗和时间开销。但是使用未加密的明文通信,很可能遭受窃听、数据篡改、中间人攻击等。
HTTP/2.0 基于 https 协议,支持线程级别多路复用和连接池。微服务中常用的 grpc 底层使用的就是 HTTP/2.0。
针对 http 比较严重的不安全问题,通过引入 SSL/TLS 层,保证了通信的安全性,下面具体看下 https 协议的工作原理。
HTTPS 协议
前置知识
1 TCP
本文主要介绍 https 协议,有关 tcp 连接的建立推荐:《UNIX 网络编程第一卷》、《深入理解 Linux 网络》,重点理解
- 三次握手交换的状态信息、半连接队列、全连接队列、SYN 攻击
- socket 内核结构体 sock
- socket、bind、listen、accept、connect、recv、send 系统调用
- 为什么 3 次握手和 5 次握手实际上效果是一样的,涉及到共识问题(继续深挖可以去研究拜占庭将军问题)。
2 密码学
HTTPS 在 HTTP 和 TCP 之间加入了 SSL/TLS 协议,实现了信息加密、内容完整性校验和身份验证的能力。涉及到的密码学知识有:
- 使用非对称加密算法安全地协商用于通信的会话秘钥
- 使用对称加密算法对通信内容进行快速加密和解密
- 使用数字证书技术验证通信对端身份真实性
- 使用哈希摘要算法校验通信内容的完整性
为什么不直接使用对称加密算法?有关对称加密和非对称加密的实现原理不做过多介绍,推荐书籍《现代密码学》。本文你只需要知道:对称加密只使用一个秘钥,它的加解密速度极快,因此适合在通信阶段对通信内容进行加密(几乎不影响传输速度)。非对称加密使用公钥和私钥两把秘钥,它的加解密很耗时(相对于对称加密),但是它能够在不安全网络中实现安全的数据交换,所以适合用于双方协商会话秘钥。
有关数字证书的介绍,一个数字证书通常包含:
- 公钥
- 持有者信息
- 证书认证机构 CA(Certificate Authority)的信息
- CA 对这份文件的数字签名以及使用的算法
- 证书有效期
- 其他信息
CA(Certificate Authority,证书认证机构)就相当于网络世界里的"公安局"、"公证中心",具有极高的可信度。数字证书中包含的有权威认证机构的签名,对端在收到后可以对数字证书进行验证,只有证书合法才代表通信方的身份是可信的,以防止第三方进行冒充。在密码局工作的应该听说过:上海 CA、广州 CA,它们的工作就与此相关。
如果没有证书签名,服务端将证书源文件直接发送给客户端,"中间人"拦截这条消息,修改证书中的公钥信息并进行自签名,然后将伪造的证书发送给客户端。客户端对数字证书文件内容的验证可以通过(签名是中间人自己构造的,用户手动点击同意自签证书才可以通过),此时中间人已经成功获得客户端的信任。于是客户端向"中间人"发送自己的数字证书,"中间人"收到后,再伪造一个客户端的证书发送给服务端。服务端验证也可以通过,此时中间人又成功获得了服务端的信任。接下来客户端向"中间人"发送请求,"中间人"使用自己的私钥解密数据,然后再使用自己的公钥加密后转发给服务器。服务器返回响应后,"中间人"再使用私钥解密响应数据,再使用和客户端通信的公钥对响应进行加密并转发给客户端。也就是说,整个通信过程实际上都是经过"中间人"的,但是客户端和服务器却毫无感知,隐私性和安全性荡然无存。
而签名的作用实际上是避免中间人攻击(Man-in-the-Middle Attack,MITM),防止中间人在获取证书时对证书内容的篡改。
CA 签发证书的过程上图所示,文字描述如下:
- 首先 CA 会把持有者的公钥、用途、颁发者、有效期等信息打成一个包(可以理解为文件证书文件),然后对这个文件进行 Hash 计算得到一个校验和 Checksum H1。
- 然后 CA 使用自己的私钥(可以认为绝对安全)将该校验和加密以生成 Certificate Signature,也就是对数字证书做了签名,最后将 Certificate Signature 添加在文件证书上,就得到了最终的数字证书。
- 服务端将数字证书发给客户端验证,客户端首先使用相同的 Hash 算法获取文件证书的校验和 H2。
- 然后使用集成在浏览器和操作系统中的 CA 公钥验证数字证书 Cerificate Signature 的有效性,验证通过后得到校验值 Checksum H1。
- 最后比较 H1 和 H2,如果值相同,则为可以信任的证书,否则认为证书不可信。
Hash 算法具有单向性和防碰撞性,这意味着从校验和反推出原始数据以及对两个不同数据做哈希后得到相同校验和基本上是不可能的。所以在使用安全哈希算法时,你就可以认为哈希算法的输入和哈希算法的输出是唯一对应的,如果修改了输入,那么输出就会发生改变。以 sha256 算法为例,该算法会经过 64 轮的迭代,每轮都引入了随机性,所以经过 64 轮迭代后,哪怕一个 bit 的微小变化,最终呈现出的结果差异也是巨大的。这也是为什么可以使用哈希算法校验数据完整性的原因。
证书的验证过程中存在一个证书信任链的问题,最上层证书称为根 CA 证书,由根 CA 证书签发的证书叫做中间证书。而一般向 CA 申请的证书是由中间证书签发的,之所以这样设计实际上是类似于权限树,不至于一个私钥的泄露导致整个信任链的坍塌,实际上就是控制影响域的设计思想。比如在 golang 中,会对子 goroutine 发生的 panic 进行捕获,防止向上传播影响主 goroutine 和其他 goroutine 的正常运行;又比如单体应用向微服务的演进,单体应用一旦崩溃将导致整个服务不可用,而微服务架构下,每个服务的影响范围仅限于当前服务和依赖它的服务,而不会影响全部的服务。
从上面的分析我们知道,我们所使用的数字证书中保存的签发人信息很可能是某个中间 CA,而我们系统中可能只集成最顶层根 CA 的公钥,因此无法直接验证数字证书的有效性。于是客户端需要先向数字证书中的颁发机构 CA 请求中间证书,然后再通过中间证书找到根证书也就是自签证书(再没有上级签发机构了)。应用软件检查根证书是否已经在根证书列表中预载(MAC 系统搜索钥匙串访问就可以看到预载的根证书列表),如果有那么可以直接利用根证书中的公钥去验证中间证书的有效性,如果验证通过,就认为该中间证书是可信的。一旦中间证书验证通过,那么由它颁发的服务端的数字证书也是可信的。最后串起来整个证书信任链:浏览器或者操作系统信任根证书--->根证书信任自己签发的中间证书--->中间证书信任自己签发的数字证书。
TLS 协议
假设你已经基本理解上述前置知识,那么下面就来看 https 是如何通过 SSL/TLS 协议建立安全连接的。
SSL/TLS 协议基本流程可以概括为:
- 客户端向服务端索要并验证服务器的公钥。
- 双方协商生成「会话秘钥」。
- 双方使用「会话秘钥」进行加密通信。
前两步属于 SSL/TLS 的建立过程,也叫做 TLS 握手阶段。TLS 握手阶段共涉及 4 次通信,使用不同的密钥交换算法其过程会有些许不同,但主体逻辑类似。现在常用的密钥交换算法有两种,分别是基于 RSA 的密钥交换算法和基于 ECDHE 的密钥交换算法。
https 和 http 协议一样,下层也是使用 tcp 协议提供的服务,因此第一步先建立 tcp 连接。如果是 http 协议,tcp 连接一旦建立就可以发送数据了。而在 https 协议中,tcp 三次握手成功后,还需要进行 TLS 的四次握手以在不安全的网络空间内建立安全的虚拟通信通道。
TLS 之 RSA 算法握手过程
直接上图
上图简要概述了 TLS 的握手过程,其中每一个圆角矩形都是一个记录(record),记录是 TLS 收发数据的基本单位,类似于 TCP 里的 Segment。多个记录可以组合为一个 TCP 报文进行发送,所以一般经过「四个消息」就可以完成 TLS 握手,大概需要 2 个 RTT 的时延,之后就可以在安全的通道里发送 http 报文,这就相当于实现了 https 协议。
使用 wireshark 工具抓一个用 RSA 密钥交换算法的 TLS 握手过程的包,如图共经历了四次握手。
对应这个图描述一下基于 RSA 的 TLS 握手全过程。
- 客户端首先会发送一个「Client Hello」消息,在这个消息中包含了客户端随机生成的随机数 Client Random、客户端使用的 TLS 版本号以及客户端支持的密钥套件列表。
- 其中随机数是后续生成会话秘钥的密码材料
- TLS 版本号则是让对端知道自己使用的 TLS 版本以让对方判断是否可以建立 TLS 通信
- 密钥套件列表则是告知对方自己支持的密码套件,比如客户端支持的对称加密算法 有AES128、AES256,支持的非对称加密算法(密钥交换算法)有 ECDHE 和RSA,支持的哈希摘要算法有 SHA256、SHA384 等,一般都是以组合形式提供
「密钥交换算法+签名算法+对称加密算法+摘要算法」
。
- 服务端在收到客户端的「Client Hello」消息后,会确认自己是否支持 TLS 版本,如果支持则从客户端提供的密码套件列表中选择一个密码套件用于后续的 TLS 握手,然后服务端也会随机生成一个随机数 Server Random。服务端将这些记录打包在消息「Server Hello」中发送给客户端。
- 客户端按照之前介绍的证书验证过程验证证书有效性,验证通过后继续往下走。
- 接着客户端会再生成一个随机数,一般称为预主密钥(PreMaster Secret),它也是用于生成「会话密钥」的材料之一。必要保证该密钥被安全交换,因此接下来就会用到密钥交换算法,这里使用的是 RSA 算法。客户端使用服务端可信数字证书中的公钥对预主密钥进行加密,通过「Client Key Exchange」消息传给服务端。
- 服务端收到「Client Key Exchange」消息后,使用 RSA 私钥解密从而获得客户端发来的预主密钥。
- 至此客户端和服务端双方都共享了三个随机数,分别是客户端选择的随机数 Client Random、服务端选择的随机数 Server Random 以及客户端选择的预主密钥 PreMaster Secret。于是双方根据这三个随机数生成「会话密钥」(Master Secret),它属于对称型密钥,用于对后续的 HTTP 请求和响应数据进行加密。
- 在生成完「会话密钥」后,客户端会再向服务端发送一条「Change Cipher Spec」的消息,告知服务端自己已经生成了「会话密钥」,接下来可以使用对称加密的方式进行加密通信了。
- 最后客户端将之前从服务端收到的消息统一起来做个摘要,并使用会话密钥进行加密后通过「Encrypted Handshake Message(Finished)」消息发给服务端。这条消息有两个作用,第一个作用是让服务器验证一下之前的握手过程中的消息有没有被篡改过,另一个作用就是验证一下「会话密钥」是否可用。
- 服务器收到 Finished 消息后进行验证,验证通过后,也向客户端发送「Change Cipher Spec」和 「Entrypted Handshake Message」消息,告知客户端自己也准备好了加密通信,让客户端也验证一下之前握手消息是不是被篡改过,会话密钥是否可用。
- 当客户端验证完成也没有问题后,那么整个 TLS 握手过程就结束了。
- 接下来通信双方就可以用「会话密钥」加解密 HTTP 请求和响应了,所有数据在不安全网络中就是以密文的形式传输的了。
最后借用小林 coding 中的一张图来总结上述过程。
TLS 之 ECDHE 算法握手过程
使用 RSA 进行密钥协商算法的最大问题是不支持前向保密。因为客户端传递随机数给服务端时使用的是公钥加密,服务端收到后使用私钥解密得到随机数。一旦服务器私钥泄露,过去被第三方截获的所有 TLS 通信密文都会被破解。为了解决这个问题,后面就出现了安全性更高的 ECDHE 密钥协商算法(现在大多数网站使用的都是 ECDHE 密钥协商算法),下面具体来看。
先总体概述一下 ECDHE 密钥交换算法的过程:
- 双方事先协商好使用哪种椭圆曲线,椭圆曲线基点 G 选择为何值,这两个参数均公开。
- 确定好基础参数后,双方各自随机生成一个随机数作为私钥 d,并通过 d 和基点 G 相乘得到椭圆曲线上的点 Q,这个 Q 就作为公钥使用。客户端的公私钥假设为(d1,Q1),服务端的公私钥假设为(d2,Q2)。
- 然后双方交换各自的公钥,此时客户端已知 d1、Q1 和 Q2,服务端已知 d2、Q1 和 Q2。然后客户端计算 d1 和 Q2 的乘积得到一个点,服务端计算 d2 和 Q1 的乘积也得到一个点。又因为椭圆曲线上满足乘法的交换律和结合律,那么 d1 和 Q2 的乘积就可以表示为 d1d2G,而 d2 和 Q1 的乘积也可以表示为 d1d2G。再根据椭圆曲线图形性质可知,一个 x 可能对应两个 y,但是无论如何 x 值都是一样的。所以双方得到点的 x 坐标就作为共享密钥,也就是会话密钥。
概述完之后直接上图
图中大部分概念都已经介绍或者和 RSA 的类似,不做过多介绍。下面还是从抓包图开始展开来看:可以看到还是四次握手,如果细心观察可以发现在使用了 ECDHE 算法后,在 TLS 第四次握手之前客户端就已经开始发送加密的 HTTP 请求了,这个行为有个非常贴切的命名
TLS False Start(TLS 伪启动)
,和TCP Fast Open
类似都是用来加快数据传输的。
TLS 伪启动是一种优化 TLS 四次握手过程的技术,它在客户端在完成自身加密设置后立即开始发送加密数据而不是等待服务器完成其加密设置后再发送数据,这样可以减少一次 RTT 延迟,从而加快连接的建立速度。
TCP Fast Open(TFO)则是一种优化 TCP 三次握手的技术,允许在建立连接的同时发送数据,通过在 SYN 包中携带数据,从而减少连接建立的延迟。
- SYN with Data:客户端发送带有数据的 SYN 包
- SYN-ACK with Data:服务器回复带有数据的 SYN-ACK 包并对接收到的数据进行确认。
- ACK:客户端发送 ACK 包确认连接建立。
通过这种方式,数据传输可以在连接建立的同时就开始,从而减少一次 RTT 的延迟。
最后以文字形式描述基于 ECDHE 密钥交换算法的 TLS 握手全过程:
- 客户端先发送一个 「Client Hello」 消息,消息中包含的内容和 RSA 第一次握手中的内容一样。
- 服务端收到客户端「打招呼」后,也回复一个「Server Hello」消息,消息中包含服务端确认使用的 TLS 版本号、服务端选择的随机数和服务端选择使用的密码套件如「 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384」,代表密钥协商算法使用 ECDHE;签名算法使用 RSA;对称加密算法使用 AES 算法,密钥长度 256 位,分组模式为 GCM;摘要算法使用 SHA384。
- 接着服务端为了证明自己的身份,发送 Certificate 消息将自己的数字证书也发给客户端。接下来就和 RSA 握手过程差别很大了,服务端在发送完证书之后紧接着就发送了「Server Key Exchange」消息。在这个过程中服务端主要做了三件事,第一件事是选择了一种椭圆曲线确定了基点和基础参数,这些都会公开给客户端。第二件事是选择一个随机数作为私钥,并根据选择的 G 计算出椭圆曲线公钥,这个也会公开给客户端。第三件事是为了保证这个公钥不被篡改,服务端使用 RSA 签名算法给服务端的椭圆曲线公钥做个签名。随后就是「Server Hello Done」消息,服务端告知客户端提供信息完成,打招呼阶段结束。
- 到目前为止,TLS 两次握手结束,服务端已知信息有:客户端选择的随机数 Client Random、服务端选择的随机数 Server Random、使用的椭圆曲线及其基础参数以及服务端的椭圆曲线公钥。
- 客户端在收到第二次握手的消息后,先对服务器证书进行验证以获得可信的 RSA 公钥。然后客户端也生成一个随机数作为椭圆曲线私钥并根据私钥和 G 生成椭圆曲线公钥,然后通过「Client Key Exchange」消息公开给服务端(无需签名,已有随机数做安全保证)。
- 至此双方都有了对方的椭圆曲线公钥、自己的椭圆曲线公钥、基点 G 的信息。于是双方就可以计算出椭圆曲线上的对应点,它们的 x 坐标是一样的。
- 最终的会话密钥由 Client Random 和 Server Random 以及椭圆曲线上特殊点的 x 坐标这三个材料生成(TLS 不信任单个伪随机数的可靠性)。计算出会话密钥后,客户端再发送「Change Cipher Spec」和「Encrypted Handshake Message」消息告知服务端自己已经准备好加密通信并让服务端验证之前发送消息的完整性。
- 服务端验证成功后,也进行同样的操作,向客户端发送「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果客户端验证也没问题,那么握手就正式完成了。接下来就可以正常收发加密的 HTTP 请求和响应了。
RSA 算法和 ECDHE 算法都是基于密码学中的困难问题,RSA(Rivest-Shamir-Adleman,三个发明者)基于大质数分解问题,其安全性依赖于讲一个大整数分解为两个大质数的困难性。具体来说,RSA 使用两个大质数 p 和 q 的乘积 n 作为模数,公钥和私钥的生成都依赖于这个模数,拥有私钥者可以利用指数抵消轻松拿到明文,而不知道私钥的攻击者所需要的计算量就目前来看是不可能在短时间内完成的。ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)算法基于椭圆曲线离散对数问题,其安全性依赖于在椭圆曲线上计算离散对数的困难性。具体来说,给定椭圆曲线上的两个点 P 和 Q,找到整数 k 使得 Q = kP 是非常困难,而知道 k 和 P 计算 Q 是非常简单的。像这种单向计算简单,反向计算困难的函数在密码学中称为陷门函数。更进一步了解推荐阅读书籍:《可证明安全性》。
小结
RSA 和 ECDHE 握手过程的区别:
- RSA 密钥协商算法「不支持」前向保密,ECDHE 密钥协商算法「支持」前向保密;
- 使用了 RSA 密钥协商算法,TLS 完成四次握手后,才能进行应用数据传输,而对于 ECDHE 算法,客户端在完成自身加密设置后立即开始发送加密数据而不是等待服务器完成其加密设置后再发送数据,这样可以减少一次 RTT 延迟,从而加快连接的建立速度;
- 使用 RSA 的 TLS 握手需要交换的信息有 Client Random、Server Random、Pre-Master Secret,而 Pre-Master Secret 是客户端在第三次 TLS 握手时随机选择的,因此 Key Exchange 消息出现在第三次握手时。而使用 ECDHE 的 TLS 握手需要交换的信息有 Client Random、Server Random、椭圆曲线、基点 G、椭圆曲线公钥,而服务端在第二次握手时就可以确定自身的这些信息,因此 Key Exchange 消息在第二次握手时就可以发出,这是使用两种密钥交换算法的 TLS 握手过程区别比较大的地方。
- 算法级别的区别,需要自己了解算法细节。
IPsec 协议
基础知识
IPsec 是一组协同工作的协议,它们的目标是在不安全的网络上建立安全的网络隧道。例如连接两个安全网络,更具体说是连接公共互联网上称为对等节点的路由器。假设你在一家拥有多个站点、分布在全球的分部组成的超大型公司工作,你的公司希望将所有分部连接在一起,也希望所有分部都可以访问公司在 AWS 或者其他云服务厂商拥有的基础设施,这时候就可以使用 IPsec 协议。
It sets up secure tunnels acroos insecure networks.
IPsec 提供身份验证,所以只有彼此认识并且可以相互验证的对等方才能够连接。IPsec 协议承载的任何流量都是加密过的,不易破解也无法在不被检测到的情况下进行更改。
公网是一个不安全的网络,可能到处都是想要窃取你数据的攻击者。通过这个不安全网络我们可以在对等节点之间创建 IPsec 隧道。在 IPsec VPN 中,有一个"感兴趣的的流量"(Interesting traffic)的概念,可以简单理解为符合某些自定义规则的流量,比如以某个特定网络前缀开头的网络流量。无论规则如何,如果流量与任何自定义规则匹配,都会被归类为"有趣流量"并且会创建 VPN 隧道负责传输这部分流量。如果没有任何"感兴趣的的流量"那么隧道最终会被关闭,然后在系统下一次检测到"感兴趣的的流量"时才会重新建立。要理解的关键是:即使这些隧道使用公网,隧道内传输的任何数据在通过不安全的网络传输时都会被加密保护起来。
为了了解 IPsec 的细节,还需要其他一些关键基础知识。
密码学
- 对称加密:在 https 协议的前置知识已经介绍过,重点就是使用相同的密钥进行加解密,速度很快,很容易在任何现代 cpu 上执行,开销相当低(
it has pretty low overhead.
) - 非对称加密:它使用公钥对数据进行加密并使用配对的私钥进行解密,实现了安全的密钥交换,但速度很慢,开销也比较大。
- 互联网上实现数据加密的协议往往都是从非对称加密开始,使用它来安全地交换对称密钥并在之后的长时间通信过程中都使用速度更快的对称密钥对通信数据进行加解密。
这三点不仅对理解 HTTPS 协议设计和实现至关重要,对于理解 IPsec VPN 也同样重要。
Interesting Traffic 和 Security Association
在 VPN(Virtual Private Network,虚拟专用网络)中,"感兴趣的的流量"(Interesting Traffic)和"安全关联"(Security Association,简称 SA)是两个非常重要的概念,尤其是在基于策略的 VPN 和基于路由的 VPN 中。
感兴趣的的流量(Interesting Traffic)
"Interesting Traffic" 是指在配置 VPN 时,指定哪些流量需要通过 VPN 隧道进行加密和传输。它通常由一组 IP 地址、子网或特定的协议和端口号来定义。
在 VPN 配置中,"Interesting Traffic" 用于触发 VPN 隧道的建立。当设备检测到符合 "Interesting Traffic" 定义的流量时,它会启动 VPN 隧道,并将这些流量通过加密隧道传输到目的地。
基于策略的 VPN 中的感兴趣的的流量:在基于策略的 VPN 中,感兴趣的的流量是通过配置的策略(通常是访问控制列表 ACL)来定义的。这些策略明确指出哪些流量需要通过 VPN 隧道传输。例如:源 IP 地址和目标 IP 地址、源端口和目标端口、协议类型(如 TCP、UDP等)。
如果接触过以太坊公链开发,应该了解交易监听,其中会设置监听规则,比较交易发起方公链地址、交易接收方公链地址,只有满足监听规则的交易事件才会发送给监听方,其余不相关的事件都被过滤掉了。这里其实也是一样,只有满足配置策略的那些流量才会通过 VPN 隧道传输。
当设备检测到匹配这些策略的流量时,它会将这些流量通过 VPN 隧道传输。
基于路由的 VPN 中的有趣流量:在基于路由的 VPN 中,感兴趣的的流量通常是通过路由表来定义的。路由表决定了哪些流量需要通过 VPN 隧道传输。例如,如果某个目的地的路由指向 VPN 隧道的网络接口,那么所有发往目的地的流量都会被视为感兴趣的的流量并通过 VPN 隧道传输。
基于策略的 VPN 更难配置,但也更加灵活,可以针对不同类型的流量使用不同的安全设置。
安全关联 Security Association
Security Association (SA) 是指在 IPsec 协议中,用于定义两个网络实体之间的安全属性和加密参数的集合。SA 包含了加密算法、哈希算法、密钥和其他安全参数。
SA 用于管理和维护 IPsec 隧道的安全性。它包括两个部分:IKE SA 和 IPsec SA。IKE SA 用于保护密钥交换和协商过程,而 IPsec SA 用于保护实际的数据传输。
安全关联的主要属性有:
- SPI(Security Parameter Index,安全参数索引):唯一表示一个 SA 的索引。
- 加密算法:用于加密数据的算法(如 AES、3DES 等对称加密算法)。
- 认证算法:用于认证数据的算法(如 SHA256、SHA384 等摘要算法)。
- 密钥:用于加密和认证的密钥,一般指的都是对称密钥。
- 生存时间(Lifetime):SA 的有效时间,通常以秒或者字节数表示。
安全关联在基于策略的 VPN 中的作用:在基于策略的 VPN 中,每个匹配策略的流量方向都有一个对应的 SA。即对于每个策略都会有两个 SA,一个用于从 A 到 B 的流量,另一个用于从 B 到 A 的流量。这种方式允许不同类型的流量设置不同的安全策略。
安全关联在基于路由的 VPN 中的作用:在基于路由的 VPN 中,SA 通常与隧道网络接口相关联。所有通过该隧道网络接口的流量都会使用相同的 SA。这种方式简化了配置但不如基于策略的 VPN 那样灵活。
两者结合使用
在实际的 VPN 配置中,"Interesting Traffic" 和 "Security Association (SA)" 是紧密相关的:
- 定义感兴趣的流量:管理员定义哪些流量是 "Interesting Traffic"。
- 触发 SA 建立:当设备检测到 "Interesting Traffic",它会触发 IKE 协商过程,建立 IKE SA。
- 建立 IPsec SA:在 IKE SA 的基础上,进一步协商和建立 IPsec SA,用于保护和传输 "Interesting Traffic"。
假设你有一个总部和远程办公室,通过 VPN 连接。你希望所有从总部到远程办公室的流量都通过 VPN 隧道加密传输。你可以定义总部和远程办公室的子网作为 "Interesting Traffic":
- 总部子网:192.168.1.0/24
- 远程办公室子网:192.168.2.0/24
当设备检测到从 192.168.1.0/24 到 192.168.2.0/24 的流量时,它会触发 VPN 隧道的建立,并通过 IPsec SA 加密和传输这些流量。
更多示例
基于策略的 VPN 示例
假设我们有如下策略:
- 策略 1:所有从 192.168.1.0/24 到 10.0.0.0/24 的流量都需要通过 VPN 隧道 A。
- 策略 2:所有从 192.168.2.0、24 到 10.0.0.0/24 的流量都需要通过 VPN 隧道 B。
每个策略都会生成一对 SA:
- 策略 1 的 SA:
- SA1:从 192.168.1.0/24 到 10.0.0.0/24
- SA2:从 10.0.0.0/24 到 192.168.1.0/24
- 策略 2 的 SA:
- SA3:从 192.168.2.0/24 到 10.0.0.0/24
- SA4:从 10.0.0.0/24 到 192.168.2.0/24
基于路由的 VPN 示例
假设我们有一个 VPN 隧道接口 tun0,所有发往 10.0.0.0/24 的流量都需要通过该接口。路由表中会有一条对应的路由记录:
- 目的地:10.0.0.0/24
- 下一跳网络接口:tun0
因此所有发往 10.0.0.0/24 子网的流量都将通过 VPN 隧道接口 tun0 进行转发。
两个 VPN 中的重要概念小结
"Interesting Traffic" 和 "Security Association (SA)" 是 VPN 配置中的关键概念。前者定义了哪些流量需要通过 VPN 隧道加密传输,后者则管理和维护这些隧道的安全性。
Diffie-Hellman 密钥交换算法
Diffie-Hellman 密钥交换算法的安全性依赖于离散对数问题的困难性。具体来说,给定 g、p 和 mod p,计算 a 是非常困难的。这使得攻击者即使知道公共参数和交换的公钥,也无法轻易计算出共享密钥。
该算法的详细步骤如下:
- 首先双方需要协商出两个公共参数:一个大素数 p 和一个生成元 g(g 是一个整数且 ),这两个参数均公开。
- 然后双方(Alice 和 Bob)选择一个随机数作为自己的私钥,并通过以下的方式派生出对应的公钥。Alice 的私钥为 a,公钥为 ;Bob 的私钥为 b,公钥为 。私钥由双方各自保密,双方公开交换公钥。
- 双方完成公钥交换后,各自计算共享密钥,这个计算出的密钥是相同的。
Alice 计算的共享密钥:s =
Bob 计算的共享密钥:s =
VPN 连接建立的两个阶段
第一阶段(IKE Phase 1)
第一阶段的主要目标是建立一个安全的、加密的通信信道,称为 IKE SA(Internet Key Exchange Security Association)。这一阶段可以通过两种模式进行:主模式(Main Mode) 和 野蛮模式(Aggressive Mode) 。
主模式(Main Mode)
- 交换策略:双方交换并协商 IKE 策略,包括加密算法、哈希算法、Diffie-Hellman 组和认证方法。
- Diffie-Hellman 密钥交换:双方使用 Diffie-Hellman 算法生成共享的秘密密钥材料。
- 认证:使用预共享密钥(PSK)、数字证书或公钥基础设施(PKI)进行身份验证。
野蛮模式(Aggressive Mode)
野蛮模式与主模式类似,但它在三个消息交换中完成,而不是六个。它更快,但安全性较低,因为身份信息在未加密的状态下传输。
第二阶段(IKE Phase 2)
第二阶段的主要目标是基于第一阶段建立的 IKE SA,创建一个或多个 IPsec SA,用于实际的数据传输。第二阶段使用快速模式(Quick Mode)。
快速模式(Quick Mode)
- 协商 IPsec SA 参数:双方协商 IPsec SA 的参数,包括加密算法、哈希算法和生命周期。
- 生成会话密钥:基于第一阶段的共享密钥材料,生成用于加密和认证的会话密钥。
- 建立 IPsec SA:双方确认并建立 IPsec SA,准备进行数据传输。
IKE 的第二阶段相比于第一阶段更快也更敏捷,因为大部分繁重工作已经在第一阶段完成,从技术上讲,第一阶段密钥用作第二阶段的起点。即第二阶段是建立在第一阶段基础之上的,可以直接使用第一阶段已经建立的安全通信信道。
之所以要将这些不同的隧道拆分开来,是因为有可能先建立第一阶段隧道,然后创建第二阶段使用的隧道,当没有"感兴趣的的流量"出现时先将第二阶段隧道关闭,但是保留第一阶段花费大力气建立好的隧道。这意味着新的"感兴趣的的流量"到来时,再重新建立第二阶段隧道会更快、更省事。这是一个优雅而精心设计的架构。
将 IPsec 协商过程分为两个阶段有以下几个主要原因:
- 安全性:第一阶段建立了一个安全的通信信道,确保了后续密钥交换和参数协商的安全性。分阶段进行可以逐步建立信任,降低初始通信的风险。
- 灵活性:第一阶段和第二阶段的分离使得 IPsec 可以更灵活地适应不同的应用场景。例如,可以在第一阶段使用较强的加密算法,而在第二阶段使用适合数据传输的算法。
- 效率:第一阶段建立的 IKE SA 可以用于多个 IPsec SA,从而提高了密钥协商的效率。第二阶段的快速模式可以在已有的安全信道上快速协商新的 SA,减少了重复的计算和通信开销。
- 可管理性:分阶段进行使得管理和维护更加简单和清晰。管理员可以独立配置和调整每个阶段的参数和策略,以满足不同的安全需求。
第一阶段的隧道和花费大力气生成的 DH 密钥会一直保留,即使后续没有"有趣流量"关闭第二阶段隧道,第一阶段隧道和对称密钥也会保留。当再出现"有趣流量"时,可以直接根据现存的第一阶段隧道和 DH 密钥快速进行第二阶段的构建。
IPsec 的两个阶段通过 IKE 协议实现,第一阶段主要用于建立一个安全的通信信道,第二阶段则基于这个信道来协商和建立实际用于数据传输的 IPsec SA。分阶段进行不仅提高了安全性和效率,还增强了灵活性和可管理性。理解这两个阶段的工作原理,有助于更好地配置和使用 IPsec 来保护网络通信。
总结
HTTPS 和 IPsec 都是用于增强网络通信安全的协议,但它们的应用场景和实现方式有显著的不同。以下是它们的异同点:
HTTPS 协议
HTTPS(Hypertext Transfer Protocol Secure)是 HTTP 协议的安全版本,通过在 HTTP 和 TCP 之间添加 SSL/TLS 层来实现安全通信。
HTTPS 工作在应用层,通过 SSL/TLS 协议在传输层之上提供加密、认证和数据完整性保护。
主要用于保护 Web 应用程序的数据传输,如浏览器和服务器之间的通信。常见的应用场景包括在线银行、电子商务网站和任何需要保护用户隐私和数据完整性的 Web 应用。
安全特性
- 加密:使用 SSL/TLS 协议对数据进行加密,防止数据在传输过程中被窃听。
- 认证:通过数字证书验证服务器的身份,防止中间人攻击。
- 数据完整性:使用消息认证码 (MAC) 确保数据在传输过程中未被篡改。
IPsec 协议
IPsec(Internet Protocol Security)是一组协议,用于在 IP 层提供加密、认证和数据完整性保护。IPsec 工作在网络层,通过对 IP 数据包进行加密和认证来提供安全性。
IPsec 常用于建立虚拟专用网络 (VPN),保护站点到站点、站点到客户端的通信。它适用于需要在网络层保护数据传输的场景,如企业内部网络、远程办公和跨区域的数据中心连接。
安全特性
- 加密:对 IP 数据包进行加密,防止数据在传输过程中被窃听。
- 认证:通过认证头 (AH) 提供数据源认证,确保数据来自合法的发送者。
- 数据完整性:使用消息认证码 (MAC) 确保数据在传输过程中未被篡改。
- 隧道模式和传输模式:IPsec 支持两种模式,隧道模式用于加密整个 IP 数据包,传输模式仅加密 IP 数据包的有效载荷。
配置和管理
IPsec 配置相对复杂,需要在网络设备(如路由器、防火墙)上进行配置。配置 IPsec 需要深入了解网络层协议和安全策略。
两者的相同点
- 安全目标:HTTPS 和 IPsec 都旨在提供加密、认证和数据完整性保护,确保数据在传输过程中不被窃听或篡改。
- 加密技术:通过上述两个协议交互流程的介绍可知,两者都使用了现代密码学技术(如对称加密、非对称加密和消息认证码)来实现数据保护。
- 使用对称加密算法在通信阶段对通信数据进行快速加解密
- 使用非对称加密算法在通信阶段开始前安全地交换密钥
- 使用消息认证码或者哈希摘要算法校验数据完整性
- 使用签名算法验证通信方身份有效性
不同点
-
HTTPS 工作在应用层,通过 SSL/TLS 协议在传输层之上提供安全性。IPsec 工作在网络层,通过对 IP 数据包进行加密和认证来提供安全性。
-
HTTPS 主要用于保护 Web 应用程序的数据传输。IPsec 常用于建立 VPN,保护站点到站点、站点到客户端的通信。
-
HTTPS 需要在服务器上配置数字证书,通常由受信任的证书颁发机构 (CA) 签发。IPsec 配置相对复杂,需要在网络设备上进行配置,并且需要深入了解网络层协议和安全策略。
HTTPS 和 IPsec 都是用于保护网络通信安全的重要协议,但它们的工作层、应用场景和配置方式有所不同。HTTPS 主要用于保护 Web 应用程序的数据传输,而 IPsec 主要用于建立 VPN,保护网络层的数据传输。理解它们的异同点有助于在不同的应用场景中选择合适的安全协议。