首先,了解 OceanBase 所有的连接原理以及理论上确认是否支持 SSL 传输加密。
第二,准备 SSL 用的 CA 证书和私钥、服务器和客户端的证书等。 第三,配置 OB 集群和 ODP(OBProxy)开启 SSL 认证以及创建相关数据库用户。 第四,应用客户端开启 SSL 连接 OB 集群并多个环节验证连接确实开启了 SSL 。

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.pem
You are about to be asked to enter information that will be incorporated
into 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 blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:ZJ
Locality Name (eg, city) [Default City]:HZ
Organization Name (eg, company) [Default Company Ltd]:OB
Organizational Unit Name (eg, section) []:CA
Common Name (eg, your name or your server's hostname) []:OBCA
Email Address []:
复制
OB 集群端也需要生成证书。
这里不需要每台节点都去申领证书,共用一个证书即可。
第一步,生成服务器端私钥和证书签名请求文件。
[root@server063 ~]# openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem
Generating 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 incorporated
into 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 blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:ZJ
Locality Name (eg, city) [Default City]:HZ
Organization Name (eg, company) [Default Company Ltd]:YQ
Organizational Unit Name (eg, section) []:CA
Common Name (eg, your name or your server's hostname) []:OBSERVER
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A 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.pem
Signature ok
subject=/C=CN/ST=ZJ/L=HZ/O=YQ/OU=CA/CN=OBSERVER
Getting CA Private Key
You have new mail in var/spool/mail/root
复制
然后将签名后的证书发回到 OBServer 服务器上。
第三步,查看经 CA 签名后的服务端证书。
[root@server063 certs]# openssl x509 -in server-cert.pem -noout -text
Certificate:
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.pem
Generating 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 incorporated
into 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 blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:ZJ
Locality Name (eg, city) [Default City]:HZ
Organization Name (eg, company) [Default Company Ltd]:YQ
Organizational Unit Name (eg, section) []:CA
Common Name (eg, your name or your server's hostname) []:OBCLIENT
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A 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.pem
Signature ok
subject=/C=CN/ST=ZJ/L=HZ/O=YQ/OU=CA/CN=OBCLIENT
Getting CA Private Key
You 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.pem
server-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: DEFAULT
edit_level: DYNAMIC_EFFECTIVE
1 row in set (0.01 sec)
复制
第三步,指定允许的 SSL 协议最低版本号。
MySQL [oceanbase]> ALTER SYSTEM SET sql_protocol_min_tls_version = 'TLSv1.1';
Query OK, 0 rows affected (0.02 sec)
复制
第四步,配置 MySQL 端口连接使用 SSL 通信。
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 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 oceanbase
ERROR 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.pem
ERROR 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.pem
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3221661160
Server 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: 3221661160
Current database: oceanbase
Current user: u_ssl@10.0.0.62
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.2.1.1 (r101010022023110921-5d0b2ec58d7661e382f65d3753b65f3a914f89ec) (Built Nov 9 2023 21:27:01)
Protocol version: 10
Connection: 10.0.0.63 via TCP/IP
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4
TCP port: 2881
Active --------------
(u_ssl@10.0.0.63:2881) [oceanbase]>
复制
连接成功后即可查看当前连接的 SSL 状态。
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 --ssl
Welcome to the OceanBase. Commands end with ; or \g.
Your OceanBase connection id is 996616
Server 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: 996616
Current database: TPCC
Current user: TPCC
SSL: Cipher in use is ECDHE-RSA-AES256-GCM-SHA384
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: OceanBase 4.2.1.1 (r101010022023110921-5d0b2ec58d7661e382f65d3753b65f3a914f89ec) (Built Nov 9 2023 21:27:01)
Protocol version: 10
Connection: 127.1 via TCP/IP
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4
TCP port: 2883
Protocol: Compressed
Active --------------
复制
在 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)
复制
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
复制
SELECT tenant, svr_ip, id, USER, host, db, command, time, state, info, proxy_sessid,user_client_ip, ssl_cipher
FROM oceanbase.gv$ob_processlist
WHERE 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)
复制
总结
最后总结一下 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 加密。