jjzjj

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

OceanBase数据库官方博客 2024-03-30 原文

经过本系列前六篇文章的分布式特性介绍,相信大家已经了解了 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 之间的连接不计算在内。
当 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 设置密钥相关信息。
数据流:业务 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之间的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表,字段含义如下:

  • 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能力也没作用。
是否走了加密,客户端可以通过\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:		root@127.0.0.1
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 的内部表确定。
 

2. 协议

 

大家都知道,使用开源 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)  |
   +-------------------+-------------------+-------------------------------------+

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

  • 兼容性:2.0协议在 MySQL 协议上进行了扩展,可以方便的进行 2.0协议和MySQL协议转换。
  • 安全性:尾部包含 CRC 32 信息,可以进行数据正确性校验。
  • 扩展性:通过Extra Info等字段可以传输更多功能信息,实现丰富功能;如全链路诊断信息、事务状态信息都可以放到这里面。

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

3. 监控

 

对于监控信息,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 的一定是加密数据吗?

有关高性能数据访问中间件 OBProxy(七):安全、协议和监控的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  5. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  6. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  7. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  8. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  9. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  10. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

随机推荐