经过本系列前六篇文章的分布式特性介绍,相信大家已经了解了 OBProxy 在 OceanBase 数据库整体架构下的作用。本篇文章我们将换一个视角,介绍一些偏“中间件”的功能:安全、协议和监控功能。
从 OBProxy 整体来看,安全、协议和监控属于产品层,因此更加贴近用户和开发者,大家了解起来比较容易,我们用一篇文章来统一介绍。
OBProxy 的安全功能和 OBProxy 的使用场景相关。OBProxy 作为 OceanBase 数据库服务接入层和路由层,涉及到的安全包括:
下面,我们将对这两方面展开详细介绍。
当用户登录发送用户名和密码给 OBProxy 后,OBProxy不做认证,直接转发给 OBServer 认证。这样 OBProxy 实现简单,也不存在泄漏密码风险。流程如下:
让用户管理密码增加了用户负担和密码泄漏风险。随着云服务的普及,用户可以不管理密码,只需要提供可信的身份认证信息就可以了,OBProxy 在蚂蚁内部做了类似功能,举个例子:
App 和 OBProxy 部署在同一个 k8s 的 安全 POD 内,OBProxy 信任App,App访问数据库,只需要传输用户名,不传输密码,OBProxy 向KMS(密钥管理服务)请求对应用户名的密码,和 OBServer 登录认证时传输用户名和从 KMS 获取到的密码。这样的好处有两点:
此外,在使用 OBProxy 时,有两个账号大家需要特殊关注下:
这两个密码大家在一些文档和部署配置中应该见过,经过这次讲解大家应该就熟悉了。
IP白名单指允许访问 OceanBase 集群的IP列表,默认为空,表示都允许访问。OBProxy 的白名单有以下特点:
192.168.2.2
和192.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_name
和 tenant_name
。这里大家需要注意使用网络号时要填写正确,如192.168.15.0/16
就是错误的格式,第三位不应该为15,应该为0。
OBProxy 通过配置项client_max_connections
控制客户端最大连接数。因为分布式系统连接较多,我们举例说明下。
从整个链路看,存在4个连接:App 和 OBProxy 有一个,OBProxy 和 OBServer 有三个。但从 App 角度去看,只有一个连接。因此配置项就是对 App 和 OBProxy 之间的连接数做限制,OBProxy 和 OBServer 之间的连接不计算在内。
当 OBProxy 的客户端连接数超过限制后,客户端再次建连会登陆失败,OBProxy 会给客户端返回 ERROR 报文,报错信息为 Maximum number of sessions exceeded
。
OBProxy 通过 SSL 对数据传输进行加密。在实现上有两种方案:
方案一
方案二
大家可以看到,方案一 OBProxy 只做 SQL 转发,不感知报文内容,实现简单。方案二中,OBProxy 会重新加解密数据,并分析请求报文和响应报文的内容。方案二相比方案一更加复杂,但这样的优点是:
除了优点,方案二也有一些缺点,OBProxy 需要加解密数据,对性能有一定损耗。那么影响有多大呢?基于 OBProxy 优秀的异步和多线程模型,即使全链路都开 SSL,性能影响也在 3% 以内,大家可以放心使用。
想要使用SSL功能还是比较复杂的一件事情。需要满足下面条件:
我们以 OceanBase 某公有云客户使用 SSL 为例说明。
我们从控制流和数据流两个角度说下上面内容。
控制流:OBProxy 不直接对接密钥服务,对外提供 SQL 端口供设置证书和密钥。OCP对接不同的KMS服务,并给 OBProxy 发送 SQL 设置密钥相关信息。
数据流:业务 App 发送的数据跨越 VPC,进行加密传输。OBProxy 和 OBServer 在同一个 VPC 内,首先得到了 VPC 保护,OBProxy 接收到数据后,可以给 OBServer 发送加密数据或者非加密数据,给 App 回包时,OBProxy会对数据加密后再传输。
想要使用 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之间的SSL
replace into proxy_config(name, value, config_level) values('enable_client_ssl', 1, 'LEVEL_GLOBAL');
# 开启OBProxy和OBServer之间的SSL
replace into proxy_config(name, value, config_level) values('enable_server_ssl', 1, 'LEVEL_GLOBAL');
这里介绍一下上面配置的含义,对于ssl_config表,字段含义如下:
对于proxy_config表,字段含义如下:
这里需要注意一点:打开SSL配置并不代表一定使用SSL,比如客户端不支持的话,OBProxy 开启SSL能力也没作用。
是否走了加密,客户端可以通过\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: 3221487953
Current database: test
Current user: [email protected]
SSL: Cipher in use is ECDHE-RSA-AES256-GCM-SHA384
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MySQL
Server version: 5.7.25 OceanBase 4.0.0.0 (r1-a06adb022eaa434bb5210294830a20003a5753a8) (Built Apr 7 2022 23:30:49)
Protocol version: 10
Connection: 127.1 via TCP/IP
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4
TCP port: 33041
Active --------------
这里需要注意,上面内容只能确定客户端和 OBProxy 是否开启了 SSL,OBProxy 和 OBServer 是否开启需要查询 OBServer 的内部表确定。
大家都知道,使用开源 MySQL 驱动就可以连接 OBProxy 使用了,这是因为 OBProxy 支持了 MySQL 协议。其实,OBProxy 总共支持三种协议,见下图。
使用 MySQL 协议,使用 MySQL 生态的客户端即可。使用 2.0协议和 RPC 协议,需要使用专属客户端。对于 RPC 协议,在 OBKV 的产品形态下提供,本文不做详细介绍。MySQL 协议大家都很熟悉,所以重点介绍一下2.0协议。
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) |
+-------------------+-------------------+-------------------------------------+
每个字段含义不在此作介绍,我们说明下设计考虑。
OB 4.0版本已经发布,默认使用2.0协议,后续我们也会基于2.0协议开发更多功能,如全链路诊断、分布式事务路由等,大家也会慢慢发现2.0协议的好处。
对于监控信息,OBProxy 的设计理念是和开源产品最对接,让大家使用门槛更低。目前 OBProxy 支持了Prometheus监控。Prometheus监控系统的设计如下。
OBProxy 要做的就是实现图中左下角 exporters 的功能,对 Prometheus server 提供监控数据。OBProxy 使用2884端口供Prometheus server访问。如下图通过 curl -L 127.0.0.1/2884/metrics
获得了监控数据:
在 Prometheus 监控界面可以展现的更加清楚(下图是RT和QPS监控信息):
除了分布式特性,OBProxy 也结合流行的云原生技术、安全技术等,提供面向用户的功能。
本文从安全和监控角度,介绍了登录安全、IP白名单、连接数、普罗米修斯监控等一些大家耳熟能详的功能。对于协议部分,大家可以看到 OBProxy 本身是一个协议转换器,支持了 MySQL协议、2.0协议和RPC协议,使 OBProxy 支持OBKV、融入MySQL 生态、扩展自身能力。
OBProxy 团队也在关注现有的云原生等技术,在蚂蚁公司内部做了云原生 Service Mesh 形态的功能并广泛使用,后续我们会更深入结合云产品和流行技术,为大家提供更好的服务。
问:当 OBProxy 和 某个 OBServer 节点发生网络故障后,但 OBServer 内部没有网络故障。此时如果要保证 RTO < 30s,那么 OBProxy 探测的周期、探测连续失败次数和探测超时时间该如何配置?
答:大家需要了解探测周期、探测超时时间和探测连续失败次数之间的关系,经验上看,连续失败次数不能为1,不然一次网络抖动就会导致探测失败,周期要在秒级别,不能太频繁也不能太长。对于RTO < 30 s,可以设置周期为5s,连续失败次数为4次,超时时间为5s,那么在25s~30s之间就可以发现故障。
问:客户端发给 OBproxy 加密数据,那么 OBProxy 发给 OBServer 的一定是加密数据吗?