ITPub博客

首页 > 数据库 > 数据库开发技术 > OceanBase 4.2 等保认证 SSL 验收测试

OceanBase 4.2 等保认证 SSL 验收测试

原创 数据库开发技术 作者:plvision 时间:2024-01-15 09:03:35 0 删除 编辑
OceanBase 可以用于信创项目或等保项目。等保二的标准里对于数据库连接要求支持 SSL。本文主要分享 OceanBase 4.2 如何验收等保的 SSL 传输加密这项标准。
整个分享会分为四部分:
  • 首先,了解 OceanBase 所有的连接原理以及理论上确认是否支持 SSL 传输加密。

  • 第二,准备 SSL 用的 CA 证书和私钥、服务器和客户端的证书等。
  • 第三,配置 OB 集群和 ODP(OBProxy)开启 SSL 认证以及创建相关数据库用户。
  • 第四,应用客户端开启 SSL 连接 OB 集群并多个环节验证连接确实开启了 SSL 。


OceanBase 连接原理
OceanBase 从 2.2 版本就开始支持 传输加密 SSL。由于 OceanBase 的访问都通过 ODP(OBProxy),所以传输加密主要是指 ODP 的连接加密,包括 ODP 前端连接和后端连接的加密。2.2 版本的 传输加密配置方法参考《OceanBase SSL 连接全攻略》。4.2 版本的配置方法基本相同,另外改进了 OceanBase 节点之间传输加密的配置方法。
OceanBase 采用两种协议进行通信:
  • MySQL 协议:从应用的驱动到 ODP(生产环境可能还经过负载均衡设备),ODP 到 OBServer 节点都是采用 MySQL 协议通信。ODP 还支持对 MySQL 协议内容压缩(ODP 参数 enable_compression_protocol 控制)以及自研的通信协议 OceanBase 2.0 协议(兼容 MySQL 协议,通过 ODP 参数 enable_ob_protocol_v2 开启)。OceanBase 4.0 版本后强制在 ODP 跟 OBServer 之间开启 2.0 协议(新增 ODP 参数 enable_ob_protocol_v2_with_client 控制是否在客户端之间开启,客户端需要使用 OB 最新驱动)。这个协议连接端口默认是 2881 。

  • OB-RPC 协议:OceanBase 集群节点之间通信、以及跟 Liboblog 组件通信、ob_admin 命令通信都是使用自定义的 RPC 协议通信。RPC 连接端口默认是 2882 。

OceanBase 支持在这两种协议上开启 TLS/SSL 协议传输。

关于客户端连接,除了链路支持 SSL 认证外,还需要创建相应的数据库用户,强制这些用户使用 SSL 相关认证。OceanBase 数据库为每个用户提供不同的 SSL 认证机制的选择。包括:

  • SSL 单向认证:客户端需要加载服务端的 CA 证书。客户端单向校验服务器端证书的有效性。
  • X509 双向认证:服务器端和客户端都需要加载对端的 CA 证书,服务器端和客户端双向校验证书的有效性。
  • 特殊的双向认证(可组合):
    • 指定加密算法认证:基于 X509 双向认证,同时限定 SSL 加密算法。
    • 指定发行方认证:基于 X509 双向认证,同时限定客户端 CA 证书发行方。
    • 指定 SSL 主题认证:基于 X509 双向认证, 同时限定客户端 CA 证书主题。
有关名词概念在这里简单补充一下。

简称

英文全称

中文全称

CA

Certificate Authority / Certification Authority

证书颁发机构

SSL

Secure Sockets Layer

安全套接字层协议

TLS

Transport Layer Security

传输层安全性协议

-

Public key

公钥

-

Private key

私钥

X.509

-

密码学里的公钥证书格式标准



相关证书生成方法

CA 根证书严格来说由可信机构持有,这里是测试,选择一台第三方服务器模拟权威机构生成 CA 证书。

  • 第一步是生成 RSA 私钥。

[root@server065 certs]# openssl genpkey -algorithm RSA  -pkeyopt rsa_keygen_bits:2048 -outform PEM  -out cakey.pem.......+++..................+++[root@server065 certs]#
  • 第二步是生成 CA根 证书。

[root@server065 certs]# openssl req -new -x509 -nodes -days 3600 -key cakey.pem -keyform PEM -out ca.pemYou are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [XX]:CNState or Province Name (full name) []:ZJLocality Name (eg, city) [Default City]:HZOrganization Name (eg, company) [Default Company Ltd]:OBOrganizational Unit Name (eg, section) []:CACommon Name (eg, your name or your server's hostname) []:OBCAEmail Address []:

OB 集群端也需要生成证书。

这里不需要每台节点都去申领证书,共用一个证书即可。

  • 第一步,生成服务器端私钥和证书签名请求文件。

[root@server063 ~]# openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pemGenerating a 2048 bit RSA private key.....................................................................................................................+++.................+++writing new private key to 'server-key.pem'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [XX]:CNState or Province Name (full name) []:ZJLocality Name (eg, city) [Default City]:HZOrganization Name (eg, company) [Default Company Ltd]:YQOrganizational Unit Name (eg, section) []:CACommon Name (eg, your name or your server's hostname) []:OBSERVEREmail Address []:
Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:aaAA11__An optional company name []:

注意,上面输入的 Common Name 在后面会有用。

  • 第二步,将上面生成的 server-req.pem 文件发送到 CA 服务器上进行签名,申请证书。

[root@server065 certs]# openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey cakey.pem -set_serial 01 -out server-cert.pemSignature oksubject=/C=CN/ST=ZJ/L=HZ/O=YQ/OU=CA/CN=OBSERVERGetting CA Private KeyYou have new mail in /var/spool/mail/root

然后将签名后的证书发回到 OBServer 服务器上。

  • 第三步,查看经 CA 签名后的服务端证书。

[root@server063 certs]# openssl x509 -in server-cert.pem -noout -textCertificate:    Data:        Version: 1 (0x0)        Serial Number: 1 (0x1)    Signature Algorithm: sha256WithRSAEncryption        Issuer: C=CN, ST=ZJ, L=HZ, O=OB, OU=CA, CN=OBCA        Validity            Not Before: Jan 14 03:11:21 2024 GMT            Not After : Nov 22 03:11:21 2033 GMT        Subject: C=CN, ST=ZJ, L=HZ, O=YQ, OU=CA, CN=OBSERVER        Subject Public Key Info:            Public Key Algorithm: rsaEncryption                Public-Key: (2048 bit)                Modulus:                    00:ec:c1:7b:b7:29:36:b5:b4:cf:31:79:ae:21:02:                    07:dc:08:0f:40:c8:29:34:cc:d4:bd:d0:3e:cc:d8:                    df:85:93:e5:0f:62:16:78:a2:b7:20:86:19:c8:c5:                    2d:bf:fb:e7:7a:10:a0:5f:e9:c3:be:5e:ce:4e:0f:                    4a:19:e5:e8:23:13:26:9b:7c:6d:ca:3d:02:49:a2:                    1f:42:00:e6:99:a4:e3:cb:e9:29:ee:a2:5a:27:f2:                    55:5e:5b:b4:34:a4:a0:d7:c5:99:f7:73:1f:af:6e:                    fb:08:35:32:3b:81:13:de:84:4f:e1:d3:df:5e:be:                    cc:5e:cf:c2:b9:60:95:57:cd:14:0c:e2:3f:6c:17:                    7b:f6:44:a1:ec:6f:36:e8:b2:86:e2:75:12:fc:08:                    1b:c3:ce:31:3f:dd:08:eb:a5:71:a0:2d:8e:d0:37:                    62:d6:ea:e1:ef:ee:4a:8f:ae:df:54:15:8a:a5:54:                    ba:7d:aa:54:90:ae:25:23:13:25:a0:f8:81:29:43:                    91:a5:a0:6a:9b:ed:93:e5:80:ea:fe:07:94:6d:d1:                    f8:a5:e5:42:c4:a7:64:7b:92:1f:d5:2f:a8:e8:2a:                    ec:5b:e2:d8:48:39:3d:16:a6:5a:c8:20:d1:26:7b:                    cc:b0:de:44:5e:70:c9:68:c3:ad:fc:07:9f:af:dd:                    d6:e3                Exponent: 65537 (0x10001)    Signature Algorithm: sha256WithRSAEncryption         1d:b8:df:1d:66:d1:35:1d:fb:3d:2a:aa:79:41:4a:38:2b:a5:         49:bf:e4:43:cb:af:a8:41:57:38:50:5c:fc:c5:03:68:2d:ed:         5a:dc:ea:57:a0:8b:56:1e:2f:2b:21:23:29:ba:b6:b8:09:39:         8d:5a:40:ad:7e:21:a3:c8:3e:1d:15:be:bb:6d:ac:f3:5b:7e:         9d:53:3c:a4:cd:e3:cc:41:e2:e8:42:9f:7e:34:d6:40:8b:45:         55:3f:9a:d1:df:75:8b:b3:a5:fe:63:e3:09:47:ad:be:2f:0f:         88:03:55:7e:d5:06:68:1e:c0:07:6f:5e:38:fd:ba:8c:0e:a9:         53:49:48:f2:70:fe:5b:50:60:94:99:bb:62:35:cb:b4:6a:98:         71:71:68:66:1b:41:42:c9:92:99:b5:aa:ed:ca:65:77:2a:da:         e0:ec:a6:82:47:d8:c7:b6:3d:ca:b7:09:f4:c4:ae:2d:79:45:         6f:e6:62:c6:a5:05:6a:44:19:4c:2a:c6:12:0e:77:a1:c0:f2:         a7:b9:f0:85:ca:13:1b:c6:8b:0a:e9:13:dc:15:01:05:f1:f0:         5e:e4:06:bf:8f:e5:3c:63:a3:a1:0c:b5:7f:e8:52:81:22:28:         dd:70:47:33:72:08:7b:df:f6:a7:f5:a5:38:45:5a:82:26:8a:         d3:f2:1c:be

CN=OBServer  这个是这个证书的 Common Name,后面会用到。

OB 客户端也要申请证书,方法同上。

[root@server062 certs]# openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pemGenerating a 2048 bit RSA private key...+++....................................................................................+++writing new private key to 'client-key.pem'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [XX]:CNState or Province Name (full name) []:ZJLocality Name (eg, city) [Default City]:HZOrganization Name (eg, company) [Default Company Ltd]:YQOrganizational Unit Name (eg, section) []:CACommon Name (eg, your name or your server's hostname) []:OBCLIENTEmail Address []:
Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:aaAA11__An optional company name []:

注意,客户端证书的 Common Name 不一样,后面会用到。

文件发送到 CA 服务器上签名并颁发证书。

[root@server065 certs]# openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey cakey.pem -set_serial 01 -out client-cert.pemSignature oksubject=/C=CN/ST=ZJ/L=HZ/O=YQ/OU=CA/CN=OBCLIENTGetting CA Private KeyYou have new mail in /var/spool/mail/root

最后再次校验以下证书的有效性。

[root@server062 certs]# openssl verify -CAfile ca.pem client-cert.pem                                                                                                                                                                                          client-cert.pem: OK
[root@server063 certs]# openssl verify -CAfile ca.pem server-cert.pemserver-cert.pem: OK

这一步是关键。如果证书验证不过,就是前面生成证书的时候一些信息填写不对。注意服务端和客户端证书中的证书适用的机器名称不要重复。


开启 OBServer 传输加密

OBServer 节点、liboblog、obadmin 等组件的底层通信均依赖 Libeasy 库,因此支持的私钥/证书加载方式均相同(本地文件模式),即将 CA 证书、用户证书、私钥放在 wallet 文件夹下,根据配置项开启时从该目录下读取加载。

  • 首先需要将 ca.pem 和 server-cert.pem 、server-key.pem 文件复制到 OceanBase 所有节点的 /home/admin/oceanbase/wallet/ 文件夹下。

  • 第二步,修改 OceanBase 集群参数 ssl_external_kms_info 。

    如果前面证书文件在有些节点没有复制,这个命令会报错。报错提示如下。

(root@127.1:2883) [oceanbase]> ALTER SYSTEM SET ssl_external_kms_info = '{"ssl_mode":"file"}';ERROR 1210 (HY000): Invalid argument

查看 observer.log 看到提示 CA 证书不存在。

[2024-01-14 19:35:16.114636] WDIAG [LIB] is_accessible (file_directory_utils.cpp:70) [64488][T1_L0_G0][T1][YB420A00003F-00060D7886EFBBDD-0-0] [lt=35][errcode=0] access file failed(errmsg="No such file or directory", file_path="wallet/ca.pem")[2024-01-14 19:35:16.125539] WDIAG [SHARE] ssl_file_mode_config (ob_encrypt_kms.cpp:2293) [64488][T1_L0_G0][T1][YB420A00003F-00060D7886EFBBDD-0-0] [lt=10899][errcode=-4002] not access ssl file(ret=-4002, is_access=false)

或者提示服务器私钥不存在。

[2024-01-14 19:50:56.807125] WDIAG [LIB] is_accessible (file_directory_utils.cpp:70) [64490][T1_L0_G0][T1][YB420A00003F-00060D7888C8B6DD-0-0] [lt=34][errcode=0] access file failed(errmsg="No such file or directory", file_path="wallet/server-key.pem")[2024-01-14 19:50:56.807154] WDIAG [SHARE] ssl_file_mode_config (ob_encrypt_kms.cpp:2293) [64490][T1_L0_G0][T1][YB420A00003F-00060D7888C8B6DD-0-0] [lt=29][errcode=-4002] not access ssl file(ret=-4002, is_access=false)

或者提示服务端证书不存在。

[2024-01-14 19:42:32.761477] WDIAG [LIB] is_accessible (file_directory_utils.cpp:70) [64488][T1_L0_G0][T1][YB420A00003F-00060D7886EFC056-0-0] [lt=32][errcode=0] access file failed(errmsg="No such file or directory", file_path="wallet/server-cert.pem")                                                                                                                                                                                                                                             [2024-01-14 19:42:32.761499] WDIAG [SHARE] ssl_file_mode_config (ob_encrypt_kms.cpp:2293) [64488][T1_L0_G0][T1][YB420A00003F-00060D7886EFC056-0-0] [lt=22][errcode=-4002] not access ssl file(ret=-4002, is_access=false)

最终参数修改成功。

MySQL [oceanbase]> ALTER SYSTEM SET ssl_external_kms_info = '{"ssl_mode":"file"}';Query OK, 0 rows affected (0.18 sec)
MySQL [oceanbase]> show parameters like 'ssl_external_kms_info'\G*************************** 1. row *************************** zone: zone1 svr_type: observer svr_ip: 10.0.0.63 svr_port: 2882 name: ssl_external_kms_info data_type: NULL value: {"ssl_mode":"file"} info: when using the external key management center for ssl, this parameter will store some key management information section: OBSERVER scope: CLUSTER source: DEFAULTedit_level: DYNAMIC_EFFECTIVE1 row in set (0.01 sec)
  • 第三步,指定允许的 SSL 协议最低版本号。

这是 4.2 版本新增的功能。此前的版本没有这个限制。
MySQL [oceanbase]> ALTER SYSTEM SET sql_protocol_min_tls_version = 'TLSv1.1';Query OK, 0 rows affected (0.02 sec)
  • 第四步,配置 MySQL 端口连接使用 SSL 通信。

这里要开启客户端的 SSL 认证,以及设置客户端 SSL 认证白名单。这个白名单名字从客户端证书里提取 Common Name(CN=后面的名字)。
MySQL [oceanbase]> ALTER SYSTEM SET ssl_client_authentication = 'TRUE';Query OK, 0 rows affected (0.02 sec)MySQL [(none)]> alter system set ob_ssl_invited_common_names='OBCLIENT';Query OK, 0 rows affected (0.02 sec)

注意,第二个白名单参数生效级别是租户级别,所以需要针对租户设置。

  • 第五步,设置 RPC 端口连接使用 SSL 客户白名单。

这个参数是个隐含参数,目前功能还是内测中。可以设置整个集群层面,或者针对个别子网或 IP 设置开启。当 OB 集群多机房部署时,可以针对某个机房要求开启 SSL 传输。

MySQL [oceanbase]> ALTER SYSTEM SET _ob_ssl_invited_nodes='10.0.0.0/24';Query OK, 0 rows affected (0.01 sec)
由于 OBServer 之间 TCP 连接都是长连接,因此需要重启 OBServer 后 RPC SSL 加密通信才能开启。如果是单节点 OB 集群环境,就不需要重启了。
  • 第六步,检查 OBServer RPC 通信确实开启了 SSL。

通过视图 GV$OB_SERVERS 可以查看。

MySQL [(none)]> select svr_ip, svr_port,zone, ssl_cert_expired_time, from_unixtime(ssl_cert_expired_time/1000000) from oceanbase.GV$OB_SERVERS;+-----------+----------+-------+----------------------------+----------------------------------------------+| svr_ip    | svr_port | zone  | ssl_cert_expired_time      | from_unixtime(ssl_cert_expired_time/1000000) |+-----------+----------+-------+----------------------------+----------------------------------------------+| 10.0.0.63 |     2882 | zone1 | 2033-11-22 03:11:21.000000 | 1970-08-24 15:32:02.031121                   |+-----------+----------+-------+----------------------------+----------------------------------------------+1 row in set (0.00 sec)

不过要严格的验证 RPC 端口连接使用了 SSL ,OB 集群节点规模至少要有 2 台。这里环境有限就没有验证。官网给出了抓包确认的方法。

  • 第七步,验证 MySQL 直连 OBServer 支持 SSL 。

这里以 SYS 租户为例。首先需要创建单独的用户,开启 SSL 属性。root 用户默认是不要求 SSL,所以已有的连接方式并不会变化。这里也不建议去改 root 连接属性,避免配置错误的时候连 root@sys 都不能登录了。

MySQL [(none)]> create user u_ssl identified by 'abc@ABC#123' require ssl;Query OK, 0 rows affected (0.25 sec)
MySQL [(none)]> grant select on *.* to u_ssl;Query OK, 0 rows affected (0.14 sec)

然后在任意客户端使用 u_ssl 用户连接。如果连接的时候没有指定 SSL 证书和私钥或者证书里的 CN= 名字不在 OB 集群的客户端 SSL 白名单里,这个连接都会失败(提示密码错误)。

[root@server062 certs]# mysql -h10.0.0.63 -uu_ssl@sys -P2881 -p'abc@ABC#123' -c -A oceanbaseERROR 1045 (42000): Access denied for user 'u_ssl'@'xxx.xxx.xxx.xxx' (using password: YES)[root@server062 certs]# mysql -h10.0.0.63 -uu_ssl@sys -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl-cert=client-cert.pem --ssl-key=client-key.pemERROR 1045 (42000): Access denied for user 'u_ssl'@'xxx.xxx.xxx.xxx' (using password: YES)
[admin@server063 wallet]$ mysql -h10.0.0.63 -uroot@sys -P2881 -p'aaAA11__' -c -A oceanbase -e "alter system set ob_ssl_invited_common_names='OBCLIENT' tenant=all;"
[root@server062 certs]# mysql -h10.0.0.63 -uu_ssl@sys -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl-cert=client-cert.pem --ssl-key=client-key.pemWelcome to the MariaDB monitor. Commands end with ; or \g.Your MySQL connection id is 3221661160Server version: 5.7.25 OceanBase 4.2.1.1 (r101010022023110921-5d0b2ec58d7661e382f65d3753b65f3a914f89ec) (Built Nov 9 2023 21:27:01)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(u_ssl@10.0.0.63:2881) [oceanbase]> \s--------------mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 3221661160Current database: oceanbaseCurrent user: u_ssl@10.0.0.62SSL: Cipher in use is ECDHE-RSA-AES256-GCM-SHA384Current pager: stdoutUsing outfile: ''Using delimiter: ;Server: MySQLServer version: 5.7.25 OceanBase 4.2.1.1 (r101010022023110921-5d0b2ec58d7661e382f65d3753b65f3a914f89ec) (Built Nov 9 2023 21:27:01)Protocol version: 10Connection: 10.0.0.63 via TCP/IPServer characterset: utf8mb4Db characterset: utf8mb4Client characterset: utf8mb4Conn. characterset: utf8mb4TCP port: 2881Active --------------
(u_ssl@10.0.0.63:2881) [oceanbase]>

连接成功后即可查看当前连接的 SSL 状态。

业务租户也可以建相应用户和设置客户端 SSL 白名单。不过由于业务通常连接租户都是通过 ODP 节点,而不是直连 OBServer 节点。所以,接下来还需要配置 ODP 传输加密。

ODP 传输加密

ODP 传输加密支持前端连接和后端连接分别使用 SSL 加密。

最简单的情形就是前端连接使用 SSL,后端连接不使用 SSL。这个场景主要是因为 ODP 通常跟 OBServer 节点是部署在同一个服务器的,后端连接相对很安全就没有必要加密。

这种前端连接使用 SSL 只需要修改 ODP 参数 enable_client_ssl 开启客户端 SSL 协议支持。

(root@10.0.0.63:2883) [oceanbase]> alter proxyconfig set enable_client_ssl=true;Query OK, 0 rows affected (0.11 sec)
(root@10.0.0.63:2883) [oceanbase]> show proxyconfig like '%ssl%';+-------------------+-------+--------------------------------------------------------------------+-------------+---------------+| name | value | info | need_reboot | visible_level |+-------------------+-------+--------------------------------------------------------------------+-------------+---------------+| ssl_attributes | | store ssl config to control ssl behavior, works for new connection | false | SYS || enable_server_ssl | False | if enabled, proxy will try best to connect server whith ssl | false | SYS || enable_client_ssl | True | if enabled, proxy will try best to connect client with ssl | false | SYS |+-------------------+-------+--------------------------------------------------------------------+-------------+---------------+3 rows in set (0.00 sec)

这种场景需要关闭 OB 集群的客户端 SSL 认证。并且 OB 租户里用户不需要设置 require ssl 或 x509 。

MySQL [oceanbase]> alter system set ssl_client_authentication=false;Query OK, 0 rows affected (0.02 sec)

以上设置仅针对新的连接生效。客户端连接的时候只需要开启 --ssl 选项即可。

[admin@server063 ~]$ obclient -h127.1 -utpcc@oboracle#obv4 -P2883 -pabc@ABC#123 --sslWelcome to the OceanBase.  Commands end with ; or \g.Your OceanBase connection id is 996616Server version: OceanBase 4.2.1.1 (r101010022023110921-5d0b2ec58d7661e382f65d3753b65f3a914f89ec) (Built Nov  9 2023 21:27:01)Copyright (c) 2000, 2018, OceanBase and/or its affiliates. All rights reserved.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
obclient [TPCC]> \s--------------obclient Ver Distrib 10.4.18-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 996616Current database: TPCCCurrent user: TPCCSSL: Cipher in use is ECDHE-RSA-AES256-GCM-SHA384Current pager: stdoutUsing outfile: ''Using delimiter: ;Server version: OceanBase 4.2.1.1 (r101010022023110921-5d0b2ec58d7661e382f65d3753b65f3a914f89ec) (Built Nov 9 2023 21:27:01)Protocol version: 10Connection: 127.1 via TCP/IPServer characterset: utf8mb4Db characterset: utf8mb4Client characterset: utf8mb4Conn. characterset: utf8mb4TCP port: 2883Protocol: CompressedActive --------------

在 ODP 管理命令入口下,也能看到这个客户端连接使用了 SSL。

(root@proxysys@127.1:2883) [(none)]> show proxysession;+--------------------+---------+---------+----------+------+------------------+-----------+-------------+-------------------+-------------------+-------+-------+-----------+| proxy_sessid       | Id      | Cluster | Tenant   | User | Host             | db        | trans_count | svr_session_count | state             | tid   | pid   | using_ssl |+--------------------+---------+---------+----------+------+------------------+-----------+-------------+-------------------+-------------------+-------+-------+-----------+|                  0 | 2075234 | obdemo  | proxysys | root | 127.0.0.1:51790  | NULL      |           0 |                 0 | MCS_ACTIVE_READER | 13506 | 13485 |         0 || 720576211151204943 |  996616 | obv4    | oboracle | tpcc | 127.0.0.1:50542  | TPCC      |           0 |                 1 | MCS_ACTIVE_READER | 13501 | 13485 |         1 || 720576211151204918 | 1118529 | obv4    | obmysql  | root | 10.212.1.5:55532 | oceanbase |           0 |                 1 | MCS_ACTIVE_READER | 13502 | 13485 |         0 |+--------------------+---------+---------+----------+------+------------------+-----------+-------------+-------------------+-------------------+-------+-------+-----------+3 rows in set (0.00 sec)
第二种情形就是前端连接和后端连接都开启 SSL 。

ODP 是 OceanBase 集群的访问代理,对应用客户端而言,ODP 就是 Server 端。但是对于 OBServer 节点而言,ODP 是客户端。ODP 连接 OBServer 的时候也需要提供客户端证书和私钥。

  • 首先,将文件 CA.pem 、client-cert.pem 和 client-key.pem 文件复制到 OBProxy 工作目录下的 wallet 文件夹(目录名自定义)下。

  • 第二步,登录 ODP 命令行管理入口(root@proxysys 用户),修改 ODP 内部表 proxyconfig.security_config 记录。 

MySQL [(none)]> UPDATE proxyconfig.security_config SET CONFIG_VAL= '{"sourceType" : "FILE", "CA" : "wallet/ca.pem", "publicKey" : "wallet/client-cert.pem", "privateKey" : "wallet/client-key.pem"}' WHERE APP_NAME = 'obproxy' and VERSION = '1';Query OK, 1 row affected (0.01 sec)  
MySQL [(none)]> select * from proxyconfig.security_config;ERROR 4016 (HY000): Ooooooooooooops
MySQL [(none)]> select * from proxyconfig.security_config where app_name='obproxy';+----------------+| CONFIG_VAL |+----------------+| SSL INFO VALID |+----------------+1 row in set (0.00 sec)

注意:这一步设置里的证书写的客户端证书,跟官网文档(写的是服务端证书)是不一样的。

  • 第三步,开启 ODP 的服务端连接(后端连接)的 SSL 支持。

MySQL [(none)]> alter proxyconfig set enable_server_ssl=true;Query OK, 0 rows affected (0.24 sec)
MySQL [(none)]> show proxyconfig like '%enable_%ssl%';+-------------------+-------+-------------------------------------------------------------+-------------+---------------+| name | value | info | need_reboot | visible_level |+-------------------+-------+-------------------------------------------------------------+-------------+---------------+| enable_server_ssl | True | if enabled, proxy will try best to connect server whith ssl | false | SYS || enable_client_ssl | True | if enabled, proxy will try best to connect client with ssl | false | SYS |+-------------------+-------+-------------------------------------------------------------+-------------+---------------+2 rows in set (0.01 sec)

一旦开启了 ODP 后端连接的 SSL 协议,所有经过这个 ODP 产生的新的连接都会起用 SSL。

  • 第四步,OceanBase 集群参数开启客户端 SSL 认证以及各个租户都开启 SSL 白名单。

这一步,误操作风险很大。设置错了后面会导致租户原本的连接失败(原因是导致所有新的会话的 ODP 后端连接失败)。尽管前面介绍过,还是重复一遍。

首先确保每个 OBServer 节点工作目录下的 wallet 文件夹都有文件:ca.pem 、server-cert.pem 、server-key.pem 。然后要确保所有租户的 SSL 白名单都要设置为 ODP 本地目录里的证书里的授予对象(CN= 后面的名字)。

MySQL [oceanbase]> alter system set ob_ssl_invited_common_names='OBCLIENT' tenant=all;Query OK, 0 rows affected (0.03 sec)
MySQL [oceanbase]> alter system set ssl_client_authentication=true;Query OK, 0 rows affected (0.03 sec)

如果设置错了导致无法通过 ODP 登录 OceanBase 集群的 SYS 租户,可以用 root@sys 直连 OBServer节点将参数 ssl_client_authentication 改回 false。

  • 第五步,检验应用连接开启了 SSL。

首先在业务租户 obmysql 下创建用户 ,开启 x509 双向认证。

create user u_x509 identified by 'abc@ABC#123' require x509;grant all privileges on *.* to u_x509;

客户端登录 业务租户 obmysql 。

[root@server062 certs]#  mysql -h10.0.0.63 -uu_x509@obmysql -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl -e "\s" |egrep "SSL"ERROR 1045 (42000): Access denied for user 'u_x509'@'xxx.xxx.xxx.xxx' (using password: YES)[root@server062 certs]#  mysql -h10.0.0.63 -uu_x509@obmysql -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -e "\s" |egrep "SSL"SSL:                    Cipher in use is ECDHE-RSA-AES256-GCM-SHA384[root@server062 certs]#  mysql -h10.0.0.63 -uu_x509@obmysql#obv4 -P2883 -p'abc@ABC#123' -c -A oceanbase --ssl -e "\s" |egrep "SSL"SSL:                    Cipher in use is ECDHE-RSA-AES256-GCM-SHA384[root@server062 certs]#  mysql -h10.0.0.63 -uu_x509@obmysql#obv4 -P2883 -p'abc@ABC#123' -c -A oceanbase --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem  -e "\s" |egrep "SSL"SSL:                    Cipher in use is ECDHE-RSA-AES256-GCM-SHA384
这个示例的最后两个应用连接特点就是 ODP 前端连接和后端连接都使用了 SSL ,并且后端连接还使用了双向认证。
在 OceanBase 集群里,通过查看会话信息,也能看到 OBServer 上的连接是否使用了 SSL 。
SELECT tenant, svr_ip, id, USER, host, db, command, time, state, info, proxy_sessid,user_client_ip, ssl_cipherFROM oceanbase.gv$ob_processlistWHERE tenant IN ('obmysql');


官网文档分析

OceanBase 官网文档在介绍 ODP 传输加密这里步骤是不完整的。这里倒不是刻意在这里挑给官网文档毛病。而是借这个案例来分析 ODP 传输加密失败的原因。

官网文档里在 ODP 内部表里配置的证书是服务端证书和私钥(server-cert.pem 和 server-key.pem),并且后面查询结果还显示证书有效。这个文字截图信息也是对的,推测写文档的人向 ODP 本地文件夹 certs 里复制的是这两个证书。表里配置内容跟实际证书能对得上这一步自然能通过。

但是要测试这个传输加密还需要 OB 集群里设置。虽然文档提到了开启 OBServer 端加密配置,但没有提租户的 SSL 白名单参数设置 ob_ssl_invited_common_names 。查看官网文档 这个参数的说明,提到要配置的是 Client 端的证书信息。

不过写文档的工程师这个配置应该也是跑通了的,其原因很可能就是租户 SSL 白名单里 ob_ssl_invited_common_names 写的是服务端证书的授予对象名字(CN= 后面的名字)。而这个跟他的 OceanBase 集群里的设置是一致的。

不管客户端用什么证书,只要服务端认这个证书就行。证书名字里的 client 和 server 完全都是人定义的。叫什么不重要,是同一个 CA 签发的证书即可。所以官网文档这个说没问题也对。

示例如下。

[admin@server063 wallet]$  mysql -h10.0.0.63 -uu_x509@obmysql -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -e "\s" |egrep "SSL"SSL:                    Cipher in use is ECDHE-RSA-AES256-GCM-SHA384[admin@server063 wallet]$  mysql -h10.0.0.63 -uu_x509@obmysql -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl-ca=ca.pem --ssl-cert=server-cert.pem --ssl-key=server-key.pem -e "\s" |egrep "SSL"                                                       ERROR 1045 (42000): Access denied for user 'u_x509'@'xxx.xxx.xxx.xxx' (using password: YES)[admin@server063 wallet]$ mysql -h10.0.0.63 -uroot@obmysql -P2881 -p'aaAA11__' -c -A oceanbase -e "alter system set ob_ssl_invited_common_names='OBSERVER';"[admin@server063 wallet]$  mysql -h10.0.0.63 -uu_x509@obmysql -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl-ca=ca.pem --ssl-cert=server-cert.pem --ssl-key=server-key.pem -e "\s" |egrep "SSL"SSL:                    Cipher in use is ECDHE-RSA-AES256-GCM-SHA384[admin@server063 wallet]$  mysql -h10.0.0.63 -uu_x509@obmysql -P2881 -p'abc@ABC#123' -c -A oceanbase --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -e "\s" |egrep "SSL"ERROR 1045 (42000): Access denied for user 'u_x509'@'xxx.xxx.xxx.xxx' (using password: YES)
如果你能解释这 5 条命令结果,那说明你彻底掌握了 ODP 传输加密的配置技巧。

总结

最后总结一下 ODP 和 OceanBase 集群节点传输加密功能实践。

  • OceanBase 集群每个 OBServer 节点本地软件工作目录下 wallet 里放置 CA 证书、服务端证书和服务端的私钥。通过内部参数设置 SSL 客户端白名单,然后重启 OceanBase 集群即可实现节点间 RPC 通信用 SSL 。这个参数设置将来应该还会完善。
  • OceanBase 集群的连接有两个端口。一个默认端口 2881 是 给 MySQL 客户端(指用 MySQL 协议)连接,包括 ODP 后端连接和其他直连 OBServer 的连接。另外一个默认端口 2882 是 RPC 连接,主要用于 OBServer 节点间连接以及 ob_admin 工具和 liboblog 组件的连接。这两个连接都支持开启 SSL 连接。
  • 应用客户端跟 ODP 的连接支持 SSL 传输加密,只需要在 ODP 里开启客户端 SSL 认证,然后客户端连接的时候带上 --ssl 或开启类似选项即可。
  • ODP 跟 OBServer 节点之间连接支持 SSL 传输加密,需要在 ODP 里开启服务端 SSL 认证以及配置 ODP 的相关证书路径(用 CA 证书、客户端证书和客户端私钥),还要在 OceanBase 集群里开启客户端 SSL 认证(集群级别)以及 SSL 认证白名单(租户级别,所有租户都要设置 )。
  • OceanBase 租户里还需要创建需要 SSL 认证的相关用户,只有这个用户连接租户才会对连接检查以及应用 SSL。普通的用户依然可以连接租户。不过如果 ODP 后端连接配置了 SSL 加密,普通用户产生的后端连接都会自动应用 SSL 加密。

更多阅读

原文作者:数据库技术闲谈;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2018-11-02

  • 博文量
    156
  • 访问量
    96854