OB 数据库全链路分析案例:租户/用户白名单机制

2023年 10月 26日 90.1k 0

本文分享一篇 OB 租户(实例)白名单和用户白名单运维实践和背后原理。仔细分析后还能发现 OB(MySQL) 跟原生MySQL在白名单方面的不同之处。

1. 问题现象

业务新部署了一个应用,部署在Docker 容器里,访问数据库报错。下面是模拟。

    [root@ora12c ]# mysql -h10.0.0.66 -utpcc@obmysql1#obcedemo -P2883 -pabcABC123-c -A
    ERROR 1227 (42501): Access denied

    报错信息是访问被拒绝。密码并没有问题,在 OB 服务器上是可以正常访问的。测试主机和网络防火墙没有开启。

    2. 问题分析

    推测是租户白名单设置问题。看了当前租户白名单设置值。

      [root@server066 ~]$mysql -h10.0.0.66 -uroot@obmysql1#obcedemo -P2883 -paaAA11__ -c -A oceanbase -s
      mysql: [Warning] Using a password on the command line interface can be insecure.
      (root@10.0.0.66:2883) [oceanbase]> show global variables like '%tcp%';
      Variable_name Value
      ob_tcp_invited_nodes 127.0.0.1,10.212.0.0/16,10.0.0.0/24

      再去看看容器 IP,果然不在白名单里。

        [root@ora12c /]# ifconfig |grep inet -B1
        eth0: flags=4163 mtu 1500
        inet 172.27.0.2 netmask 255.255.0.0 broadcast 172.27.255.255
        --
        lo: flags=73 mtu 65536
        inet 127.0.0.1 netmask 255.0.0.0

        这个容器的宿主机 IP 就是 10.0.0.66 。可见登录的时候,OB判断是容器内的 IP 解决起来也容易,将容器的IP 加到租户白名单里即可。

          set global ob_tcp_invited_nodes='127.0.0.1,10.0.0./24,10.212.0.0/16,172.27.0.0/24';

          如果是白名单设置错误导致 root 用户不能登录了,还可以到 SYS 租户里去对业务租户白名单进行设置。SQL 如下:

            (root@10.0.0.66:2883) [oceanbase]> alter tenant obmysql1 set variables ob_tcp_invited_nodes='127.0.0.1,10.0.0.0/24,10.212.0.0/16,172.27.0.0/24';
            Query OK, 0 rows affected (0.02 sec)

            所以为了避免错误,设置租户白名单的时候一定要把 127.0.0.1 这个地址带上。

            问题到这一步轻易解决了。不过我们再深入看看一些有趣的东西,对理解 OBProxy 和 OB 连接以及相关命令也有些帮助。

            3. 连接探索

            3.1 关于OB 取到这个真实 IP 的功能。

            官方的解释从某个版本后 OB 驱动会在 Connect attribute 里保存客户端的真实 IP 然后 OBServer 在会话连接的时候会读取到这个真实的。这个功能早期版本没有,业务有些 IP 是挂载在负载均衡产品(如F5)的 VIP 后(VIP 原理是 NAT)时,当时 OBServer 没办法读取到应用客户端真实物理 IP,导致租户的白名单只能设置 F5的 VIP所在地址网段。此外,这个对做从应用到 OB 的全链路分析也不是很方便。所以,OB的 JDBC 驱动后来实现这个了。

            不过,这个实际 IP 用于做白名单也面临了新的挑战。随着容器的发展,很多应用都部署在容器里,而容器的 IP 都是内部 IP,在更大的网络范围内是可以重复的。你会惊奇的发现多台物理上的容器可能会有相同的 IP。当 OBServer 取到这个 IP 后,实际上也不好区分到底是哪个物理主机来的 IP。白名单的功能自然就打折扣了。不过这也不是什么大问题,因为网络安全主要还是靠 VLAN 层面的访问规则控制,只要控制好能访问 DB 网段的应用的物理机 IP 网段,整体还是安全的。

            3.2 关于容器的这个内部 IP。

            我这个容器的网络模式是 bridged。使用 docker-compose 部署的。部署脚本如下:

              [root@server066 oracle12c]$cat docker-compose.yml
              # Use postgres/example user/password credentials
              version: '3.1'


              services:
              ora12c-ee:
              container_name: ora12c-ee
              hostname: ora12c
              image: absolutapps/oracle-12c-ee
              ports:
              - 1521:1521
              - 8080:8080
              environment:
              ORACLE_SID: orcl12c
              SERVICE_NAME: orcl12c
              TZ: Asia/Shanghai
              privileged: true
              volumes:
              - ./data:/u01/app/oracle


              deploy:
              resources:
              limits:
              cpus: '8'
              memory: 4G

              我也用了别的容器不是这个方法,但也是 bridged 模式,也出现过在 OB 里取到的宿主机的 IP 而不是容器的 IP。所以这个容器部署方法有什么特别之处我还没有搞清楚。总之,也不是所有的容器上的应用连接 OB 都看到的是容器的 IP。这个如果有朋友知道,欢迎留言指点一下。不胜感激。

              3.3 客户端会话查看命令。

              当客户端连接成功后,使用命令查看一下会话信息。

                [root@ora12c ]# mysql -h10.0.0.66 -utpcc@obmysql1#obcedemo -P2883 -pabcABC123 -c -A tpccdb
                MySQL [(none)]> show processlist;
                +---------+----------+------+------------------+------+-------------+-------------------+-------------------+-------+-------+
                | Id | Tenant | User | Host | db | trans_count | svr_session_count | state | tid | pid |
                +---------+----------+------+------------------+------+-------------+-------------------+-------------------+-------+-------+
                | 1835078 | obmysql1 | root | 172.27.0.2:19934 | NULL | 0 | 1 | MCS_ACTIVE_READER | 29288 | 29254 |
                +---------+----------+------+------------------+------+-------------+-------------------+-------------------+-------+-------+
                1 row in set (0.01 sec)


                MySQL [(none)]> show full processlist;
                +------------+------+----------+-----------------+------+---------+------+--------+-----------------------+-----------+------+
                | Id | User | Tenant | Host | db | Command | Time | State | Info | Ip | Port |
                +------------+------+----------+-----------------+------+---------+------+--------+-----------------------+-----------+------+
                | 3221524316 | root | obmysql1 | 10.0.0.66:31916 | NULL | Query | 0 | ACTIVE | show full processlist | 10.0.0.66 | 2881 |
                +------------+------+----------+-----------------+------+---------+------+--------+-----------------------+-----------+------+
                1 row in set (0.01 sec)

                在 OB 里 show processlist 查看的是客户端侧会话,具体一点就是客户端跟 OBProxy的连接信息。所以 Host 看到的是容器的真实 IP和端口。

                  [root@ora12c ]# netstat -anltp |grep 2883
                  tcp 0 0 172.27.0.2:19934 10.0.0.66:2883 ESTABLISHED 6201/mysql

                  show full processlist 查看的是服务端会话,具体一点就是 OBProxy 跟 OBServer 的连接信息(这也是后端会话,可能有多个,展示的是当前在执行的那个活跃的后端会话。详情看文后参考)。所以,Host 看到的是 OBProxy IP 和本地端口(这说明 OBProxy 原理就是 NAT),而 IP 和 Port 展示的是 OBProxy 后端会话连接到的 OBServer 节点 IP 和端口(默认2881)。

                  这里使用的是 mysql 客户端,跟 OB驱动已经没关系了,推测记录真实 IP 这个是 MySQL 连接协议里就有的能力。

                  为此我们连接一个 原生的MySQL 实例看看。

                    [root@ora12c ]# mysql -h10.0.0.65 -uroot -P3304 -pabcABC123 -c -A mysql
                    MySQL [mysql]> show processlist;
                    +-------+-----------------+------------------+--------------------+------------------+---------+-----------------------------------------------------------------+------------------+
                    | Id | User | Host | db | Command | Time | State | Info |
                    +-------+-----------------+------------------+--------------------+------------------+---------+-----------------------------------------------------------------+------------------+

                    | 48478 | root | 10.0.0.66:46633 | mysql | Query | 0 | init | show processlist |
                    +-------+-----------------+------------------+--------------------+------------------+---------+-----------------------------------------------------------------+------------------+
                    9 rows in set (0.07 sec)

                    show full processlist 跟 show processlist 结果差不多,Host 里是客户端的 IP 和端口,而这里显示的就是容器宿主机的 IP。可见,原生的 MySQL 就没用这个真实的 IP 。

                      [root@server066 ~]$docker exec -it ora12c-ee bin/bash
                      [root@ora12c ]# netstat -anltp |grep 47871
                      tcp 0 0 172.27.0.2:47871 10.0.0.65:3304 ESTABLISHED 6077/mysql

                      MySQL 跟 OB 这个行为的不同,有可能会在带白名单的用户账户的权限管控方面带来一些问题。后面还会分析。

                      3.4 OB 哪些视图还能看到这个真实的 IP。

                      show [full] processlist 命令的数据跟视图 oceanbase.__all_virtual_processlist ( MySQL租户)或 SYS.all_virtual_processlist 。

                      为方便观察,继续在容器客户端里发起会话,执行一个慢查询,便于在 OB 里定位到这个会话。

                        [root@ora12c /]# mysql -h10.0.0.66 -utpcc@obmysql1#obcedemo -P2883 -pabcABC123 -c -A tpccdb
                        MySQL [tpccdb]> select /*+ query_timeout(10000000000) */ sleep(120);

                        另开窗口访问业务租户 root 用户。

                          (root@10.0.0.66:2883) [oceanbase]> SELECT tenant, id, user, host, db, command, state, info, svr_ip, proxy_sessid, user_client_ip FROM oceanbase.__all_virtual_processlist WHERE tenant='obmysql1' and user='TPCC' ORDER BY user_client_ip\G


                          *************************** 1. row ***************************
                          tenant: obmysql1
                          id: 3221551974
                          user: tpcc
                          host: 10.0.0.66:34768
                          db: tpccdb
                          command: Query
                          state: ACTIVE
                          info: select /*+ query_timeout(10000000000) */ sleep(300)
                          svr_ip: 10.0.0.66
                          proxy_sessid: 720576224036062157
                          user_client_ip: 172.27.0.2
                          1 row in set (0.01 sec)

                          可以看到 user_client_ip 里展示的是真实的 IP,跟 show processlist 命令一致。

                          此外,就是SQL审计视图 GV$OB_SQL_AUDIT。

                            (root@10.0.0.66:2883) [oceanbase]> SELECT tenant_name,svr_ip,client_ip,user_client_ip,user_name,query_sql,sid FROM oceanbase.gv$ob_sql_audit WHERE tenant_id=effectiv
                            e_tenant_id() AND user_name='tpcc' AND query_sql LIKE '%sleep%' ORDER BY request_id DESC LIMIT 1\G
                            *************************** 1. row ***************************
                            tenant_name: obmysql1
                            svr_ip: 10.0.0.66
                            client_ip: 10.0.0.66
                            user_client_ip: 172.27.0.2
                            user_name: tpcc
                            query_sql: select /*+ query_timeout(10000000000) */ sleep(120)
                            sid: 3221541701
                            1 row in set (0.61 sec)

                            这两个方法分别适合查看正在运行的SQL(够慢)和已经运行过的 SQL 曾经的真实 IP 信息。不光是这个字段,还有 proxy_sessid 和 sid 分别对应 OBProxy.log 里的 proxy_sessid 和 server_sessid 。也就是用这两个信息中的任意一个 加上 host 或 client_ip 信息就能定位到 OBProxy 的日志里具体的连接会话记录,再通过其中的 cs_id信息可以找到整个会话的记录。

                            具体方法上篇文章介绍了,这里给结果。

                              [2023-10-25 22:43:35.309659] INFO [PROXY.SS] ob_mysql_server_session.cpp:106 [29288][Y0-00007FC6022C52A0] [lt=9] [dc=0] server session born(ss_id=11328, server_ip={
                              10.0.0.66:2881}, cs_id=1835079, proxy_sessid=0, server_type=1)

                              从obproxy.log 看OBProxy 没有去获取真实的 IP,它看到的就是容器的物理机 IP。OBProxy 也不关心这个。如果 OBProxy 有白名单机制,那么白名单就要是应用所在物理机的 IP 了。

                              3.5 登录被租户白名单拒绝时的连接日志。

                              这里查看的是 OBServer.log 。先看连接正常的日志,里面有真实的客户端 IP。

                                [admin@server066 log]$grep "sessid=3221541701" observer.log.20231025225619781| more
                                [2023-10-25 22:43:35.311189] INFO [SERVER] process (obmp_connect.cpp:367) [25203][T1004_MysqlQueu][T1004][Y0-000608828CDC5595-0-0] [lt=50] MySQL LOGIN(direct_client
                                _ip="10.0.0.66", client_ip=172.27.0.2, tenant_name=obmysql1, tenant_id=1004, user_name=tpcc, host_name=%, sessid=3221541701, proxy_sessid=720576224036062140, sess_cr
                                eate_time=0, from_proxy=true, from_java_client=false, from_oci_client=false, from_jdbc_client=false, capability=547333773, proxy_capability=916303, use_ssl=false, c/
                                s protocol="OB_2_0_CS_TYPE", autocommit=true, proc_ret=0, ret=0)

                                这里就抓取了一条日志。当登录被白名单拒绝的适合,也是这条日志提示了关键信息。

                                  [admin@server066 log]$cat observer.log |grep ip_white
                                  [2023-10-25 23:10:38.116743] WDIAG [SHARE.SCHEMA] is_in_white_list (ob_schema_struct.cpp:10692) [25202][T1004_MysqlQueu][T1004][Y0-000608828D5C5596-0-0] [lt=34][errcode=0] client ip is not in ip_white_list(client_ip=172.27.0.2, orig_ip_white_list=127.0.0.1,10.0.0./24,10.212.0.0/16)
                                  [2023-10-25 23:10:38.116776] WDIAG [SERVER] verify_ip_white_list (obmp_connect.cpp:1915) [25202][T1004_MysqlQueu][T1004][Y0-000608828D5C5596-0-0] [lt=35][errcode=-5036] client is not invited into this tenant(ret=-5036)
                                  [2023-10-25 23:10:38.116803] WDIAG [SERVER] verify_connection (obmp_connect.cpp:1724) [25202][T1004_MysqlQueu][T1004][Y0-000608828D5C5596-0-0] [lt=27][errcode=-5036] failed to verify_ip_white_list(ret=-5036)

                                  这个连接是在 OBServer 里被拒绝的,它在 OBProxy 里是连接建立成功了(客户端会话)。可以通过日志确认。

                                    [admin@server066 log]$cat obproxy.log |grep cs_id=1835082 |more
                                    [2023-10-25 22:48:09.637217] INFO [PROXY.CS] ob_mysql_client_session.cpp:370 [29288][Y0-00007FC60479F420] [lt=21] [dc=0] client session born(cs_id=1835082, proxy_se
                                    ssid=0, is_local_connection=false, client_vc=0x7fc604798920, client_fd=64, client_addr="172.27.0.2:22786")
                                    [2023-10-25 22:48:09.637250] INFO [PROXY.CS] ob_mysql_client_session.cpp:241 [29288][Y0-00007FC60479F420] [lt=13] [dc=0] Starting new transaction using sm(cs_id=183
                                    5082, get_transact_count()=0, sm_id=6805)
                                    [2023-10-25 22:48:09.639700] INFO [PROXY.SS] ob_mysql_server_session.cpp:106 [29288][Y0-00007FC60479F420] [lt=17] [dc=0] server session born(ss_id=11551, server_ip=
                                    {10.0.0.66:2881}, cs_id=1835082, proxy_sessid=0, server_type=1)
                                    [2023-10-25 22:48:09.639812] INFO [PROXY.TXN] ob_mysql_transact.cpp:4518 [29288][Y0-00007FC60479F420] [lt=23] [dc=0] succ to set proxy_sessid(cs_id=1835082, proxy_s
                                    essid=720576224036062157, server_ip={10.0.0.66:2881}, ss_id=11551, server_sessid=3221551974, is_proxy_mysql_client=false, ss_fd=100, client_addr="172.27.0.2:22786")
                                    [2023-10-25 23:10:19.179553] INFO [PROXY.SS] ob_mysql_server_session.cpp:190 [29288][Y0-00007FC60479F420] [lt=179] [dc=0] server session is closing(ss_id=11551, ser
                                    ver_sessid=3221551974, server_ip={10.0.0.66:2881}, cs_id=1835082, proxy_sessid=720576224036062157)
                                    [2023-10-25 23:10:19.179658] INFO [PROXY.TXN] ob_mysql_transact.cpp:5441 [29288][Y0-00007FC60479F420] [lt=14] [dc=0] [ObMysqlTransact::handle_server_connection_brea
                                    k](client_ip={172.27.0.2:22786}, server_ip={10.0.0.66:2881}, cs_id=1835082, proxy_sessid=720576224036062157, ss_id=0, server_sessid=0, sm_id=6805, proxy_user_name=tp
                                    cc@obmysql1#obcedemo, database_name=tpccdb, server_state="INTERNAL_ERROR", request_cmd="Quit", sql_cmd="Quit", sql=)
                                    [2023-10-25 23:10:19.179899] INFO [PROXY.CS] ob_mysql_client_session.cpp:94 [29288][Y0-00007FC60479F420] [lt=105] [dc=0] client session destroy(cs_id=1835082, proxy
                                    _sessid=720576224036062157, client_vc=NULL)

                                    研究这个日志目的是了解当被租户白名单拒绝的连接在 OBProxy 里的日志内容特点。

                                    3.6 MySQL 实例用户白名单原理

                                    原生 MySQL有个功能就是创建用户时指定允许的访问IP 访问来源。

                                      grant all privileges on tpccdb.* to tpcc2@'10.0.0.%';

                                      在容器里登录 MySQL,连接是没有问题。但是连接OB(MySQL)实例,连接又被拒绝了。

                                        [root@ora12c /]# mysql -h10.0.0.66 -utpcc2@obmysql1#obcedemo -P2883 -pabcABC123 -c -A tpccdb
                                        ERROR 1045 (42000): Access denied for user 'tpcc2'@'xxx.xxx.xxx.xxx' (using password: YES)

                                        我们现在知道这个是真实IP不是 10.0.0.66的原因。先看看 OBProxy.log 里记录(先通过关键字 tpcc2 找到 cs_id,然后根据 cs_id 查完整的会话日志。

                                          [admin@server066 log]$cat obproxy.log|grep "cs_id=1835093"
                                          [2023-10-26 07:11:27.997170] INFO [PROXY.CS] ob_mysql_client_session.cpp:370 [29288][Y0-00007FC6022C34E0] [lt=15] [dc=0] client session born(cs_id=1835093, proxy_sessid=0, is_local_connection=false, client_vc=0x7fc6022bcbe0, client_fd=91, client_addr="172.27.0.2:15704")
                                          [2023-10-26 07:11:27.997270] INFO [PROXY.CS] ob_mysql_client_session.cpp:241 [29288][Y0-00007FC6022C34E0] [lt=71] [dc=0] Starting new transaction using sm(cs_id=1835093, get_transact_count()=0, sm_id=13083)
                                          [2023-10-26 07:11:28.000441] INFO [PROXY.SS] ob_mysql_server_session.cpp:106 [29288][Y0-00007FC6022C34E0] [lt=40] [dc=0] server session born(ss_id=21410, server_ip={10.0.0.66:2881}, cs_id=1835093, proxy_sessid=0, server_type=1)
                                          [2023-10-26 07:11:28.000568] INFO [PROXY.TXN] ob_mysql_transact.cpp:4518 [29288][Y0-00007FC6022C34E0] [lt=25] [dc=0] succ to set proxy_sessid(cs_id=1835093, proxy_sessid=720576224036062844, server_ip={10.0.0.66:2881}, ss_id=21410, server_sessid=3221632702, is_proxy_mysql_client=false, ss_fd=96, client_addr="172.27.0.2:15704")
                                          [2023-10-26 07:11:28.063295] INFO [PROXY.SS] ob_mysql_server_session.cpp:190 [29288][Y0-00007FC6022C34E0] [lt=121] [dc=0] server session is closing(ss_id=21410, server_sessid=3221632702, server_ip={10.0.0.66:2881}, cs_id=1835093, proxy_sessid=720576224036062844)
                                          [2023-10-26 07:11:28.063336] INFO [PROXY.CS] ob_mysql_client_session.cpp:94 [29288][Y0-00007FC6022C34E0] [lt=15] [dc=0] client session destroy(cs_id=1835093, proxy_sessid=720576224036062844, client_vc=NULL)

                                          可以看到,客户端会话建立成功,服务端会话建立成功后就立即关闭了。根据服务端地址去查看 OBServer.log 。

                                            [admin@server066 log]$cat observer.log.20231026071313056 |grep 3221632702
                                            [2023-10-26 07:11:28.000447] INFO [RPC.OBMYSQL] sm_conn_build_handshake (obsm_conn_callback.cpp:104) [27391][sql_nio0][T0][Y0-0000000000000000-0-0] [lt=89] new mysql sessid created(conn.sessid_=3221632702, support_ssl=false)
                                            [2023-10-26 07:11:28.000542] INFO [RPC.OBMYSQL] init (obsm_conn_callback.cpp:121) [27391][sql_nio0][T0][Y0-0000000000000000-0-0] [lt=37] sm conn init succ(conn.sessid_=3221632702, sess.client_addr_="10.0.0.66:27686")
                                            [2023-10-26 07:11:28.000572] INFO [RPC.OBMYSQL] do_accept_one (ob_sql_nio.cpp:924) [27391][sql_nio0][T0][Y0-0000000000000000-0-0] [lt=23] accept one succ(*s={this:0x7fa5982d9230, session_id:3221632702, trace_id:Y0-0000000000000000-0-0, sql_handling_stage:-1, sql_initiative_shutdown:false, fd:199, err:0, last_decode_time:0, last_write_time:1698275488000540, pending_write_task:{buf:null, sz:0}, need_epoll_trigger_write:false, consume_size:0, pending_flag:0, may_handling_flag:true, handler_close_flag:false})
                                            [2023-10-26 07:11:28.061828] INFO [SERVER] free_session (obmp_base.cpp:312) [25199][T1004_MysqlQueu][T1004][Y0-0000000000000000-0-0] [lt=19] free session successfully(ctx={has_inc_active_num:false, tenant_id:1004, sessid:3221632702, proxy_sessid:720576224036062844})
                                            [2023-10-26 07:11:28.061850] INFO [SERVER] free_session (obmp_base.cpp:320) [25199][T1004_MysqlQueu][T1004][Y0-0000000000000000-0-0] [lt=20] mark session id unused(sessid=3221632702)
                                            [2023-10-26 07:11:28.061870] WDIAG [SERVER] disconnect (obmp_packet_sender.cpp:761) [25199][T1004_MysqlQueu][T1004][Y0-0000000000000000-0-0] [lt=14][errcode=0] server close connection(sessid=3221632702, proxy_sessid=720576224036062844, stack="0x1061068c 0x8bd468a 0x8bac282 0x8bb97d9 0x111d1b5f 0x111cbeff 0x111cce29 0x111cd6a9 0x108a2121 0x1089e30f 0x7fa64f43bea5 0x7fa64f164b0d")
                                            [2023-10-26 07:11:28.061884] WDIAG [SERVER] get_session (obmp_packet_sender.cpp:527) [25199][T1004_MysqlQueu][T1004][Y0-0000000000000000-0-0] [lt=11][errcode=-4018] get session fail(ret=-4018, sessid=3221632702, proxy_sessid=720576224036062844)
                                            [2023-10-26 07:11:28.061902] INFO [SERVER] process (obmp_connect.cpp:367) [25199][T1004_MysqlQueu][T1004][Y0-0000000000000000-0-0] [lt=8] MySQL LOGIN(direct_client_ip="10.0.0.66", client_ip=172.27.0.2, tenant_name=obmysql1, tenant_id=1004, user_name=tpcc2, host_name=xxx.xxx.xxx.xxx, sessid=3221632702, proxy_sessid=720576224036062844, sess_create_time=0, from_proxy=true, from_java_client=false, from_oci_client=false, from_jdbc_client=false, capability=547333773, proxy_capability=916303, use_ssl=false, c/s protocol="OB_2_0_CS_TYPE", autocommit=false, proc_ret=-4043, ret=0)
                                            [2023-10-26 07:11:28.062038] WDIAG [RPC.OBMYSQL] push_close_req (ob_sql_nio.cpp:730) [27391][sql_nio0][T0][Y0-0000000000000000-0-0] [lt=9][errcode=-4015] close sql sock by user req(*s={this:0x7fa5982d9230, session_id:3221632702, trace_id:Y0-0000000000000000-0-0, sql_handling_stage:256, sql_initiative_shutdown:true, fd:199, err:5, last_decode_time:1698275488000719, last_write_time:1698275488062032, pending_write_task:{buf:null, sz:0}, need_epoll_trigger_write:false, consume_size:304, pending_flag:1, may_handling_flag:true, handler_close_flag:false})
                                            [2023-10-26 07:11:28.062071] INFO [RPC.OBMYSQL] on_disconnect (obsm_conn_callback.cpp:248) [27391][sql_nio0][T0][Y0-0000000000000000-0-0] [lt=28] kill and revert session(conn.sessid_=3221632702, proxy_sessid=720576224036062844, server_id=1, ret=0)
                                            [2023-10-26 07:11:28.062081] INFO [RPC.OBMYSQL] handle_pending_destroy_list (ob_sql_nio.cpp:820) [27391][sql_nio0][T0][Y0-0000000000000000-0-0] [lt=9] can close safely, do destroy(*s={this:0x7fa5982d9230, session_id:3221632702, trace_id:Y0-0000000000000000-0-0, sql_handling_stage:256, sql_initiative_shutdown:true, fd:199, err:5, last_decode_time:1698275488000719, last_write_time:1698275488062032, pending_write_task:{buf:null, sz:0}, need_epoll_trigger_write:false, consume_size:304, pending_flag:1, may_handling_flag:false, handler_close_flag:false})
                                            [2023-10-26 07:11:28.062103] INFO  [RPC.OBMYSQL] destroy (obsm_conn_callback.cpp:223) [27391][sql_nio0][T0][Y0-0000000000000000-0-0] [lt=12] connection close(sessid 3221632702, proxy_sessid=720576224036062844, tenant_id=1004, server_id=1, from_proxy=true, from_java_client=false, c/s protocol="OB_2_0_CS_TYPE", is_need_clear_sessid_=true, is_sess_alloc_=true, ret=0, trace_id=Y0-0000000000000000-0-0, conn.pkt_rec_wrapper_=[start_pkt_pos_:0, cur_pkt_pos_:2, pkt_rec[0]:{send:obp_mysql_header_{len_:83, seq_:3}, pkt_name:"PKT_ERR", obp_mysql_header_.is_send_:1}, pkt_rec[1]:{send:obp_mysql_header_{len_:12, seq_:4}, pkt_name:"PKT_OKP", obp_mysql_header_.is_send_:1}], disconnect_state=0)

                                            其中 MySQL Login 那句日志提示了真实 IP(client_ip:172.27.0.2) 返回 -4043错误。

                                              ERROR 1045 (42000) : Access denied for user '%.*s'@'%.*s' (using password: %s)
                                              OceanBase 错误码:4043


                                              兼容 MySQL 错误码:1045

                                              这个错误码就是 MySQL的 1045 。其实就是权限表里查不到这个 IP(client_ip:172.27.0.2) 的匹配记录。解决办法就是再按这个IP创建一个同名和密码相同的用户即可。由于多个白名单要创建多个用户匹配,MySQL 的这个用法实际生产可能用的也不多。

                                              4. 总结

                                              OB的租户白名单和MySQL租户的用户白名单功能会取客户端的真实 IP,这个对全链路诊断有很大帮助,对数据访问安全有一定作用。严格的数据库安全要结合网络 VLAN 访问规则、租户白名单一起设置。OB的 MySQL 租户的用户白名单其原理跟原生 MySQL 有一定区别,所以创建用户的时候不能完全按原来 MySQL 的做法。

                                              更多阅读请参考:

                                              • OBCE V3 培训实验:应用到数据库全链路分析(上)

                                              • OBCE V3 培训实验:应用到数据库全链路分析(下)

                                              相关文章

                                              Oracle如何使用授予和撤销权限的语法和示例
                                              Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
                                              下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
                                              社区版oceanbase安装
                                              Oracle 导出CSV工具-sqluldr2
                                              ETL数据集成丨快速将MySQL数据迁移至Doris数据库

                                              发布评论