背景介绍
GrowingIO 作为一家大数据公司,外围资产尽管在大数据平台上,但关系型数据库仍扮演着不可或缺的角色。它负担着存储产品逻辑,配置信息等重要数据信息。
GrowingIO 目前的数据库实例较多,例如按环境辨别为开发环境,测试环境,生产环境等不同环境。按需要来说,又存在运维人员须要间接批改线上脏数据,开发人员本地拜访开发环境的实例进行联调等状况。
而随着公司员工一直倒退,人员的流动性会加剧,数据库权限管制会越来越简单。
这时一个易用的数据库管理工具会缩小相当大的工作量。
因为 GrowingIO 选用 PostgreSQL 作为关系型数据库,所以以下内容以 PostgreSQL 作为根底开展。
目前情况
之前 GrowingIO 是应用基于 SSH + Iptables + PostgreSQL 日志的组合架构来实现的 PostgreSQL 的治理。
这种架构只是满足了权限管制和审计的根本需要,然而理论应用中有些问题是很难解决,例如:
- 因为权限管制和日志审计属于独立的零碎,造成审计的溯源比拟麻烦。
- 权限管制比拟粗粒度,只能管制能不能拜访,无奈做更细粒度的权限划分。
- 无奈做到 SQL 级别的限度。
- 没有接到对立账号管理系统,账号治理繁琐。
因为以上种种原因,所以决定将该架构进行一次重构。
基于 PostgreSQL 审计和权限控制系统
后期筹备
性能需要
- 不对 PostgreSQL 数据库做变更或者侵入较小。
- 反对 RBAC 权限管制。
- 应用 LDAP 作为 RBAC 中的角色和用户认证零碎。
- 有审计性能。
- 有 SQL 过滤的性能。
-
易于应用和治理。
工具调研
因为目前市面上次要数据库应用 MySQL 居多,而 PostgreSQL 应用的较少,扩大工具方面的材料绝对较少。
目前找到的可行的计划是 PostgreSQL 自身的 LDAP 性能 + pgAudit 组合来达到权限和审计性能。
该计划可实现的性能包含:
- 基于 LDAP 的用户和角色认证。
- 基于 pgAudit 的日志审计性能。
该计划存在的问题: - 须要操作 PostgreSQL 自身,对 PostgreSQL 自身有肯定的侵入性。
- 各个 PostgreSQL 实例的治理还是割裂的状态。
- 前期性能扩展性不强。
因为该计划每个 PostgreSQL 实例的治理还是割裂的状态,当实例过多时仍会带来治理的简单,对于不反对公网的实例仍需在 PostgreSQL 实例前端搭建一个 Proxy 程序来做流量转发的工作。
基于以上艰难,决定本人开发一个 PostgreSQL 的审计和权限控制系统。
数据库审计零碎设计与实现
程序架构设计
整体架构较为简单,整个零碎的外围为 Server 端和 Proxy 端。
Server 端须要实现与 PostgreSQL 客户端通过某些认证形式建设连贯,并将用户发来的申请进行解决,并通过一些模块来扩大性能,例如:
登录和权限通过 Auth 模块来解决,Auth 前面接入 LDAP 模块来进行用户的登录和权限认证。
Audit 模块记录用户的申请信息,并将用户的行为格式化后输入到日志和其余零碎中作为审计记录。
Filter 模块监测用户的申请,例如能够对 drop database 等语句禁止执行,后端能够对接其余零碎进行动态控制。
Proxy 端则次要通过 PostgreSQL 的零碎用户与 PostgreSQL 数据库建设连贯,作为 Server 端和 PostgreSQL 数据库之间沟通的桥梁。
所以零碎的外围为 Server 端和 Proxy 端的实现,当这两块实现后咱们就能够在此上做扩大,减少不同的性能。
Server 和 Proxy 实现
这里仿佛只有找到 PostgreSQL Server 和 Client 的包而后做一次封装后就差不多能够实现 Server 和 Proxy 了。
然而真正问题的是网上找了一圈没发现有实现 PostgreSQL 服务端的示例,也没找到官网的包。只在 PostgreSQL 官网文档中找到了前后端的通信协议。
最初只能本人实现 PostgreSQL 的前后端。
PostgreSQL 前后端交互的外围为通信协议和会话过程这两局部,上面次要进行这两块的解说。
PostgreSQL 前后端通信协议
这里介绍一下我集体去理解 PostgreSQL 通信协议的办法。
首先是官网文档中对于 PostgreSQL 前后端协定。
查看 PostgreSQL 的客户端源码进行剖析和 Debug,并通过 Wireshark 进行抓包。这里次要查看的客户端为 psycopg2,node-postgres,go-pg,这里发现 psycopg2 其实是封装了 libpq 这个官网库,没有更多的对于协定的细节,帮忙不大。然而发现 go-pg 和 node-postgres 是本人做了客户端协定,通过源码能够明确数据包内容的提取办法和协定格局。
PostgreSQL 前后端协定格局中,咱们次要介绍如下两种,这两种弄懂后,其余格局其实大同小异。
第一种比拟非凡的 StartupMessage 音讯格局为客户端发送的第一条正式音讯。
第二种为一般音讯类型也是 PostgreSQL 前后端交互的次要音讯格局。
协定字段阐明:
内容的长度 标记了这个数据包中音讯的长度(包含本身),大部分协定格局中都有这个字段,绝大部分长度为 4 Byte,类型为 Int32。这里须要留神的是局部协定格局中的长度不是 4 Byte。
StartupMessage 协定的版本信息 标记客户端申请应用的协定版本,其中前 16bits 为 Major Version,后 16bits 为 Minor Version。
音讯类型 标记本条音讯的类型,在大部分音讯中为第一个字节,Char 类型,例如
‘R’ 为服务端的认证音讯类型。
‘p’ 为客户端的认证信息。
‘Q’ 为客户端的简略查问音讯类型。
音讯主体内容 音讯类型中的主体内容。依据不同的音讯类型,须要不同的解析形式,上面会次要介绍 StartupMessage 和 音讯类型(‘R’) 中的主体内容格局,其余音讯类型请查看官网文档。
StartupMessage 音讯
为客户端发送的第一次的音讯格局,用于标记客户端的一些信息。
数据类型为 String,应用 key/value 格局,应用 0 做宰割符,次要字段有 user database,如下:
user\x00xiaoming\x00database\x00hello\x00application_name\x00navicat…
音讯类型 (’R‘)
是服务端发送到客户端的一种音讯格局,用于告诉客户端的认证形式。
主体音讯 中前四位应用 Int32,标记认证格局,局部含意如下。
- 0 示意认证胜利。
- 2 指定应用 Kerberos V5 认证形式。
- 3 指定明文明码认证形式。
- 5 指定须要 MD5 加密的明码认证形式,其中主体音讯的 4-7 位为加密的 SALT 值,加密过程如下。
password = 'md5' + string(md5(md5(USERNAME+PASSWORD) + string(SALT)))
PostgreSQL 前后端会话过程
通过下面的介绍,咱们大抵对协定格局有了一些理解,上面内容介绍一下 PostgreSQL 的会话过程,同样先放一张图,而后咱们再来进行阐明。
如图,咱们能够将一个前后端会话过程概括为如下四个阶段:
- 建设连贯
次要为建设 TCP 网络连接申请过程,如果启用 SSL,则客户端须要发送一条蕴含 SSL Requests 信息的 TCP 申请。
SSL Requests 内容为
[]byte{0, 0, 0, 8, 4, 210, 22, 47} - 认证阶段
该阶段次要为用户登录的认证阶段,次要过程如下。
客户端发送一条蕴含用户名,数据库等信息 StartupMessage 的音讯。
服务端发送一条蕴含认证形式的 ‘R’ 格局音讯。
客户端依据认证形式发送一条蕴含认证信息的 ‘p’ 音讯进行验证。
服务端依据认证信息进行认证,依据认证后果进行回复,如 ‘R’ 的认证胜利格局音讯。 - 会话阶段
认证通过后前后端开始进入会话进行 SQL 的申请操作。
这时客户端会发送例如 ‘Q’ 和 ‘P’ 等格局音讯的 SQL 申请,服务端进行应答。 - 完结会话
客户端发送一条 ‘X’ 的 Close 申请后,进入 SSL/TCP 挥手阶段。
[]byte{'X', '\x00', '\x00', '\x00', '\x04'}
数据库审计零碎的会话流程
通过上一节介绍的 PostgreSQL 前后端通信协议格局 和 前后端的会话过程 咱们对 Server 和 Proxy 端的开发曾经不存在阻碍了,上面我会简略的介绍一下数据库审计零碎的会话流程,同样还是先放一张图。
整个数据库审计零碎的解决流程大体如下:
- PostgreSQL 客户端建设与零碎的 TCP 连贯。
- 零碎告诉 PostgreSQL 客户端应用 SSL 连贯。
- PostgreSQL 客户端开始与零碎建设 SSL 连贯。
- 连贯建设后,所有的客户端数据都会先通过 Parser 模块进行音讯解析。
- 如果发现客户端没有登录,那么零碎会走到认证过程进行登录认证。
- 认证通过后零碎中的 Proxy 模块会与 PostgreSQL 服务端进行连贯建设,并实现认证过程。
- 后续客户端的申请通过 Parser 解析后会进行认证信息校验。
- 认证信息校验通过后,申请会进入到 Filter 模块进行 SQL 的过滤。
- Filter 过滤后,将申请通过 Proxy 模块转发到 PostgreSQL 服务端上。
- 服务端返回的信息达到 Proxy 后,数据在转回 Server 模块将音讯发回 PostgreSQL 客户端。
- 当会话达到超时或者 PostgreSQL 客户端发动敞开申请等状态,则进入到敞开会话阶段。
- 最初敞开会话,敞开 TCP/SSL 会话。
通过下面的介绍,咱们能够晓得数据库审计零碎的外围还是在于 PostgreSQL 的前后端协定和会话过程,其余性能绝对比较简单,所以对于零碎更多的细节介绍这里不在开展。
总结
目前该零碎曾经稳固运行了一年多的工夫,通过这段时间的应用能够确认该零碎达到了当初的设计指标,齐全满足了目前的应用场景,并且大大加重了日常中对于数据库治理的相干工作,并且因为没有对 PostgreSQL 数据库做任何方面的改变,从而没有对线上的业务产生任何影响。
参考
https://www.postgresql.org/do…
https://github.com/go-pg/pg
https://github.com/psycopg/ps…
https://github.com/brianc/nod…
作者:邢建辉
GrowingIO 运维开发工程师,次要负责平台化,自动化方向的设计与开发。
招聘信息
GrowingIO 技术团队是一个生机四射、对技术充斥激情的团队,多个岗位继续招聘中!诚招前端工程师 / 大数据工程师 /Java 工程师等,欢送有趣味的同学投递简历至:jianli@growingio.com(邮件题目请注明具体岗位名称),更多职位及信息可进入招聘官网查看
对于 GrowingIO
GrowingIO 是国内当先的一站式数据增长引擎整体计划服务商,创建于 2015 年,以数据智能剖析能力为外围,通过构建客户数据平台,打造增长营销闭环,帮忙企业晋升数据驱动能力,赋能商业决策、实现业务增长。