2021-04-27

随着数字化技术的飞速发展,数字、连接、信号、人工智能充斥着人们工作、生活的各个领域。这些数字化信息被快速转换成数据并存放在各式各样的数据库系统中,而且通过进一步的数据管理与分析产生商业价值。这些有价值的数据或被存放在企业相对封闭的私有网络内,或被存放在相对开放的公有云环境下,又或是集成在智能系统中。人们在享受由数字化发展所带来的便捷生活的同时,也可能面临着无处不在的隐私泄露、信息篡改、数据丢失等安全风险。

数据库安全作为数据库系统的护城河,通过访问登录认证、用户权限管理、审计与监视、数据隐私保护以及安全信道等技术手段防止恶意攻击者访问、窃取、篡改和破坏数据库中的数据,阻止未经授权用户通过系统漏洞进行仿冒、提权等路径恶意使用数据库。

openGauss作为新一代自治安全数据库,为有效保障用户隐私数据、防止信息泄露,构建了由内而外的数据库安全保护措施。本篇将介绍和分析openGauss所采用的安全技术以及在不同应用场景下所采取的不同的安全实施策略。

一 、openGauss安全机制概览

作为独立的组件,传统数据库系统构建于特定的操作系统平台上,以对外提供数据服务或通过对接可视化管理界面对外提供数据管理服务,整个系统部署在一个封闭的网络环境中。系统中的数据存放于物理存储介质上,存储介质可以为机械磁盘,也可以为SSD(固态硬盘)。硬件的稳定性和可靠性作为重要的一个环节,保障了数据整体的存储安全。

随着云化技术的快速发展,数据逐步上传到云,系统所处的环境越来越复杂,相对应的系统风险也逐步增加。openGauss作为分布式系统,需要横跨不同的网络区域进行部署。除了需要像传统数据库那样从系统访问、数据导入导出、数据存储等维度来考虑系统安全体系外,还需要考虑网络安全、虚拟隔离等与实际业务场景紧密相关的安全措施。一个完整的openGauss安全机制体系如图1所示。
在这里插入图片描述

图1 openGauss安全机制体系

openGauss安全机制充分考虑了数据库可能的接入方,包括 DBA、用户、应用程序以及通过攻击途径连接数据库的攻击者等。

openGauss提供了用户访问所需的客户端工具 GaussSQL(缩写为 gsql),同时支持JDBC/ODBC等通用客户端工具。整个openGauss系统通过认证模块来限制用户对数据库的访问,通过口令认证、证书认证等机制来保障认证过程中的安全,同时可以通过黑白名单限制访问IP。

用户以某种角色登录系统后,通过基于角色的访问控制(Role Based Access Control, RBAC)机制,可获得相应的数据库资源以及对应的对象访问权限。

用户每次在访问数据库对象时,均需要使用存取控制机制———访问控制列表(AccessControlList,ACL) 进行权限校验。常见的用户包括超级用户、管理员用户和普通用户,这些用户依据自身角色的不同,获取相应的权限,并依据 ACL来实现对对象的访问控制。所有访问登录、角色管理、数据库运维操作等过程均通过独立的审计进程进行日志记录,以用于后期行为追溯。

openGauss在校验用户身份和口令之前,需要验证最外层访问源的安全性,包括端口限制和IP地址限制。访问信息源验证通过后,服务端身份认证模块对本次访问的身份和口令进行有效性校验,从而建立客户端和服务端之间的安全信道。整个登录过程通过一套完整的认证机制来保障,满足 RFC5802通信标准。登录系统后用户依据不同的角色权限进行资源管理。角色是目前主流的权限管理概念,角色实际是权限的集合,用户则归属于某个角色组。管理员通过增加和删除角色的权限,可简化对用户成员权限的管理。

用户登录后可访问的数据库对象包括表(Table)、视图(View)、索引(Index)、序列(Sequence)、数据库(Database)、模式(Schema)、函数(Function)及语言(Language)等。在下文将介绍其他的一些对象。实际应用场景中,不同的用户所获得的权限均不相同,因此每一次对象访问操作,都需要进行权限检查。当用户权限发生变更时,需要更新对应的对象访问权限,且权限变更即时生效。

用户对对象的访问操作本质上是对数据的管理,包括增加、删除、修改、查询等各类操作。数据在存储、传输、处理、显示等阶段都会面临信息泄露的风险。openGauss提供了数据加密、数据脱敏以及加密数据导入导出等机制保障数据的隐私安全。

二、 openGauss安全认证

openGauss是一款标准的基于客户端/服务端(C/S)模式工作的数据库系统,每一个完整的会话连接都由后台服务进程和客户端进程组成。一个完整的openGauss认证过程如图2所示。

在这里插入图片描述

图2 openGauss认证详细流程

  • 客户端依据用户需求配置相关认证信息,这里主要指 SSL(Secure Sockets Layer,安全套接层)认证相关信息,建立与服务端之间的连接。
  • 连接建立完成后,客户端发送访问所需要的连接请求信息给服务端,对请求信息的验证工作都在服务端完成。
  • 服务端首先需要进行访问源的校验,即依据配置文件对访问的端口号、访问IP地址、允许用户访问范围以及访问数据对象进行校验。
  • 在完成校验后连同认证方式和必要的信息返回给客户端。
  • 户端依据认证方式加密口令并发送认证所需的信息给服务端。
  • 服务端对收到的认证信息进行认证。认证通过,则启动会话任务与客户端进行通信提供数据库服务;否则,拒绝当前连接,并退出会话。客户端安全认证机制是openGauss的第一层安全保护机制,解决了访问源与数据库服务端间的信任问题。通过这层机制可有效拦截非法用户对数据库进行恶意访问, 避免后续的非法操作。

(一)客户端配置信息

如上面所描述的,安全认证机制首先要解决访问源可信的问题。openGauss通过系统配置将访问方式、访问源IP地址(客户端地址)以及认证方法存放在服务端的配置文件中。与这些信息同时存放的还包括数据库名、用户名。这些信息会组成一条认证记录,存放在配置文件(Host-BasedAut henticationFile,HBA 文件)中。HBA 文件记录的格式可为如下四种格式中的一种:

local     DATABASE USER METHOD [OPTIONS]

host      DATABASE USER ADDRESS METHOD [OPTIONS]

hostssl   DATABASE USER ADDRESS METHOD [OPTIONS]

hostnossl DATABASE USER ADDRESS METHOD [OPTIONS

一个 HBA 文件中可以包含多条记录,一条记录不能跨行存在,每条记录内部是由若干空格、/和制表符分隔的字段组成。在实际认证过程中,身份认证模块需要依据HBA 文件中记录的内容对每个连接请求进行检查,因此记录的顺序是非常关键的。

每一条记录中各个字段的具体含义如下所述:

  • local:表示这条记录只接收通过 UNIX域套接字进行的连接。没有这种类型的记录,就不允许 UNIX域套接字的连接。只有在从服务器本机连接且在不指定-U参数的情况下,才是通过 UNIX域套接字连接。
  • host:表示这条记录既接收一个普通的 TCP/IP套接字连接,也接收一个经过SSL加密的 TCP/IP套接字连接。
  • hostssl:表示这条记录只接收一个经过SSL加密的 TCP/IP套接字连接。
  • hostnossl:表示这条记录只接收一个普通的 TCP/IP套接字连接。
  • DATABASE:声明当前记录所匹配且允许访问的数据库。特别地,该字段可选用all、sameuser以及samerole。其中all表示当前记录允许访问所有数据库对象; sameuser表示访问的数据库须与请求的用户同名才可访问;samerole表示访问请求的用户必须是与数据库同名角色中的成员才可访问。
  • USER:声明当前记录所匹配且允许访问的数据库用户。特别地,该字段可选用all以及“+角色(角色组)”。其中all表示允许对所有数据库用户对象的访问;“+角色(角色组)”表示匹配该角色或属于该角色组的成员,这些成员通过继承方式获得。
  • ADDRESS:指定与记录匹配且允许访问的IP地址范围。目前支持IPv4和IPv6两种形式的地址。
  • METHOD:声明连接时所使用的认证方法。目前openGauss所支持的认证方法包括trust、reject、sha256、cert及gss。这些将在下文着重介绍。
  • OPTIONS:这个可选字段的含义取决于选择的认证方法。目前作为保留项方便后续认证方法扩展,如支持基于ident认证时需要指定映射选项。

在openGauss系统安装部署完成后,HBA 文件中默认包含了超级用户的配置记录。对于其他管理员新创建的用户则需要重新进行配置。对于认证规则的配置建议遵循如下基本原则:

  • 靠前的记录有比较严格的连接参数和比较弱的认证方法。
  • 靠后的记录有比较宽松的连接参数和比较强的认证方法。

openGauss除了支持手工配置认证信息外,还支持使用 GUC(Grand Unified Configuration)工具进行规则配置,如允许名为jack的用户在客户端工具所在的IP地址为122.10.10.30的地方以sha256方式登录服务端数据库database1:

gs_guc set -Z coordinator -N all -I all -h "host database1 jack 122.10.10.30/32 sha256" 

这条命令将在所有的 CN 侧对应的 HBA 文件中添加对应规则。

(二)服务端认证方法

openGauss安全认证方法在 HBA 文件中由数据库运维人员配置,支持trust认证、口令认证和cert认证。

1.trust认证

trust认证意味着采用当前认证模式时,openGauss无条件接收连接请求,且访问请求时无须提供口令。这个方法如果使用不当,可允许所有用户在不提供口令的情况下直接连入数据库。为保障安全,openGauss当前仅支持数据库超级用户在本地以trust方法登录,不允许远程连接使用trust认证方法。

2.口令认证

openGauss目前主要支持sha256加密口令认证。由于整个身份认证过程中,不需要还原明文口令,因此采用 PBKDF2单向加密算法。其中 Hash函数使用sha256算法,盐值salt则通过安全随机数生成。算法中涉及的迭代次数可由用户自己视不同的场景决定,需考虑安全和性能间的一个平衡。

为了保留对历史版本的兼容性,在某些兼容性场景下,openGauss还支持 MD5算法对口令进行加密,但默认不推荐。

特别地,openGauss管理员用户在创建用户信息时不允许创建空口令,这意味着非超级用户在访问登录时必须提供口令信息(命令方式或交互式方式)。用户的口令信息被存放在系统表pg_authid中的rolpassword字段中,如果为空,则表示出现元信息错误。

3.cert认证

openGauss支持使用SSL安全连接通道(在安全认证通道详细介绍)。cert认证表示使用SSL客户端进行认证,不需要提供用户密码。在该认证模式下,客户端和服务端数据经过加密处理。在连接通道建立后,服务端会发送主密钥信息给客户端以响应客户端的握手信息,这个主密钥将是服务端识别客户端的重要依据。值得注意的是,该认证方式只支持hostssl类型的规则。

在文中,提到openGauss所支持的 METHOD字段选项包括trust、reject、sha256、cert及gss。除去上述介绍的三种认证方法外,reject选项表示对于当前认证规则无条件拒绝,一般用于“过滤”某些特定的主机。gss表示使用基于gssapi的kerberos认证,该认证方法依赖kerberosserver组件,一般用于支持openGauss集群内部通信认证和外部客户端连接认证,外部客户端仅支持gsql(openGauss提供的在命令行下运行的数据库连接工具。)或JDBC连接时使用。

(三) 安全认证通道

openGauss支持SSL标准协议(TLS1.2)。SSL 协议是安全性更高的协议标准, 它们加入了数字签名和数字证书来实现客户端和服务器的双向身份验证,保证了通信双方更加安全的数据传输。

openGauss在安装部署完成后,默认开启SSL认证模式。安装包中也包含了认证所需要的证书和密钥信息。这些证书由 CA 可信中心颁发。假定服务器的私钥为server.key,证书为server.crt,客户端的私钥为client.key,证书为client.crt,CA 根证书名称为cacert.pem。这些证书信息存放在“/home/ommdbadmin”目录。需要说明的是,集群安装部署完成后,服务端证书、私钥及根证书均已默认配置完成。用户只需要配置客户端相关的参数。

1.配置客户端参数

客户端参数配置依据实际场景分为单向认证配置和双向认证配置,整个配置信息存储在客户端工具所在的环境配置文件中(如.bashrc文件)。单向认证需要配置如下参数:

export PGSSLMODE="verify-ca"

export PGSSLROOTCERT="/home/ommdbadmin/cacert.pem" 

双向认证需配置如下参数:

export PGSSLCERT="/home/ommdbadmin/client.crt"

export PGSSLKEY="/home/ommdbadmin/client.key"

export PGSSLMODE="verify-ca"

export PGSSLROOTCERT="/home/ommdbadmin/cacert.pem"

2.修改客户端密钥的权限

客户端根证书、密钥、证书以及密钥密码加密文件的权限,需保证为600。如果权限不满足要求,则客户端无法以SSL连接到集群。配置如下:

chmod 600 cacert.pem

chmod 600 client.key

chmod 600 client.crt

chmod 600 client.key.cipher

chmod 600 client.key.ran

在实际应用中,应结合场景进行配置。从安全性考虑,建议使用双向认证方式,此时客户端的 PGSSLMODE变量建议设置为verify-ca。但如果本身数据库处在一个安全的环境下,且业务场景属于高并发、低时延业务则可使用单向认证模式。

除了通过SSL进行安全的 TCP/IP 连接外,openGauss还支持 SSH 隧道进行安全的 TCP/IP连接。SSH 专为远程登录会话和其他网络服务提供安全性的协议。从SSH 客户端来看,SSH 提供了两种级别的安全验证。

  • 基于口令的安全验证:使用账号和口令登录到远程主机。所有传输的数据都会被加密,但是不能保证正在连接的服务器就是需要连接的服务器。可能会有其他服务器冒充真正的服务器,也就是受到“中间人”方式的攻击。
  • 基于密钥的安全验证:用户必须为自己创建一对密钥,并把公钥放在需要访问的服务器上。这种级别的认证不仅加密所有传送的数据,而且避免“中间人”攻击方式。但是整个登录的过程可能需要10秒。

在实际执行过程中,SSH 服务和数据库服务应运行在同一台服务器上。

(四) RFC5802认证协议

在实际应用过程中,仅仅选定认证方法是不够的,还需要有一套完整的认证机制。这个机制要很好地解决客户端和服务端认证交互过程中的通信风险,还要解决客户端接收到加密口令后的验证问题。

openGauss目前选用标准的 RFC5802 认证机制来解决相关问题。它实际上是SCRAM(Salted Challenge Response Authentication Mechanism,是指Salted质询响应身份验证机制或者基于盐值的质询响应身份验证机制)标准流程中的协议。SCRAM 是一套包含服务器和客户端双向确认的用户认证体系,配合信道绑定可以避免中间人攻击。下面将着重介绍该协议内容。

  • 客户端知道用户名username和密码password,客户端发送username给服务端,服 务 端 检 索 相 应 的 认 证 信 息,例 如 salt、StoredKey、ServerKey 和 迭 代 次 数iteration-count(注意,服务端可能对于所有的用户都是用相同的迭代次数)。然后,服务端发送盐值salt和迭代次数给客户端。
  • 客户端需要进行一些计算,给服务端发送 ClientProof认证信息,服务端通过ClientProof对客户端进行认证,并发送ServerSignature给客户端。
  • 客户端通过ServerSignature对服务端进行认证。具体密钥计算公式如下:
SaltedPassword := Hi (password, salt, i) 其中,Hi()本质上是PBKDF2。

ClientKey := HMAC(SaltedPassword, "Client Key")

StoredKey := Hash(ClientKey)

AuthMessage := client-first-message-bare + "," +

server-first-message + "," +

client-final-message-without-proof

ServerKey := HMAC(SaltedPassword, "Server Key"

     其中:

  • AuthMessage:是通过连接认证交换的信息来计算的。
  • client-first-message-bare:主要包含客户端给服务端发送的用户名username和随机字符串 C-Nonce。
  • server-first-message:主 要 是 盐 值 salt、迭 代 次 数 以 及 随 机 生 成 的 字 符 串Nonce。
  • client-final-message-without-proof:不包含认证信息 ClientProof,包含随机字符串 Nonce。

具体密钥衍生过程如图3所示。

在这里插入图片描述

图3 密钥衍生过程

在这里,服务端存的是StoredKey和ServerKey。

  • StoredKey:用来验证客户端的客户身份,服务端认证客户端。通过计算ClientSignature与客户端发来的ClientProof进行异或运算,从而恢复得到 ClientKey, 然后将其进行哈希运算,将得到的值与StoredKey进行对比。如果相等,证明客户端验证通过。
  • ServerKey:用来向客户端表明自己身份,客户端认证服务端。通过计算ServerSignature与服务端发来的值进行比较,如果相等,则完成对服务端的认证。

在认证过程中,服务端可以计算出 ClientKey,验证完后直接丢弃不必存储。防止服务端伪造认证信息 ClientProof,从而仿冒客户端。要做到合法的登录,必须知道Password、SaltedPassword或者 ClientKey。如果 StoredKey和 ServerKey泄露,则无法做到合法登录。

图4描述了在一个认证会话期间的客户端和服务端的详细信息交换过程。

在这里插入图片描述

图4 服务端、客户端认证标准流程

  • 客户端发送username和随机生成的挑战值 C-Nonce给服务端。
  • 服务端返回盐值 salt、迭代次数以及随机 生 成 的 挑 战 值 Nonce给 客 户 端。Nonce是将从客户端收到的 C-Nonce和随机生成字符串组合形成的新挑战值。
  • 客户端发送认证响应。响应信息包含客户端认证信息 ClientProof和挑战值Nonce。ClientProof证明客户端拥有 ClientKey,但是不通过网络的方式发送。在收到信息后,首先需要校验传来的挑战值 Nonce,校验通过后,计算 ClientProof。 客户端利用盐值salt和迭代次数,从password计算得到 SaltedPassword,然后通过密钥计算公式计算得到ClientKey、StoredKey和ServerKey。计算AuthMessage、ClientSignature。通过将客户端首次发送的信息,服务端首次发送的信息以及客户端的响应信息(不包含认证信息)连接起来得到 AuthMessage。代码如下:
AuthMessage := client-first-message-bare + "," +server-first-message + "," + client-final-message-without-proof

ClientSignature := HMAC(StoredKey, AuthMessage

客户端通过将ClientKey和ClientSignature进行异或得到ClientProof:

ClientProof := ClientKey XOR ClientSignature 

将计算得到的ClientProof和第2步接收的随机字符串Nonce发送给服务端进行认证。

  • 服务端认证 Nonce和 ClientProof,并且发送自己的认证信息 ServerSignature。首先需要校验Nonce,校验通过后,计算 ServerSignature。使用其保存的StoredKey和AuthMessage通过 HMAC(HashMessageAuthenticationCode,哈希消息认证码) 算法进 行 计 算,然 后 与 客 户 端 传 来 的 ClientProof进 行 异 或,恢 复 ClientKey,再 对ClientKey进行哈希计算,得到的结果与服务端保存的 StoredKey进行比较。如果相等,则服务端对客户端的认证通过。
ClientSignature := HMAC(StoredKey, AuthMessage)

H(ClientProof XOR ClientSignature ) == StoredKe

  • 服务端通过计算得到的ServerSignature返回给客户端。
ServerSignature := HMAC(ServerKey, AuthMessage) 

  • 客户端通过将ServerKey和AuthMessage进行 HMAC计算得到的ServerSignature 与服务端传来的 ServerSignature进行比较。如果相等,则客户端完成对 服 务 端 的 认证。

三、openGauss角色管理机制

数据库发展早期,访问控制通常可以分 为 自 主 访 问 控 制 (Discretionary Access Control,DAC)和强制访问控制(Mandatory Access Control,MAC)。在自主访问控制模式下,用户是数据对象的控制者,用户依据自身的意愿决定是否将自己的对象访问权或部分访问权授予其他用户。而在强制访问控制模式下,对特定用户指定授权,用户不能将权限转交给他人。在实际应用中,DAC模式太弱,MAC又太强,且两者工作量较大,不便于管理。基于角色的访问控制机制(Role-BasedAccessControl,RBAC) 是一种更加灵活的机制,可以作为传统访问控制机制(DAC、MAC)的代替,也是较为有效的管理方法。

openGauss继承了业界目前通用的权限管理模型,实现了基于角色的访问控制机制。整个机制中的核心概念是“角色”,其更深层次的含义是角色组,即角色所拥有的权限实际上对应着这个角色组中所有成员的权限。管理员只需要将管理所希望的权限赋给角色,用户再从角色继承相应的权限即可,而无须对用户进行单一管理。当管理员需要增加和删减相关的权限时,角色组内的用户成员也会自动继承权限变更。

基于角色管理模型,用户可具备对对象的访问操作权限,并基于此完成数据管理。而这些用户所具备的权限是会经常发生变化的,为了有效地防止诸如权限提升、利用权限漏洞进行恶意操作等行为,必须进行权限的合理管控,即对象权限管理。更重要的是,需要在对象被访问操作时对当前用户的合法权限进行有效性检查,即对象权限检查。

(一)角色管理模型

在openGauss内核中,用户和角色是基本相同的两个对象,通过CREATE ROLE和CREATE USER分别来创建角色和用户,两者语法基本相同。以CREATE ROLE的语法为例进行说明,其语法为(通过“\h CREATE ROLE”可以在系统中查询):

CREATE ROLE role_name [ [ WITH ] option [ ... ] ] [ ENCRYPTED | UNENCRYPTED ] { PASSWORD | IDENTIFIED BY } { 'password' | DISABLE }; 

其中设置子句option的选项可以是:

 {SYSADMIN | NOSYSADMIN}

| {AUDITADMIN | NOAUDITADMIN} | {CREATEDB | NOCREATEDB}

| {USEFT | NOUSEFT} | {CREATEROLE | NOCREATEROLE}

| {INHERIT | NOINHERIT} | {LOGIN | NOLOGIN}

| {REPLICATION | NOREPLICATION} | {INDEPENDENT | NOINDEPENDENT}

| {VCADMIN | NOVCADMIN} | CONNECTION LIMIT connlimit

| VALID BEGIN 'timestamp' | VALID UNTIL 'timestamp'

| RESOURCE POOL 'respool' | USER GROUP 'groupuser'

| PERM SPACE 'spacelimit' | NODE GROUP logic_cluster_name

| IN ROLE role_name [, ...] | IN GROUP role_name [, ...]

| ROLE role_name [, ...] | ADMIN role_name [, ...]

| USER role_name [, ...] | SYSID uid

| DEFAULT TABLESPACE tablespace_name | PROFILE DEFAULT

| PROFILE profile_name | PGUSER

该命令仅可由具备 CREATE ROLE或者超级管理员权限的用户执行。对语法中涉及的关键参数做如下说明:

(1)ENCRYPTED | UNENCRYPTED

用于控制密码是否以密文形态存放在系统表中。目前该参数无实际作用,因为密码强制以密文形式存储。

(2)SYSADMIN | NOSYSADMIN

决定一个新创建的角色是否为“系统管理员”,默认为 NOSYSADMIN。

与该参数具有相类似概念的还包括 AUDITADMIN|NOAUDITADMIN、CREATEDB|NOCREATEDB、CREATEROLE|NOCREATEROLE,分别表示新创建的角色是否具有审计管理员权限,是否具有创建数据库权限,以及是否具有创建新角色的权限。

(3)USEFT|NOUSEFT

决定一个新角色是否能操作外表,包括新建外表、删除外表、修改外表和读写外表,默认为 NOUSEFT。

(4)INDEPENDENT|NOINDEPENDENT

定义私有、独立的角色。具有INDEPENDENT 属性的角色,管理员对其进行的控制、访问的权限被分离,具体规则如下:

  • 未经INDEPENDENT 角色授权,管理员无权对其表对象进行增加、删除、查询、修改、复制、授权操作。
  • 未经INDEPENDENT 角色授权,管理员无权修改INDEPENDENT 角色的继承关系。
  • 管理员无权修改INDEPENDENT 角色的表对象的属主。
  • 管理员无权去除INDEPENDENT 角色的INDEPENDENT 属性。
  • 管理员无权修改INDEPENDENT 角色的数据库口令,INDEPENDENT 角色需要管理好自身口令,口令丢失无法重置。
  • 管理员属性用户不允许定义修改为INDEPENDENT 属性。

(5)CONNECTION LIMIT

声明该角色可以使用的并发连接数量,默认值为-1,表示没有限制。

(6)PERM SPACE

设置用户使用空间的大小。

CREATEUSER语法与 CREATE ROLE基本相同,option选项范围也相同。事实上,用户和角色在openGauss内部是基本相同的两个对象。区别在于:①创建角色时默认没有登录权限,而创建用户时包含了登录权限;②创建用户时,系统会默认创建一个与之同名的schema,用于该用户进行对象管理。因此在权限管理实践中,建议通过角色进行权限的管理,通过用户进行数据的管理。

管理员通过 GRANT 语法将角色赋给相应的用户可使该用户拥有角色的权限。而在实际场景中,一个用户可以从属于不同的角色,从而拥有不同角色的权限。同样角色之间的权限也可以进行相互传递。用户在继承来自于不同角色的权限时,应尽量避免权限冲突的场景,如某一用户同时具有角色 A 不能访问表 T 的权限和角色 B访问表 T 的权限。

为了更清晰地描述权限管理模型,需要说明openGauss系统中的权限分为两种类型:系统权限和对象权限。系统权限描述了用户使用数据库的权限(如访问数据库、创建数据库、创建用户等)。对象权限,顾名思义,描述了用户操作数据库对象的权限(如增加、删除、修改、查表对象、执行函数、使用表空间等)。

通过上述CREATEROLE和CREATE USER的语法发现,在创建过程中,通过指定每一个options的值就可以设定该角色的属性。而这些属性事实上定义了该角色的系统权限,以及该角色登录认证的方式。这些属性包括是否具备登录权限(LOGIN),是否为超级用户(SUPERUSER),是否具备创建数据库的权限(CREATEDB),是否具备创建角色的权限(CREATEROLE),当前角色的初始口令信息(PASSWORD)以及是否可以继承其所属角色的权限的能力(INHERIT)。

角色所有的权限都记录在系统表pg_authid里面,通过对应的字段进行描述。如pg_authid表中对应的createrole字段用于标记当前角色是否拥有创建角色的权利。

角色的这些系统属性实际 上 定 义 了 用 户 使 用 数 据 库 权 限 的 大 小。例 如,所 有 具 有 CREATEROLE权限的角色都可以创建新的角色或用户。

在整个数据库系统的安装部署时会创建一个初始化用户。该初始化用户拥有最高权限,也称为系统的超级用户,这也是 pg_authid表中唯一一个superuser字段为true(真)的角色。

超级用户可以按照实际的业务诉求创建普通用户,也可以通过其所创建的管理员创建新的普通用户,再进行权限的管理。超级用户可以随时进行权限的赋予和撤回, 也可以直接参与到实际的数据管理业务中。在单用户场景的作业管理模式中,使用超级用户使权限和数据管理变得非常的高效。

(二)三权分立模型

如上文所述,openGauss安装完成后会得到一个具有最高权限的超级用户。数据库超级用户的高权限意味着该用户可以做任何系统管理操作和数据管理操作,甚至可以修改数据库对象,包括接下来将要介绍的审计日志信息。对于企业管理来说, 手握超级用户权限的管理人员可以在无人知晓的情况下改变数据行为,这带来的后果是不可想象的。

在上文提到,初始化用户不允许远程登录,仅可本地登录。那么,在组织行为上由IT 部门严格监控拥有该权限的员工在本地的操作行为,就可有效避免诸如修改表中数据等“监守自盗”行为的发生。为了实际管理需要,在数据库内部就需要其他的管理员用户来管理整个系统,如果将大部分的系统管理权限都交给某一个用户来执行,实际上也是不合适的,因为这等同于超级用户。

为了很好地解决权限高度集中的问题,在openGauss系统中引入三权分立角色模型,如图5所示。三权分立角色模型最关键的三个角色为安全管理员、系统管理员和审计管理员。其中,安全管理员用于创建数据管理用户;系统管理员对创建的用户进行赋权;审计管理员则审计安全管理员、系统管理员、普通用户实际的操作行为。

在这里插入图片描述

图5 三权分立角色模型

通过三权分立角色模型实现权限的分派,且三个管理员角色独立行使权限,相互制约制衡。使得整个系统的权限不会因为权限集中而引入安全的风险。

事实上,产品使用过程中的安全是技术本身与组织管理双重保障的结果,在系统实现三权分立模型后,需要有三个对应的产品自然人分别握有对应的账户信息,以达到真正权限分离的目的。

(三)对象访问控制

数据库中每个对象所拥有的权限信息经常发生变化,比如授予对象的部分操作权限给其他用户,或者删除用户对某些对象的操作权限。为了保护数据安全,当用户要对某个数据库对象进行操作之前,必须检查用户对对象的操作权限,仅当用户对此对象拥有合法操作的权限时,才允许用户对此对象执行相应操作。ACL(AccessControl list,访问控制列表)是openGauss进行对象权限管理和权限检查的基础。在数据库内部,每个对象都具有一个对应的 ACL,在该 ACL数据结构上存储了此对象的所有授权信息。当用户访问对象时,只有它在对象的 ACL 中并且具有所需的权限时才能访问该对象。当用户对对象的访问权限发生变更时,只需要在 ACL 上更新对应的权限即可。

事实上,ACL是内核中存储控制单元 ACE(Access Control Entry,访问控制项)的集合,这些存储控制单元记录了授权者 OID、受权者 OID 以及权限位三部分信息。其中,权限位是一个32位整数,每一位标记一个具体的权限操作,如 ACL_SELECT(第二位信息)标记查询用户是否有对对象的查询权限。每一个 ACE 对应一个 AclItem结构,记录了完整的对象访问用户和执行单元信息。在openGauss内部,每一个对象都对应一个 ACL,用户可以依据 ACL信息来校验对象上存在的权限信息。依据实际对象(如表、函数、语言)的不同,内核提供了不同的函数以实现对当前对象访问权限的校验:has_table_privilege__ ARGS函数中的星号分别代表用户信息和数据库对象信息。根据 ARGS(泛指一个可变数量的参数列表)提取的诸如用户信息、表信息、需要校验的权限信息,然后依据 ACL中记录的权限集与操作所需的权限集进行比对。如果 ACL记录的权限集大于操作所需的权限集,则 ACL检查通过,否则失败。

当管理者对对象的权限进行授权/回收时,需要修改 ACL 中对应的权限信息,即在对应的权限标记位添加或删除指定的权限(权限对应的标志位被修改为0或者1),完成对 ACL的更新操作。需要注意的是,在实际权限操作中,应尽可能避免循环授权情况的发生。

四、openGauss审计与追踪

openGauss在部署完成后,实际上会有多个用户参与数据管理。除了管理员用户外,更多的是创建的普通用户直接进行数据管理。用户的多样性会导致数据库存在一些不可预期的风险。如何快速发现和追溯到这些异常的行为,则需要依赖审计记录机制和审计追踪机制。

(一) 审计记录机制

审计记录的关键在于:

  • 定义何种数据库操作行为需要进行日志记录。
  • 记录的事件以何种形式展现和存储。

只有有效地记录了所关心的行为信息,才能依据这些行为进行问题审计和追溯,实现对系统的一个有效监督。

正如在“三权分立模型”中描述的,进行权限分离后,就出现了审计管理员(当然也可以使用普通角色管理模型中的系统管理员来担当)。审计管理员最重要的作用在于对管理员以及普通用户所有关心的行为进行记录和审计追溯。审计首先要定义审计哪些数据库行为,其次需要定义审计内容记录在什么文件中以及何种目录下,最后需要定义清楚应提供何种接口供审计管理员进行审计查询。

openGauss针对用户所关心的行为提供了基础审计能力,包括事件的发起者、发生的时间和发生的内容。openGauss的审计功能受总体开关audit_enabled控制,默认开启。该开关不支持动态加载,需要重启数据库后才可以使功能的性质发生改变。在总体开关的基础上,openGauss增加了每一个对应审计项的开关。只有相应的开关开启,对应的审计功能项才能生效。

不同于总体开关,每一个对应的子审计项都支持动态加载,在数据库运行期间修改审计开关的值,不需要重启数据库即可支持。审计的子项目包括如下部分:

  • audit_login_logout:用户登录、注销审计。

  • audit_database_process:数据库启动、停止、恢复和切换审计。

  • audit_user_locked:用户锁定和解锁审计。

  • audit_user_violation:用户访问越权审计。

  • audit_grant_revoke:授权和回收权限审计。

  • audit_system_object:数据库对象的 CREATE、ALTER和 DROP操作审计。

  • audit_dml_state:具体表的INSERT、UPDATE和 DELETE操作审计。

  • audit_dml_state_select:SELECT 查询操作审计。

  • audit_copy_exec:复制行为审计。

  • audit_function_exec:审计执行 FUNCTION 操作。

  • audit_set_parameter:审计设置参数的行为。

定义完审计记录行为后,当数据库执行相关的操作时,内核独立的审计线程就会记录审计日志。

传统的审计日志保存方法有两种:记录到数据库的表中及记录到 OS文件中。前一种方法由于表是数据库的对象,在符合权限的情况下就可以访问到该审计表,当发生非法操作时,审计记录的准确性难以得到保证。而后一种方法虽然需要用户维护审计日志,但是比较安全,即使一个账户可以访问数据库,但不一定有访问 OS这个文件的权限。

与审计日志存储相关的配置参数及其含义定义如下:

  • audit_directory:字符串类型,定义审计日志在系统中的存储目录,一个相对于“/data”数据目录的路径,默认值为/var/log/opengauss/perfadm/pg_audit,也可以由用户指定。

  • audit_resource_policy:布尔类型,控制审计日志的保存策略,即以空间还是时间限制为优先策略决定审计文件更新,默认值为on。

  • audit_space_limit:整数类型,定义允许审计日志占用的磁盘空间总量,默认值为1GB,在实际配置中需要结合环境进行总体考虑。

  • audit_file_remain_time:整数类型,定义保留审计日志的最短时间要求,默认值为90,单位为天。特别的,如果取值为0,则表示无时间限制。

  • audit_file_remain_threshold:整数类型,定义审计目录audit_directory下可以存储的审计文件个数。默认值为1048576。

  • audit_rotation_size:整数类型,定义单个审计日志文件的最大大小,当审计日志文件大小超过此参数值时,新创建一个审计文件。

  • audit_rotation_interval:整数类型,定义新创建一个审计日志文件的时间间隔。默认值为1天,单位为分钟。

通过上述的这些配置参数,系统管理员用户可以在查询任务发生后找到对应的审计日志,并进行有效归档。审计日志文件也会按照参数指定的规则进行更新、轮换等。

(二) 审计追踪机制

openGauss将审计所产生的文件独立存放在审计文件夹中,按照产生的先后顺序进行标记管理,并以特定的格式进行存储(默认为二进制格式文件)。当审计管理员需要进行审计查询时,通过执行函数pg_query_audit()即可,其具体的语句如下:

select * from pg_query_audit(timestamp valid_start_time, timestamp valid_end_time, audit_log);

其中,valid_start_time和valid_end_time定义了审计管理员将要审计的有效开始时间和有效结束时间;audit_log表示审计日志信息所在的归档路径,当不指定该参数时,默认查看链接当前实例的审计日志文件(不区分具体的审计文件)。

值得注意的是,valid_start_time和valid_end_time的有效值为从valid_start_time日期中的00:00:00开始到valid_end_time日期中的23:59:59。由于审计日志中包含了众多的信息,如时间、地点、行为分类等,审计管理在获得完整的信息后可以增加各种过滤条件来获得相对应的更明确的信息。

(三)统一审计

传统审计依据开关定义了不同的审计组合行为。事实上,这种无区分对待的审计虽然记录了所有想要审计的行为,但是对于通过审计日志发现问题则显得不那么容易,且管理员无法为特定的用户定义特定的行为,反而造成了系统处理的负担。因此需要为审计添加更精细化管理的能力。

统一审计的目的在于通过一系列有效的规则在数据库内部有选择性执行有效的审计,从而简化管理,提高数据库生成的审计数据的安全性。本节所述的技术目前处于研发阶段,对应产品尚未向客户发布。

openGauss提供了一套完整的统一审计策略机制,依据不同任务的诉求对用户行为进行定制化审计管理。更进一步,openGauss的统一审计不仅可以依据用户、依据表进行审计行为定义,同时还可以扩展至通过IP地址、App的名称来过滤和限制需要审计的内容。实际的语句如下:

CREATE AUDIT_POLICY policy_name
[
(privilege_audit_clause) | (access_audit_clause)
[filter_clause FILTER_TYPE(filter_value)]
[ENABLED|DISABLED]];

其中,privilege_audit_clause定义语句如下:

PRIVILEGES (DDL|ALL) [ ON (LABEL(resource_label_name)) [, …]* ];

该语句定义了针对 DDL类语句的审计策略,其中 LABEL表示一组资产集合,即数据库对象的集合。access_audit_clause定义语句如下:

ACCESS (DML|ALL) [ ON (LABEL(resource_label_name)) [, ...]* ];

该语句定义了针对 DML类语句的审计策略。filter_clause标记需要过滤的信息,常见的 Filtertypes(过滤类型)包括IP、APPS应用(访问的应用名)、ROLES(数据库系统用户)以及 LABEL对象。

一个有效的统一审计策略可参见如下:

CREATE AUDIT_POLICY admin_policy PRIVILEGES CREATE, ALTER, DROP FILTER ON IP(local), ROLES(dev);

该语句表示创建针对 CREATE/ALTER/DROP操作的审计策略,审计策略只对dev用户在本地(local)执行CREATE/ALTER/DROP行为时生效。

五、 openGauss数据安全技术

数据库最重要的作用是存储数据和处理分析数据。数据是整个数据库系统中最关键的资产。因此,在保护系统不受侵害的基础上最为重要的任务就是保护数据的安全。常见的数据安全技术包括数据加密、数据脱敏(Data Masking)、透明数据加密(Transparent Data Encryption,TDE)和全程加密(Always Encryption)技术。这里囊括了数据的动态流程和静态存储行为。

(一) 数据加密算法

数据加密和解密是防止数据隐私泄露最为常见也最为有效的手段之一。数据在经过加密后以密文形式存放在指定的目录下。加密的意义在于,通过一系列复杂的迭代计算,将原本的明文转换为随机的没有任何具体含义的字符串,即密文。当所使用的加密算法足够安全时,攻击者在有限的计算资源下将很难根据密文获取到明文信息。

常见的加密算法可分为对称加密算法和非对称加密算法。其中最为著名的非对称加密算法为 RSA 算法,其密钥长度须达到3072比特(b)才可以保证其安全性,即强安全。常见的对称加密算法为 AES算法,如 AES128和 AES256。相比于非对称加密算法,对称加密算法运算速度快,密文长度增长少,安全性容易证明,所需要的密钥长度短,但也存在密钥分发困难和不可用于数字签名等缺点。除了上述介绍的加密算法外,还有很多其他强安全算法,在此不一一介绍。下面重点介绍openGauss中所支持的数据加密能力。

首先openGauss在内核定义了数据加密和解密的函数,并对外提供了数据加密和解密的接口,函数接口为:

gs_encrypt_aes128(text, initial_value);

其中,text为需要加密的明文数据;initial_value为生成密钥时需要的初始化向量。该函数可以被灵活地应用在 SQL语句的各个地方。例如,通过使用INSERT 语句插入数据或者查询数据时均可以绑定该函数对数据进行加密处理,具体如下:

SELECT * FROM gs_encrypt_aes128(tbl.col, ‘1234’);

通过该查询,用户可以直接返回表tbl中的col列的密文信息。

与加密函数相对应的是解密函数,其接口格式定义为:

gs_decrypt_aes128(cypertext, initial_value);

其中,cypertext为加密之后的密文;initial_value需要为与加密时所采用的相同的值才可以,否则使用该函数也无法得到正确明文。

除了基本的数据加密和解密接口外,openGauss还在多个特性功能里提供了数据加密和解密功能。其中第一个提供加密和解密功能的特性是数据导入导出;第二个提供加密和解密功能的特性是数据库备份恢复。

(二)数据脱敏技术

在很多应用场景下,用户需要通过拥有表中某一列的访问权限来执行任务,但是又不能获取所做事务之外的其他权限。以快递人员为例,快递人员在递送包裹的时候需要知道收件人的联系方式和姓氏,但是无须知道对应的收件人的全称。在快递收件人信息部分,如果同时定义了收件人的姓名和电话,则暴露了收件人的隐私信息,“有心之人”可以通过此信息进行虚假信息构造或利用该隐私信息进行财产欺诈。因此在很多情况下,所定义的敏感信息是不建议对外展现的。

数据脱敏是解决此类问题的最有效方法之一,通过对敏感数据信息的部分信息或全量信息进行特殊处理可以有效掩盖敏感数据信息的真实部分,从而达到保护数据隐私信息的目的。数据脱敏按照脱敏呈现的时机可以分为数据动态脱敏和数据静态脱敏,其中前者在数据运行时对数据进行特殊处理,后者在数据存储的时候进行特殊处理以防止攻击者通过提取数据文件来直接获取敏感信息。本小节重点介绍数据动态脱敏技术。

数据动态脱敏的安全意义在于:

  • 用户在实际操作的时候无须用真实数据,只需要使用一个变化后的数据,可有效规避数据信息的直接暴露。
  • 在不同的国家或地区的法律法规中,如 GDPR(通用数据保护条例),约定不同的用户在管理数据的时候具有不同的访问对象权限。
  • 对于表中的同一列数据信息,不同的用户应具有不同的用途。

数据动态脱敏功能在数据库内核实际上表现为数据处理函数。通过函数处理使得数据库中的数据在返回给实际查询用户时数据值发生变更,如用户所有的年龄信息值在返回给客户端时均显示为“0”;又或是字符串数据中的部分字节位变更为其他字符,如信用卡卡号“1234 5678 0910 1112”在返回给客户端时显示为“XXXX XXXX XXXX 1112”。

在openGauss系统中,数据动态脱敏策略定义如下:

CREATE MASKING_POLICY policy_name
(
(masking_clause)
[filter_clause]
[ENABLE|DISABLE]
);

其中的具体参数说明如下:

  • masking_clause定义如下:
MASKING_FUNCTION(PARAMETERS) ON (SCOPE(FQDN)) | (LABEL(resource_label_name)) [, …]*;

定义了针对不同数据集合对象所采用的脱敏函数。这里,LABEL 为数据库安全标签。数据库安全标签实际上定义了一组数据内部的表对象或表中的部分列,用于标记相应数据脱敏策略的范围。

  • filter_clause定义如下:
FILTER ON FILTER_TYPE(filter_value [, …]*) [, …]*;

定义了数据动态脱敏策略所支持的过滤条件。 一个实际的数据动态脱敏案例如下:

CREATE MASKING_POLICY my_masking_policycreditcardmasking ON LABEL (mask_credcard),maskall ON LABEL (mask_all)FILTER ON IP(local), ROLES(dev);

其中,my_masking_policy为定义的数据动态脱敏策略名字;creditcardmasking以及mask_all为定义的 masking处理函数,分别用于处理从属于 mask_credcard对象集合和 mask_all对象集合;mask_credcard和 mask_all代表不同的Label对象,这些Label对象名称将作为唯一标识记录在系统表中。FILTER 表示当前动态脱敏策略所支持的连接源,连接源指的是实际数据库管理员使用何种用户,从何IP源位置发起,使用何种 App应用来访问当前的数据库。通过使用 FILTER 可以有效定义系统的访问源信息,并规避不应该访问当前系统的行为。

openGauss在系统内部预定义了七种数据脱敏策略,具体如表1所示。

表1 数据脱敏策略 |脱敏策略 | 含义 |脱敏前数据 | 脱敏后数据| |--|--|--|--| | creditcardmasking | 针对信用卡定义类数据的脱敏策略 |4880-9898-4545-2525 | xxxx-xxxx-xxxx-2525 | |maskall | 全脱敏策略 | 4880-9898-4545-2525 |xxxxxxxxxxxxxxxxxxx | | basicemailmasking |邮件类信息基础脱敏策略:脱敏用户名 | [email protected]|[email protected] | | fullemailmasking |邮件类信息全脱敏策略 | [email protected] | [email protected] | | alldigitsmasking | 数字脱敏策略 | alex123alex | alex000alex | | shufflemasking | 置换脱敏策略 | hello word | ollehdlrow | |randommasking | 随机脱敏策略 | hello word | ad5f5ghdf5 |

用户在实际使用时,还可以根据自己的需求自行定义数据脱敏策略。

(三)透明加密技术

当数据在静态存储状态时,除了使用常见的静态脱敏技术进行数据隐私保护外,另一种行之有效的方法是 TDE(透明加密)。事实上,静态脱敏在实际应用过程中是存在一定限制的。用户并不能对所有的数据类型都施加静态脱敏措施。

TDE从加密策略出发,即使用户数据被导出,也可以有效解决数据信息泄露风险。数据透明加密的初衷是为了防止第三方人员绕过数据库认证机制,直接读取数据文件中的数据(数据文件中的数据虽然是二进制数据,但是仍然是明文存放)。所以对数据库的数据文件进行加密后,必须在数据库启动后,用户通过正常途径连接数据库,才可以读取解密后的数据,达到数据保护的目的。

openGauss实施透明加密策略,首先是需要确 定一个数据库加密密钥(Database Encryption Key,DEK),该DEK由系统密钥管理系统(Key Management Service,KMS)生成,数据库密钥密文(EncryptedDatabaseEncryptionKey,EDEK)以文件方式(gs_tde_keys.cipher)存储于数据库系统中。该 DEK 一次生成,终身使用,不可变更,不可轮换。在快照(即备份)恢复时,需要使用此前的 DEK。

数据库在每次启动时,通过读取本地存储的密钥信息和 EDEK,向 KMS机器上的URL地址,传入密钥版本名(version-name)、密钥名(name)、IV 值和数据库加密密钥密文值,从而获取到解密后的 DEK。此密钥会缓存在实例的内存当中,当数据库需要加密或解密数据时从内存中复制密钥明文。

openGauss支持两种格式的透明加密算法,通过 GUC参数transparent_encryption_algo进行控制,当前支持的算法包括 AES-CTR-128和SM4-CTR-128。加密模式选用CTR(CounTeR,计数器模式)的原因是 CTR 加密可以保证明文和密文长度相等。明文和密文长度相等是由数据块(Block)的大小决定的,因为内存和磁盘存储格式对块的大小是有要求 的 (默 认 为 8KB)。特 别 的,在 openGauss列 存 储 中,列 存 储 单 元(ColumnUnit,CU)的最大值是有限制的,所以其加密后的长度也不能超过最大限制值。

一个完整的数据透明加密流程如图1所示,即该特性的生命周期共分为3个阶段:安装阶段、启动阶段和使用阶段。

  • 安装阶段:用户通过安装部署的配置,生成密钥记录文件和 GUC参数。

  • 启动阶段:用户依据密钥记录文件和 GUC参数,获取到明文。

  • 使用阶段:用户根据密钥算法标记和全局缓存明文,完成数据落盘的加密和数据读取的解密。

在这里插入图片描述

图1 数据透明加密流程

(四) 全程加密技术

无论是当前通用的数据脱敏方案,还是数据透明加密方案,其所解决的都是部分状态或部分流程下的数据隐私安全。数据库攻击者可通过其他不同的攻击技术手段在数据以明文存在或处于内存中时抓取数据流信息,从而达到获取隐私数据的目的。如果数据在整个生命周期中都能够处于加密的形态,且密钥掌握在用户自己手中,则数据库用户可有效地防止数据隐私的泄露。

全程加密技术就是在这种场景下诞生的。其核心是使得数据从用户手中进入到数据库系统后一直处于加密状态,用户所关心的数据分析过程也在密态状态下完成。在整个数据分析处理过程中,即使用户数据被攻击者窃取,由于密钥一直掌握在客户自己手中,攻击者也无法获得相关的信息。目前该技术处于研发阶段,对应产品尚未发布。

openGauss分三个阶段来实现完整的数据全程加密功能。

  • 第一阶段:实现客户端全程加密能力。系统在客户端提供数据加解密模块和密钥管理模块,在这种设计思路下数据在客户端完成加密后进入数据库,在完成处理分析返回结果的时候在客户端完成解密功能。客户端全程加密的缺陷在于只能支持等值类查询。
  • 在第二阶段:将在服务端实现基于密文场景的密文查询和密文检索能力,使得数据库具备更加强大的处理能力。
  • 在第三阶段:openGauss将构建基于可信硬件的可信计算能力。在此将基于鲲鹏芯片来构建数据库的可信计算能力。在可信硬件中,完成对数据的解密和计算。数据从可 信 硬 件 进 入 到 真 实 世 界 后,将 再 加 密 成 密 文 返 回 给 客 户。一 个 完 整 的openGauss全程加密方案架构如图2所示。

[图片上传失败...(image-af3b64-1619524289597)]

图2openGauss全程加密方案架构

下面介绍openGauss客户端全程加密方案,也称为客户端列密方案 (Client ColumnEncryption,CCE)。在该方案中,首先应该由用户来指定对哪一列数据进行 加密,通过在指定的属性列后面加上关键字“encrypted”进行标记,如下述语句所示:

CREATE TABLE test_encrypt(creditcard varchar(19) encrypted);

为了有效保证加密数据的安全性并支持数据的密态查询,在内核中选用确定性AES算法。具体来说,其加密算法为:AEAD_AES_256_CBC_HMAC_SHA_256。整个方案中使用双层密钥方案,第一层根密钥用户向密钥管理中心获取,作为根密钥(master key)。第二层为数据加密密钥,也称为工作密钥。工作密钥通过根密钥加密后存放在服务器端。在加密列创建完成后,如果没有工作密钥,则系统会单独为该列创建一个工作密钥。不同的属性列可以通过创建语法指定并共享列加密密钥。

为保证整个系统的安全性,加密工作密钥的加密算法强度应高于使用工作密钥加密数据的强度。在openGauss中,一般使用 RSA-OAEP算法来加密工作密钥,而根密钥仅存放在客户端。密钥层次关系如图3所示。

[图片上传失败...(image-7c3b89-1619524289597)]

图3 全程加密功能的密钥管理方案

由于采用确定性加密算法,对于相同的明文,所获取的密文也是相同的。在这种机制下,客户端全程加密可有效地支持等值查询,只需要将对应查询条件中的参数按照对应属性列的加密算法进行加密,并传给服务端即可。一个完整的客户端全程加密方案的查询流程如图4所示。在流程图的客户端部分,需要优先检查相关信息的有效性。

在这里插入图片描述

图4客户端加密方案查询流程图

客户端全程加密方案是非常简单易懂的,即通过确定加密机制保障结果的正确性和完整性,但对于日益复杂的查询任务来说,客户端全程加密方案是远远不够的。因为客户端全程加密仅仅能满足那些等值查询任务,如等值条件查询、分组、连接操作等。对于那些更为复杂的数据搜索,如比较查询、范围查询等,则需要更为复杂的密态查询算法或服务端可信硬件方案。

事实上,密文查询算法和检索算法在学术界一直都是热点的研究方向,如 OPE(Order Preserve Encryption,保存加密)/ORE(Order Reveal Encryption,顺序揭示加密)算法、SSE(SymmetricSearchableEncryption,顺序揭示加密)算法等。openGauss将针对排序、范围查询、模糊检索实现纯软件态的密文查询和密文检索。纯软件方案的缺陷在于:由于在密文状态下进行运算,会导致系统整体性能变慢。为了支持密态计算,需要密文在计算完成后解密的结果与明文计算所获得的结果相同。全同态加密是最行之有效的算法,可有效解决数据在密文形态下的加法和乘法计算,而不暴露相关明文信息。但是全同态加密最大的问题在于其性能过于低效,以至于没有一款商业数据库支持该能力,哪怕是部分同态加密能力,如加法同态或者乘法同态。

在第三阶段,openGauss将提供基于可信硬件的密态计算能力。其核心是数据密文形态进入服务端可信硬件中并完成所需要的密文计算。可信硬件将系统内核分为安全世界和非安全世界。数据计算完成后再以密文形态返回给非安全世界,并最终返回给客户端。目前通用的Intel芯片和 ARM 芯片均提供了相类似的功能。在Intel芯片中,该隔离区域被称为 SGX(SoftwareGuardExtensions,软件保护发展)。SGX是一个被物理隔离的区域,数据即使以明文形式存放在该物理区域内,攻击者也无法访问。在 ARM 架构中,与其类似的功能被称为 Trust Zone(受信区域),基于 Trust Zone,人们可以构建可信操作系统(Trusted OS),然后可以开发相对应的可信应用。基于可信计算环境,用户可以解密这些数据进行各类数据库查询操作。当数据离开这些环境后,数据则以密文形态存在,并返回给客户再进行解密。从而起到保护数据隐私的目的。

六 、openGauss云安全技术

传统的数据库对于企业来说,运维是一个重大的难题,因为每个企业需要拥有针对特定数据库专业知识的 DBA 人员,且数据库运维成本很高,对于小企业来说是很难持续维持的。随着云技术的成熟,越来越多的企业将应用和数据迁移上云。不同于传统的IT 业务场景,在云环境下,系统所面临的风险远远多于私有环境。因此,除基本的安全能力外,还需要额外的考虑云环境所面临的风险。

(一) IAM 认证

当用户需要把数据库部署到云上时,用户首先需要通过 Portal界面创建数据库服务。创建成功后,用户则可以下载对应的客户端来进行数据管理操作。为了提升数据库使用过 程 中 的 便 捷 性 和 安 全 性,云 服 务 一 般 会 提 供 IAM(Identityand Access Management,身份与访问管理)服务。

openGauss搬迁上云后所提供的服务称为华为数据仓库服务(Data Warehouse Service,DWS)。当与IAM 进行对接时,需要对应的服务和数据库的 C/S两端协作完成。完整的IAM 认证对接组件流程图如图5所示。

在这里插入图片描述

图5 IAM 认证对接组件流程图

在上述流程图中,要求云数据库服务管控侧和openGauss内核侧分别具备如表2的功能。

表2 云数据库服务管控侧和openGauss内核侧功能表 | 序号 | 云数据库服务管控侧 | openGauss内核侧 | | ------------ | ------------ | ------------ | | 1 | 与IAM对接,支持配置具有登录数据库权限的IAM角色信息 | 支持创建支持IAM认证的数据库用户,该用户没有密码,只支持IAM连接认证使用 | | 2 | 支持获取凭证API接口,以ak/sk信息为入参获取token,且返回token前需要校验token中IAM用户名信息 | 服务端新增认证类型,通过用户属性判断使用IAM认证,而非账户口令认证 | | 3 | 获取凭证API接口需支持用户自动创建及群组添加用户功能 |客户端JDBC支持使用凭证API接口获取IAM临时凭据信息,并作为密码参数,传递给服务器 | | 4 |在DB开始认证前,将集群标识码、解析token用的证书传递到数据库服务器上 | 数据库服务侧支持获取region证书对token进行解签名 | | 5 | 将集群标识码信息与token信息进行封装,返回给DB client使用 | 数据库服务根据token(含集群标识码)、policy等信息check解签名后的token是否符合数据库连接请求的要求,进行最终认证 |

事实上,openGauss支持两种方式来创建用于IAM 认证的用户。第一种方式是手动创建,使用语句如下,无须指定该用户的密码。

CREATE USER 'db_iam_user' PASSWORD DISABLE;

第二种方式为自动创建,由 DWS管控侧提供凭证来指定自动创建参数(参数为AutoCreate),如果指定的数据库用户不存在,则会自动创建,需 openGauss内核侧适配,工具支持以下参数:

  • 集群标识符:包含数据库的集群名称。

  • 数据库用户名:现有或新的数据库用户名称。如果数据库中不存在此用户且AutoCreate为true,则将创建支持IAM 认证的数据库新用户。如果此用户不存在且AutoCreate为false,则请求会失败。

  • AutoCreate(可选):如果数据库用户名不存在,则创建新用户。

获取凭证 API接口将通过 DWSService和管控侧工具将 AutoCreate、数据库用户名信息传递到管控域,GuestAgent需要内部连接数据库查询 DWS Service传递的数据库用户名是否存在,如果存在,则直接退出;如果不存在,则判断 AutoCreate是否为true,如果AutoCreate为true,则拼接如下SQL语句发给数据库创建用于IAM 认证的用户:

CREATE ROLE user_name PASSWORD DISABLE;

(二) 安全chroot技术

数据库搬迁上云后需要解决的另外一个问题是目录安全。当攻击者知道数据库的安装目录后,可以破坏数据库的目录结构。chroot(change Root)技术通过改变程序执行时所参考的根目录位置增进系统的安全性来限制使用者能做的事。

chroot是当前云环境必须具备的一种技术,chroot的作用包括:

  • 切换运行系统的根目录所在位置,可引导 Linux系统启动和系统急救;
  • 增强系统的安全性,限制用户的可见性和权限;
  • 建立与原始系统相隔离的系统目录结构,降低失败传播等问题。

openGauss采用基于chroot目录内容最小化方案将集群所有相关文件配置在chroot目录下的/var/chroot文件,在经过chroot之后,系统读取到的目录和文件将不再是旧系统根下的而是新根下,建立一个与原系统隔离的系统目录结构,增加了系的安全性,限制了用户的权利。默认chroot的目录路径为/var/chroot。

(三)防篡改技术

数据库从线下搬迁到云上后,除了解决基本的风险之外,还有一个最为重要的风险,就是恶意 DBA 的运维风险。DBA 用户及恶意运维人员可以登录系统,并恶意修改系统数据。在修改完数据信息后,DBA 用户可以删除对应的审计日志而不被审计管理员发现。这里实际上体现的是第三方可信源“监守自盗”的问题。

当前解决第三方可信源“监守自盗”的最有效方法是去中心化。区块链就是最好的体现,即在牺牲一点效率的情况下,可获得极大的安全性。在区块链系统中,首先没有一本中央大账本了(如第三方机构),所以无法摧毁;其次,无法作弊,除非篡改者能够控制系统内的大多数人对计算机中的账本进行修改,否则系统会参考多数人的意见来决定什么才是真实结果,而自己修改的账本完全没有意义。

区块链的本质即分布式多活数据库。区块链与数据库在很多概念上具有共同之处。下面就一些区块链中的基本概念进行对比。

  • 共识算法:在分布式数据库中,最为关键的一点是需要保持数据的一致性。当前普遍采用 PAXOS或 RAFT 算法达成分布式数据库的数据一致性协商。在实施时,数据分片会同时存放在数据库的主从实例上,主实例负责数据的读写操作,从实例进行只读操作。当主实例写入数据时,其事务日志会被实时同步给其他从实例进行回放,以达到主从实例之间数据一致性的目标。 相比于区块链体系,数据库的主实例即为日志生成实例,其每次生成事务日志的功能,与区块链中每次出块时矿工的功能完全等价。但是分布式数据库每次操作时对日志实时广播到实例中,并且在事务提交时进行一致性判断。

  • 智能合约:在区块链系统中,智能合约其实是一段存储在一个区块链上的代码,由区块链交易触发,并与区块链状态模式相互影响。这里所说的代码可以是任意的支持语言,如Java、Fortran、C++等。当使用SQL时,它就是写在扩展SQL中的存储过程。

除了上述关键技术点对比分析外,还可以对区块链和数据库在其他技术细节上进行如表3所示的分析。

表3 区块链和数据库技术分析 | 分析点 | 数据库|区块链| |--|--|--| | 参与者 | 单方参与 | 多方参与 | | 管理 | Centralized | Decentralized | | 最新记录 | Table Value | World State | | 历史记录| Log | Chain| | 查询 | Table Value | World State + Chain | | 数字签名 | No | Yes | | 容错机制 | CFT(Crash Fault Tolerance) | BFT(Byzantine Fault Tolerance) | | 用户自定义逻辑 |Stored Procedure/User Define Function | Smart Contract |

事实上,通过上述分析可以看到,数据库和区块链具有很多相似之处,因此可以在数据库中融入区块链的思想,将区块链天生具备的防篡改能力集成到数据库中。

openGauss数据将支持两种形态的防篡改系统:中心化部署和去中心化部署方式。中心化部署和去中心化部署方案的主要区别在于:

  • 中心化部署情况下,对外提供服务的实例即为主实例。
  • 不需要通过拜占庭等类似的共识算法进行共识和校验。

因此,在中心化部署下,除主实例外的剩余实例主要为日志备份实例,或提供对外的查询服务。在去中心化部署下,交易连接的任务实例即为主实例(整个系统是一个多主的关系),然后在本地交易完成后与其他实例进行背书共识和验证。当复制实例验证成功后方可提交当前事务。

由于结合了数据库的优点和区块链的优点,openGauss防篡改系统有如下优势:系统内数据不可更改、记录历史可追溯、数据加密可验证、系统高可靠、整体易用性高。

七 、openGauss智能安全机制

随着攻防理念的发展,系统中的安全特性变得越来越复杂。虽然更加系统化、精细化的安全技术可以有效地防御和解决环境中存在的各类风险,但是对 DBA 和运维人员都提出了较高的要求。这部分工作无论是由企业来做,还是由云服务提供商来完成,都是一个较大的挑战。另一方面,不同国家和地区对安全的诉求和定义也是不一样的,服务提供商在选择对应的安全策略时很容易遗忘彼此之间的差异。因此需要系统变得更加智能,变得可以自己管理这些安全机制,这称为自治安全机制或智能安全机制。

事实上,越来越多的数据库服务商正在聚焦于通过使用 AI技术来提升系统的安全性,这不仅包括通常的智能数据安全,还包括系统自治管理安全。在众多的智能安全机制中,首要的是敏感数据的发现。对于数据库而言,最重要的是保护用户数据,而数据中最为重要的是敏感数据。随着数据格式的多样化,用户实际的隐私数据隐藏在了海量的数据潮中,更为困难的一点是,不同行业、不同国家的法律法规所定义的敏感数据是不一样的。因此,不仅要实现敏感数据发现功能,还要基于 AI来实现该功能。

除了发现敏感数据外,另外一个重要的需要是利用 AI功能的特性使 AI防 SQL注入攻击。SQL注入通过动态拼接 SQL 注入传入Web服务端或者数据库服务端。其呈现的方式多种多样。与之类似的还包括 AI异常行为发现和 AI日志分析。AI系统通过对异常行为和 AI日志的分析,可以快速了解到系统在遭遇什么样的风险,以及这些风险行为的特征是什么,并会提示存在的风险,然后由系统自己根据当前存在的风险进行安全策略制定。一个完整的AI自反馈机制如图6所示。这也是openGauss未来重点的发力方向。

在这里插入图片描述

图6 AI自反馈机制全景图

在整个 AI自反馈机制中:

  • 数据库仍然可以接收来自不同行为的连接,包括终端手机数据、数据库用户、各类应用,也可能涵盖攻击者。所有的这些访问行为均记录在数据库内核日志中。

  • 除了对外的这些连接行为外,数据库迁移上云后还会有一个特殊类的连接用户,如 DBA 或集群维护用户,这些用户存在第三方信任问题。

你可能感兴趣的:(2021-04-27)