暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

OceanBase 4.2 等保认证 SSL 验收测试

570
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.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 协议最低版本号。

                            这是 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 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 状态。

                                        业务租户也可以建相应用户和设置客户端 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 --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)
                                                复制
                                                第二种情形就是前端连接和后端连接都开启 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_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)
                                                              复制
                                                              如果你能解释这 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 加密。

                                                              更多阅读

                                                              文章转载自数据库技术闲谈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                              评论