【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(2)

二.openGauss安全认证

安全认证通道03

首先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"
  1. 修改客户端密钥的权限
    客户端根证书、密钥、证书以及密钥密码加密文件的权限,需保证为600。如果权限不满足要求,则客户端无法以SSL连接到集群。
chmod 600 cacert.pem
chmod 600 client.key
chmod 600 client.crt
chmod 600 client.key.cipher
chmod 600 client.key.rand

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

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

§ 基于口令的安全验证:使用帐号和口令登录到远程主机。所有传输的数据都会被加密,但是不能保证正在连接的服务器就是需要连接的服务器。可能会有其他服务器冒充真正的服务器,也就是受到“中间人”方式的攻击。

§ 基于密钥的安全验证:用户必须为自己创建一对密钥,并把公钥放在需要访问的服务器上。这种级别的认证不仅加密所有传送的数据,而且避免“中间人”攻击方式。但是整个登录的过程可能需要10秒。

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

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

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

§ 首先,客户端知道用户名username和密码password,客户端发送用户名username给服务端,服务端检索相应的认证信息,例如:salt、StoredKey、ServerKey和迭代次数i(注意,服务端可能对于所有的用户都是用相同的迭代次数)。然后,服务端发送盐值salt和迭代次数i给客户端。

§ 接下来,客户端需要进行一些计算,给服务端发送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、迭代次数i以及随机生成的字符串Nonce。

§ client-final-message-without-proof不包含认证信息ClientProof,包含随机字符串Nonce。

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

【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(2)_第1张图片

图3 密钥衍生过程

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

§ StoredKey是用来验证Client客户身份,服务端认证客户端。通过计算ClientSignature与客户端发来的ClientProof进行异或运算,从而恢复得到ClientKey,然后将其进行hash运算,将得到的值与StoredKey进行对比。如果相等,证明客户端验证通过。

§ ServerKey是用来向客户端表明自己身份的,客户端认证服务端。通过计算ServerSignature与服务端发来的值进行比较,如果相等,则完成对服务端的认证。

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

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

【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(2)_第2张图片

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

(1) 客户端发送username和随机生成的挑战值C-Nonce给服务端。
(2) 服务端返回盐值salt、迭代次数i以及随机生成的挑战值Nonce给客户端。Nonce是将从客户端收到的C-Nonce和随机生成字符串组合形成的新挑战值。
(3) 客户端发送认证响应。响应信息包含客户端认证信息ClientProof和挑战值Nonce。ClientProof证明客户端拥有ClientKey,但是不通过网络的方式发送。在收到信息后,首先需要校验传来的挑战值Nonce,校验通过后,计算ClientProof。
客户端利用salt和iteration-count(迭代次数),从password计算得到SaltedPassword,然后通过密钥计算公式计算得到ClientKey、StoryKey和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发送给服务端进行认证。

(4) 服务端认证Nonce和ClientProof,并且发送自己的认证信息ServerSignature。首先需要校验Nonce,校验通过后,计算ServerSignature。使用其保存的StoredKey和AuthMessage通过HMAC(Hash Message Authentication Code)算法进行计算,然后与客户端传来的ClientProof进行异或,恢复ClientKey,再对ClientKey进行哈希计算,得到的结果与服务端保存的StoredKey进行比较。如果相等,则服务端对客户端的认证通过。
ClientSignature := HMAC(StoredKey, AuthMessage)
H(ClientProof XOR ClientSignature ) == StoredKey
(5) 服务端通过计算得到的ServerSignature返回给客户端。
ServerSignature := HMAC(ServerKey, AuthMessage)
(6) 客户端通过将ServerKey和AuthMessage进行HMAC计算得到的ServerSignature与服务端传来的ServerSignature进行比较。如果相等,则客户端完成对服务端的认证。
未完待续......

你可能感兴趣的:(数据库)