去哪儿数据库自动化平台实践——通讯协议

3,155 阅读7分钟

作者介绍:

钱芳园,专注数据库和数据库自动化领域的工程师,擅长 MySQL、Redis 运维以及基于 go 语言的数据库自动化开发。

一、背景

新一代去哪儿数据库自动化平台设计整体架构如下:

图片

架构说明:

【1】平台是分层构建,不同层级的模块功能专注不同的功能,上图只是列出部分模块。

【2】Server 是整个架构的初始化模块,也是整个平台的管控节点。

【3】Meta 是整个架构的元数据中心。

【4】每个模块都是独立的存在,同一层级的模块之间可以相互调用,低层级的模块不能主动调用高层级的模块。根据自动化平台的规划,平台需要部署一套 Agent 和各种 Plugin 在目标服务器上,Agent 和 Plugin 具备执行各种命令、任务。但是 Agent/Plugin 需要与 Server 之间传输一些敏感信息(密码、秘钥等),需要设计一套交互协议,防止敏感信息泄露,确保数据传输的安全性。

二、目标

设计一套Agent/Plugin和Server之间的通信协议,需要实现以下目标:

  • 满足功能上的需求,可以接受请求,执行命令和任务。
  • 确保敏感信息传输的安全性。
  • 对部分影响较大的请求进行认证。
  • 尽可能不依赖外部服务。

三、分析

通讯方式

目前主流两个服务之间的通讯方式有:http/https、tcp、udp、rcp。

通讯方式协议层优点缺点
tcp/udp传输层完全可定制化的通讯协议,可以具备较高的安全性。需要从底层实现一套复杂的通讯协议,开发成本非常高。
rpc应用层成熟的通讯协议,现有框架可以完整支持,可以在此基础上完成二次开发,并且性能较高。需要指定的客户端才能通讯,调试不太方便,开发成本稍高。
http/https应用层成熟的通讯协议,现有框架可以完整支持,可以在此基础上完成二次开发,并且客户端较多,调试非常方便。相比rcp,性能较低,开发成本较低。

目前 Agent / Plugin 和 Server 之间的通讯的性能要求不高,最主要的是满足功能上的需求和防止敏感信息泄露,方便开发、调试。故我们采用开发成本稍低的 http 协议。

需要加密的接口

Agent/Plugin和Server 之间通讯时,90% 的场景是获取一些非敏感性信息,例如:服务器信息、硬件信息等。如果这些非敏感的信息进行加密会大大浪费资源,增加双方的负担。故我们对含有非敏感信息的接口不采用加密的通讯方式,仅对含有敏感信息的接口进行加密传输。

加密协议

加密方式大致分为对称加密和非对称加密。两者主要的区别在于加密和解密的秘钥是否是同一个。

- 对称加密

对称加密用的秘钥既可以用来加密明文数据,也可以用来解密密文数据,故被称之为对称加密。一般情况下对称加密的加密算法是公开的,一旦秘钥泄露则密文就会很容破解,所以对称加密的关键在于秘钥的安全管理。

图片

加密过程如下:

密文=Func(明文,秘钥)

其中Func为加密算法。解密过程如下:

明文=Func(密文,秘钥)

其中 Func 为加密算法。

对称加密算法主要有 AES、DES、3DES 等,由于 DES 和 3DES 在安全性方面不如 AES,故现在不再推荐使用 DES 和 3DES 。

名称密钥长度运算速度安全性资源消耗是否推荐
DES56位较快不推荐
3DES112位或168位不推荐
AES128、192、256位推荐

- 非对称加密

非对称加密有一对秘钥,可以用其中任何一个秘钥来加密,用另一个秘钥来解密。一般情况下会把其中的一把秘钥公开,可以使用这个秘钥对任何数据进行加密,只要另一把秘钥不泄露就可以确保数据安全。为了区分这两个秘钥,可以公开的秘钥称为公钥,不能公开的秘钥称为私钥。

图片

加密过程如下:

密文=Func(明文,公钥)

其中Func为加密算法。解密过程如下:

明文=Func(密文,私钥)

其中Func为加密算法。

常见的非对称加密算法有RSA、DSA等。

名称成熟度安全性(取决于密钥长度)运算速度资源消耗
RSA
DSA只能用于数字签名
ECC低(计算量小,存储空间占用小,带宽要求低)

RSA 加密算法是目前最有影响力的公钥加密算法,并且被普遍认为是目前最优秀的公钥方案 之一。RSA 是第一个能同时用于加密和数字签名的算法,它能够抵抗到目前为止已知的所有密码攻击,已被 ISO 推荐为公钥数据加密标准。对称加密和非对称加密算法比较:

加密方式优势劣势
对称加密速度快,资源消耗低安全性不如非对称加密
非对称加密安全性高加解密速度低,资源消耗高

基于加密和解密速度上的考虑,目前Agent/Plugin和Server之间采用对称加密算法。

流程设计

- 流程图

图片

图示以Agent和 Server 认证过程为例。Agent 和 Server 之间都含有一个固定的 key,这个 key 是编码在二进制代码中,无法访问。

- 认证过程

  1. agent 启动时会收集自身和环境信息,并向 server 注册。
  2. server 收到注册请求之后,会针对本次请求的 agent 生成配置信息。
  • 随机生成一个securityKey(每个agent每次注册都会生成新的securityKey)。
  • 使用 securityKey 加密 agent 的原始配置信息。
  • 使用 key 加密 securityKey 。
  1. server 将配置信息(包含加密之后的 securityKey)发送给 agent。
  2. agent 收到配置信息后,使用对应的 key 解析 securityKey,然后使用 securityKey 解密出原始的配置信息。

- 请求过程

  1. server 生成 token。
  • 生成包含 server 身份信息在内的服务信息。
  • 使用 agent 对应的 securityKey 加密服务信息。
  • 使用加密之后的服务信息生成 token 。
  1. server 向 agent 下发指令请求,并附加 token。

  2. agent 收到请求之后,进行检查。

  • 解析 token 并获取服务信息。
  • 使用 securityKey 解密服务信息,并获取请求的身份信息。
  • 检查身份信息是否正确,如果检查错误则直接拒绝请求。
  1. agent 执行指令并返回结果。

- 说明

  1. agent 和 server 共有的 key
  • key 只用于加密和解密 sercurityKey,不用于其他用途,即使泄露也不会影响认证。
  • agent 和 server 是二进制编译部署,key 不存在与配置文件中,key 不会在网络中以任何形式传输。
  • key不参与数据加密过程,即使 server 向 agent 请求时,key 不相同认证也会通过。
  • 后面如果需要考虑替换掉 key,只需要保证 agent 注册的时候 server 与 agent 的 key 相同就可以注册成功。
  1. securityKey
  • 每个 agent 专属一个 securityKey 。
  • 每个 agent 启动注册均会随机生成一个 securityKey ,如果存在旧的 securityKey 则会被覆盖。
  • securityKey 是用来加密敏感信息,防止敏感信息。
  • securityKey 仅在注册过程中传输一次,并且只存在于 agent 的内存中,不会以任何形式存在于文件中。
  1. token

token 中包含加密之后的server身份信息,agent 认证时会做如下检查:

  • agent 检查 token 身份信息是否符合要求,如果身份信息不符合要求则认证不予通过。
  • agent 会将身份信息与请求来源进行比较,如果不同则被认为 token 为非法。