写点什么

高性能数据访问中间件 OBProxy(七):安全、协议和监控

  • 2022-12-07
    浙江
  • 本文字数:5466 字

    阅读完需:约 18 分钟

高性能数据访问中间件 OBProxy(七):安全、协议和监控

经过本系列前六篇文章的分布式特性介绍,相信大家已经了解了 OBProxy 在 OceanBase 数据库整体架构下的作用。本篇文章我们将换一个视角,介绍一些偏“中间件”的功能:安全、协议和监控功能。



从 OBProxy 整体来看,安全、协议和监控属于产品层,因此更加贴近用户和开发者,大家了解起来比较容易,我们用一篇文章来统一介绍。 

1. 安全功能

 

OBProxy 的安全功能和 OBProxy 的使用场景相关。OBProxy 作为 OceanBase 数据库服务接入层和路由层,涉及到的安全包括:


  • 登录安全。通过密码认证、IP 白名单、连接数控制等保证登陆安全。

  • 传输安全。通过 SSL 加密保证数据传输安全。


下面,我们将对这两方面展开详细介绍。 

1.1 登录安全

 

1.1.1 密码认证

当用户登录发送用户名和密码给 OBProxy 后,OBProxy 不做认证,直接转发给 OBServer 认证。这样 OBProxy 实现简单,也不存在泄漏密码风险。流程如下:



让用户管理密码增加了用户负担和密码泄漏风险。随着云服务的普及,用户可以不管理密码,只需要提供可信的身份认证信息就可以了,OBProxy 在蚂蚁内部做了类似功能,举个例子:



App 和 OBProxy 部署在同一个 k8s 的 安全 POD 内,OBProxy 信任 App,App 访问数据库,只需要传输用户名,不传输密码,OBProxy 向 KMS(密钥管理服务)请求对应用户名的密码,和 OBServer 登录认证时传输用户名和从 KMS 获取到的密码。这样的好处有两点:


  • App 的代码或者配置文件不需要保存密码,减轻用户负担。

  • 数据库不需要改造,整个流程对数据库都是透明的。


此外,在使用 OBProxy 时,有两个账号大家需要特殊关注下:


  • proxyro@sys 账号:OBProxy 访问 OB 数据库元数据的账号,安全起见,用户无法通过该账号连接 OBProxy。

  • root@proxysys 账号:OBProxy 的管理员账号,可以查询 OBProxy 内部状态、修改配置等。


这两个密码大家在一些文档和部署配置中应该见过,经过这次讲解大家应该就熟悉了。 

1.1.2 IP 白名单

 

IP 白名单指允许访问 OceanBase 集群的 IP 列表,默认为空,表示都允许访问。OBProxy 的白名单有以下特点:


  • 支持指定 IP 和指定网络号两种方式设置 IP。如 192.168.2.2192.168.0.0/16

  • 支持设置租户级别、集群级别和全局级别白名单,优先级为租户级别 > 集群级别 > 全局级别。


为了安全起见建议大家定期维护白名单。使用 root@proxysys 账号登录 OBProxy ,白名单操作方式如下:


MySQL [(none)]> select * from white_list;Query OK, 0 rows affected (0.00 sec)
# 增加租户tenant1的白名单MySQL [(none)]> replace into white_list(cluster_name, tenant_name, name, value) values('cluster1', 'tenant1', 'ip_list', '182.168.1.1');Query OK, 0 rows affected (0.02 sec)
# 查询所有白名单内容MySQL [(none)]> select cluster_name, tenant_name, name, value from white_list;+--------------+-------------+---------+-------------+| cluster_name | tenant_name | name | value |+--------------+-------------+---------+-------------+| cluster1 | tenant1 | ip_list | 182.168.1.1 |+--------------+-------------+---------+-------------+
复制代码


如果只设置集群级别,replace 语句不加入 tenant_name 即可,全局级别类似,replace 语句不加入 cluster_nametenant_name 。这里大家需要注意使用网络号时要填写正确,如192.168.15.0/16就是错误的格式,第三位不应该为 15,应该为 0。 

1.1.3 最大连接数

 

OBProxy 通过配置项client_max_connections控制客户端最大连接数。因为分布式系统连接较多,我们举例说明下。



从整个链路看,存在 4 个连接:App 和 OBProxy 有一个,OBProxy 和 OBServer 有三个。但从 App 角度去看,只有一个连接。因此配置项就是对 App 和 OBProxy 之间的连接数做限制,OBProxy 和 OBServer 之间的连接不计算在内。<br />当 OBProxy 的客户端连接数超过限制后,客户端再次建连会登陆失败,OBProxy 会给客户端返回 ERROR 报文,报错信息为 Maximum number of sessions exceeded。 

1.2 传输加密

 

1.2.1 实现原理

OBProxy 通过 SSL 对数据传输进行加密。在实现上有两种方案:



方案一



方案二


大家可以看到,方案一 OBProxy 只做 SQL 转发,不感知报文内容,实现简单。方案二中,OBProxy 会重新加解密数据,并分析请求报文和响应报文的内容。方案二相比方案一更加复杂,但这样的优点是:


  • 相比方案一,方案二中 OBProxy 感知 SQL 请求和回包内容,才能够实现 OBProxy 的连接管理、SQL 路由、高可用等核心功能。

  • 方案二可以实现更灵活的加密控制,如 App <-> OBProxy 链路走 SSL 加密,OBProxy <-> OBServer 不走 SSL 加密。


除了优点,方案二也有一些缺点,OBProxy 需要加解密数据,对性能有一定损耗。那么影响有多大呢?基于 OBProxy 优秀的异步和多线程模型,即使全链路都开 SSL,性能影响也在 3% 以内,大家可以放心使用。 

1.2.2 使用案例

 

想要使用 SSL 功能还是比较复杂的一件事情。需要满足下面条件:


  • 具备密钥和证书分发体系:如云厂商的 KMS 服务;个人用户可以通过 openssl 命令生成证书和密钥。

  • 链路模块都支持 SSL:如 App、OBProxy 和 OBServer 都需要支持 SSL 能力。


我们以 OceanBase 某公有云客户使用 SSL 为例说明。



我们从控制流和数据流两个角度说下上面内容。


控制流:OBProxy 不直接对接密钥服务,对外提供 SQL 端口供设置证书和密钥。OCP 对接不同的 KMS 服务,并给 OBProxy 发送 SQL 设置密钥相关信息。<br />数据流:业务 App 发送的数据跨越 VPC,进行加密传输。OBProxy 和 OBServer 在同一个 VPC 内,首先得到了 VPC 保护,OBProxy 接收到数据后,可以给 OBServer 发送加密数据或者非加密数据,给 App 回包时,OBProxy 会对数据加密后再传输。 

1.2.3 SSL 配置

 

想要使用 SSL 能力,还需要对各个组件进行配置,本节介绍 OBProxy 如何配置 SSL。方法如下图所示。


# 配置密钥和证书replace into ssl_config (cluster_name, tenant_name, name, value) values('*', '*', 'key_info', '{"sourceType" : "FILE", "CA" : "certs/ca.pem", "publicKey" : "certs/server-cert.pem", "privateKey" : "certs/server-key.pem"}');
# 开启客户端和OBProxy之间的SSLreplace into proxy_config(name, value, config_level) values('enable_client_ssl', 1, 'LEVEL_GLOBAL');
# 开启OBProxy和OBServer之间的SSLreplace into proxy_config(name, value, config_level) values('enable_server_ssl', 1, 'LEVEL_GLOBAL');
复制代码


这里介绍一下上面配置的含义,对于 ssl_config 表,字段含义如下:


  • cluster_name 和 tenant_name:SSL 配置也支持租户和集群级别,'*' 表示无,上面含义就是无租户和集群名,就是全局级别

  • name:为 'key_info' 表示是 SSL 密钥配置

  • value:json 格式,包含密钥详细信息

  • sourceType:支持"FILE"和"KEY"两种信息。"FILE"表示用文件的方式设置,"KEY"表示用字符串的方式设置

  • CA:证书信息,文件名或者字符串,如果是文件名注意下权限信息

  • publicKey:公钥信息,也需要注意文件权限

  • privateKey:私钥信息,也需要注意文件权限


对于 proxy_config 表,字段含义如下:


  • cluster_name 和 tenant_name:上面例子未出现,本身也支持租户和集群级别。这里需要注意下,不设置就表示无,而 ssl_config 中'*'表示无

  • name:enable_client_ssl 表示客户端和 OBProxy 之间是否使用 SSL 能力;enable_server_ssl 表示 OBProxy 和 OBServer 之间是否使用 SSL 能力,两者相互独立

  • value:0 表示不使用 SSL 能力;1 表示使用 SSL 能力


这里需要注意一点:打开 SSL 配置并不代表一定使用 SSL,比如客户端不支持的话,OBProxy 开启 SSL 能力也没作用。<br />是否走了加密,客户端可以通过\s 命令确认(关注 SSL 一行,下图为 Cipher in use is ECDHE-RSA-AES256-GCM-SHA384)。


MySQL [test]> \s--------------mysql  Ver 15.1 Distrib 5.5.64-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 3221487953Current database: testCurrent user: root@127.0.0.1SSL: Cipher in use is ECDHE-RSA-AES256-GCM-SHA384Current pager: stdoutUsing outfile: ''Using delimiter: ;Server: MySQLServer version: 5.7.25 OceanBase 4.0.0.0 (r1-a06adb022eaa434bb5210294830a20003a5753a8) (Built Apr 7 2022 23:30:49)Protocol version: 10Connection: 127.1 via TCP/IPServer characterset: utf8mb4Db characterset: utf8mb4Client characterset: utf8mb4Conn. characterset: utf8mb4TCP port: 33041Active --------------
复制代码


这里需要注意,上面内容只能确定客户端和 OBProxy 是否开启了 SSL,OBProxy 和 OBServer 是否开启需要查询 OBServer 的内部表确定。 

2. 协议

 

大家都知道,使用开源 MySQL 驱动就可以连接 OBProxy 使用了,这是因为 OBProxy 支持了 MySQL 协议。其实,OBProxy 总共支持三种协议,见下图。<br />



使用 MySQL 协议,使用 MySQL 生态的客户端即可。使用 2.0 协议和 RPC 协议,需要使用专属客户端。对于 RPC 协议,在 OBKV 的产品形态下提供,本文不做详细介绍。MySQL 协议大家都很熟悉,所以重点介绍一下 2.0 协议。<br />2.0 协议是 OceanBase 团队自研的协议。设计时考虑了兼容性、安全性和扩展性几个方面,整体格式如下:


ceanBase 2.0 Protocol Format:
0 1 2 3 4 Byte +-----------------+----------------------+ | Magic Num | Version | +-----------------+----------------------+ | Connection Id | +-----------------------------+----------+ | Request Id | Seq | +-----------------------------+----------+ | PayLoad Length | +----------------------------------------+ | Flag | +-----------------+----------------------+ | Reserved |Header Checksum(CRC16)| +-----------------+----------------------+ | ... PayLoad Data ... |----------+ +----------------------------------------+ | | Tailer PayLoad Checksum (CRC32) | | +----------------------------------------+ | | | +--------------------------+ | | v +-------------------+-------------------+-------------------------------------+ | Extra Len(4Byte) | Extra Info(K/V) | Basic Info(Standard MySQL Packet) | +-------------------+-------------------+-------------------------------------+
复制代码


每个字段含义不在此作介绍,我们说明下设计考虑。


  • 兼容性:2.0 协议在 MySQL 协议上进行了扩展,可以方便的进行 2.0 协议和 MySQL 协议转换。

  • 安全性:尾部包含 CRC 32 信息,可以进行数据正确性校验。

  • 扩展性:通过 Extra Info 等字段可以传输更多功能信息,实现丰富功能;如全链路诊断信息、事务状态信息都可以放到这里面。


OB 4.0 版本已经发布,默认使用 2.0 协议,后续我们也会基于 2.0 协议开发更多功能,如全链路诊断、分布式事务路由等,大家也会慢慢发现 2.0 协议的好处。 

3. 监控

 

对于监控信息,OBProxy 的设计理念是和开源产品最对接,让大家使用门槛更低。目前 OBProxy 支持了 Prometheus 监控。Prometheus 监控系统的设计如下。<br />



OBProxy 要做的就是实现图中左下角 exporters 的功能,对 Prometheus server 提供监控数据。OBProxy 使用 2884 端口供 Prometheus server 访问。如下图通过 curl -L 127.0.0.1/2884/metrics 获得了监控数据:<br />



在 Prometheus 监控界面可以展现的更加清楚(下图是 RT 和 QPS 监控信息):<br />



总结

 

除了分布式特性,OBProxy 也结合流行的云原生技术、安全技术等,提供面向用户的功能。<br />本文从安全和监控角度,介绍了登录安全、IP 白名单、连接数、普罗米修斯监控等一些大家耳熟能详的功能。对于协议部分,大家可以看到 OBProxy 本身是一个协议转换器,支持了 MySQL 协议、2.0 协议和 RPC 协议,使 OBProxy 支持 OBKV、融入 MySQL 生态、扩展自身能力。<br />OBProxy 团队也在关注现有的云原生等技术,在蚂蚁公司内部做了云原生 Service Mesh 形态的功能并广泛使用,后续我们会更深入结合云产品和流行技术,为大家提供更好的服务。<a name="gekb0"></a>

课后互动

<a name="BxWEw"></a>

上期互动答案

问:当 OBProxy 和 某个 OBServer 节点发生网络故障后,但 OBServer 内部没有网络故障。此时如果要保证 RTO < 30s,那么 OBProxy 探测的周期、探测连续失败次数和探测超时时间该如何配置?<br />答:大家需要了解探测周期、探测超时时间和探测连续失败次数之间的关系,经验上看,连续失败次数不能为 1,不然一次网络抖动就会导致探测失败,周期要在秒级别,不能太频繁也不能太长。对于 RTO < 30 s,可以设置周期为 5s,连续失败次数为 4 次,超时时间为 5s,那么在 25s~30s 之间就可以发现故障。<a name="uI0nq"></a>

本期互动

问:客户端发给 OBproxy 加密数据,那么 OBProxy 发给 OBServer 的一定是加密数据吗?

发布于: 刚刚阅读数: 5
用户头像

企业级原生分布式数据库 2020-05-06 加入

github:https://github.com/oceanbase/oceanbase 欢迎大家

评论

发布
暂无评论
高性能数据访问中间件 OBProxy(七):安全、协议和监控_数据库_OceanBase 数据库_InfoQ写作社区