跳转至

引言

20240618154020

如果想将数据从一台电脑发送到另一台电脑,可以使用 Socket 编程,由于 TCP 是基于字节流传输的协议,无法区分数据边界,会有粘包问题

UDP 是基于数据报的传输协议,无论应用层交给 UDP 多长的报文,UDP 都照样发送,交给 IP 层处理,而 IP 层只管运输不涉及是否粘包,所以 UDP 不会有粘包问题,但是不可靠。

所以需要加一些特殊标志以及消息长度等来区分边界,于是基于 TCP 就衍生出了 RPC 和 HTTP 等各种协议。

RPC 协议的具体实现有很多,至今没有一个统一标准。

起初在 C/S 架构中,客户端只需访问自家公司的服务端即可,所以使用各自的 RPC 协议就可以。

但随着 B/S 浏览器的兴起,需要访问不同公司的服务器,因此需要一个统一的标准协议,不然无法通信,于是诞生了 HTTP(HyperText Transfer Protocol 超文本传输协议)。

也就是说 RPC 通常用于 C/S 架构,HTTP 通常用于 B/S 架构,不过如今很多公司的服务端要同时支持移动端,PC 端以及 Web 端,所以对外提供服务通常使用标准的 HTTP 协议,而 RPC 开始退居幕后,主要用于公司内部集群中各个微服务之间的通信

服务发现

客户端若想与服务端建立连接,需要先知道服务端或资源的位置

在 HTTP 协议中,知道域名后,通过 DNS 服务解析即可获取到 IP,端口默认 80

RPC 协议中会有专门的中间服务保存服务名和 IP 信息等,要想访问某个服务就需要先到这些中间服务获取信息,通常称作服务发现,比如

  • Consul:提供服务注册、服务发现、健康检查等功能。
  • Eureka:Netflix 开源的服务发现和注册工具,广泛用于微服务架构。
  • Zookeeper:Apache 项目,提供分布式协调和服务发现功能。
  • Etcd:CoreOS 开发的分布式键值存储,用于服务发现和配置管理。
  • Redis

服务发现通常用于企业内部或云环境中,动态处理服务实例的注册和查找,适应快速变化的服务环境

长连接

HTTP 1.0 每次请求都需要 TCP 三次握手,请求完后则会断开,即短连接。而 HTTP 1.1 在建立底层 TCP 连接后,会一直保持连接,供之后的请求都复用,即长连接。

请求和返回都可以使用头字段 Connection: keep-alive 来表示长连接,如果服务端返回 Connection: close 则表示不支持长连接。

RPC 协议跟 HTTP 类似,也是建立 TCP 长连接进行数据交互,但不同的地方在于,RPC 协议一般还会再建个连接池,大大的提升了网络请求性能

很多编程语言的网络库也会给 HTTP 加连接池来提高性能,比如 Go

序列化

HTTP 协议通常使用 JSON 来序列化结构体数据

RPC 不需要考虑重定向等浏览器行为,可以使用体积更小的序列化协议,不同的 RPC 可以根据自身特点定制化,比如 gRPC 使用 protobuf

因此 RPC 传输内容性能更好,这就是微服务之间采用 RPC 协议的主要原因

不过 HTTP 2.0 改进提升了性能,比很多 RPC 协议还要好,以至于 gRPC 底层都使用了 HTTP 2.0

HTTPS

HyperText Transfer Protocol Secure

计算机科学领域里没有什么是引入中间层不能解决的,如果有,那就再加一层。

HTTPS 就是在 HTTP 和 TCP 之间增加了 SSL/TLS 协议,以此来提高数据传输的安全性。

SSL/TLS 最初叫做 SSL(Secure Sockets Layer),是由网景公司发明,经历了 v1~v3 版本的迭代,然后改名为 TLS(Transport Layer Security) 继续迭代。

TLS 收发数据的基本单位:记录(record)

TLS 主要由记录协议、警报协议、握手协议、以及密码变更协议四个子协议组成,然后还依赖一些开源的密码学底层库实现各种加密算法等

加密

开源密码学工具包 OpenSSL 是 SSL/TLS 的具体实现

将数据用公钥加密,发送给私钥所有者,数据无法被他人解密,但可能被他人篡改,因为每个人都可以用公钥加密数据,所以通常结合签名的方式一起使用防止篡改

对称加密传输效率高,非对称更安全,所以 HTTPS 中将对称与非对称结合在一起使用

加密

TLS 握手

在 TCP 连接建立之后,开始进行 TLS 握手,用于建立安全的通信通道,客户端会和服务端共同商议使用什么对称加密算法

https://www.thesslstore.com/blog/explaining-ssl-handshake/

  • TLS 1.2

20240619155421

20231028131504

以上流程只有客户端对服务端做了认证,而服务端没有对客户端的身份做认证,称之为单向认证。

通常单向认证通过后就已经建立了安全通信,用账号、密码等手段就能够确认用户的真实身份。

但为了防止账号、密码被盗,有时(比如网上银行)还会使用 U 盾给用户颁发客户端证书,实现“双向认证”,这样会更加安全。

  • TLS 1.3

20240619155433

RTT

RTT, Round-Trip Time,往返时延,是指一个数据包从发送到确认接收所需的时间,可以理解为两端之间往返一次数据所需的时间。

TCP 握手需要 1.5 RTT

TLS 四次握手需要 2 RTT

证书

为了证明公钥是可信的,引入了 PKI(Public Key Infrastructure 公开密钥基础设施),由硬件、软件、参与者、管理政策与流程组成的基础架构,其目的在于创造、管理、分配、使用、存储以及撤销数字证书。

即通过 CA(Certificate Authority 证书颁发机构)对公钥拥有者做专业认证,认证通过后颁发数字证书(digital certificate),将数字证书内置到操作系统,建立一个信任链,以此保证公钥的可信。

全球最大的七家 CA: Comodo、Symantec、Trend Micro、DigiCert、Entrust、GlobalSign、GoDaddy

他们一起组成了证书颁发机构理事会(CASC),有点类似联合国安全理事会的感觉。另外还有一个叫做 CA/Browser Forum(证书机构与浏览器论坛)的专业组织,主要使命是为浏览器和证书颁发机构提供互联网安全行业标准,通常也称为公钥基础设施,简称PKI。CASC 的成员必须遵守 CA/Browser Forum 制定的标准,目前最新标准为X.509 v3。

多说一句,审核并不一定是要提交给最大的那几个 CA,因为除了这些之外,还有一些大大小小的中介 CA,他们会组成一条条信任链,通过信任链的层层认证,最终也会被信任。不过机构越权威,安全等级也就越高,但同时也需要付出更多的费用,是的,申请数字证书是要花钱的(也有免费的),而且还不便宜,因为这背后需要很多安全和法律成本,并不是随便一个机构就能搞定的事情。

CA 按安全等级从低到高可分为:

  • DV:只验证申请域名的所有权
  • OV:需对申请者/组织的身份做验证
  • EV:需经过法律和审计的严格核查

CA 按保护域名的数量分为:

  • 单域名版:只保护一个域名
  • 多域名版:保护多个域名
  • 通配符版:保护主域名下同一级的所有子域名

作为服务端/申请者,如果想让自己的公钥被客户端所信任,需要将公钥以及一些必要信息等制作成一个CSR(Certificate Signing Request 证书签发请求)文件,通过可信网络提交给 CA 审核。

CSR在线生成工具

CA 审核通过后,会按照X.509标准的格式,将所有的必要信息通过哈希/散列函数压缩成一串固定长度的哈希值,称之为信息摘要。这是一个不可逆过程,如果信息被篡改,则哈希值会变,以此保障信息的完整性。

然后会通过 CA 私钥把这些信息和信息摘要一起进行加密,因为 CA 私钥由 CA 保管,所以没有私钥的人无法实现这一过程,所以称之为数字签名,至此就生成了一个可信赖的数字证书。

一个证书通常包含以下信息:

  • CA 信息
  • CA 的数字签名
  • CA 生成证书所用的摘要和非对称签名算法
  • 持有者公钥匙
  • 持有者唯一标识符,通常为域名
  • 序列号,CA 分配给证书的唯一标识符
  • 版本号,指出该证书使用了哪种版本的X.509标准
  • 有效期

20201026194030

最后,CA 将数字证书颁发给申请者,申请者会将其部署到服务器中,在收到客户端请求后将数字证书返回,客户端收到数字证书后,会对数字证书进行验证。

可以看到 github.com 的颁发者和有效日期,然后把菜单切到「证书路径」tab下,这就是我们前文提到的信任链,通过这个层级结构,就可以知道 github.com 的颁发者是由 DigiCert 这个 CA 认证的,也就是我们前文提到的全球最大 CA 之一,那么这些顶级的 CA 机构是由谁认证呢,答案是他们自己给自己认证,当然前提是因为这些顶级机构有足够的实力和信誉我们才选择相信他,就像各个国家的中央机构,你只能选择相信,不然整个社会体制就无法正常运转下去,言归正传,这些顶级 CA 会给自己签发一个数字证书,通常被称为根证书,这些根证书会被预置在我们的操作系统以及浏览器中,系统会定期检查他们是否已被吊销,尽可能保持最新可信状态。

证书分为系统证书(操作系统内置的,需要有Root权限才能进行添加或删除)和用户证书(用户自行安装的)

不要轻易安装盗版操作系统,因为如果从根儿上就已经不安全了,那么整个信任链也就没有安全可言。

证书