天天看點

OceanBase 安全審計之身份鑒别

作者:愛可生

本文主要以 MySQL 和 OceanBase 對比的方式,來介紹 OceanBase(MySQL 模式)安全體系中關于身份鑒别的相關内容,包括身份鑒别機制、使用者名組成、密碼複雜度、密碼過期政策等。

作者:金長龍

愛可生測試工程師,負責 DMP 産品的測試工作。

使用者鑒權

OceanBase 下的身份鑒别機制

OceanBase 資料庫目前隻支援密碼驗證方式,使用的是 MySQL Authentication Protocol(MAPI) 協定進行使用者鑒權。該協定基于用戶端機器上的 MySQL 用戶端帳戶完成身份驗證,要求用戶端具有正确的使用者名和密碼才能連接配接到 OceanBase 伺服器。下面是身份鑒權的具體過程:

OceanBase 安全審計之身份鑒别
  1. 用戶端發起連接配接請求到 OceanBase 伺服器
  2. OceanBase 伺服器發送随機字元串 (Nonce) 給用戶端
  3. 用戶端使用發送來的随機字元串以及正确的使用者名和密碼,進行哈希加密計算
  4. 用戶端将加密後的 Token 發送回 OceanBase 伺服器
  5. OceanBase 伺服器驗證用戶端發送的解碼結果是否正确
  6. 如果解碼結果正确,OceanBase 伺服器允許用戶端連接配接伺服器;否則拒絕連接配接請求
注意: OceanBase 資料庫目前支援的 MySQL 用戶端版本為 5.5、5.6 和 5.7。當使用 MySQL 8.0 用戶端連接配接 OceanBase 時,需要在連接配接指令上加 –default_auth=mysql_native_pasowrd。原因是 MySQL 5.6、MySQL 5.7 的預設加密算法是 mysql_native_password,而 MySQL 8.0 的預設加密算法是 caching_sha2_password。

使用者命名

使用者命名規則

  1. 一個 user 由 user_name 和 host 共同組成,這點 MySQL 和 OceanBase 是一緻的;
  2. MySQL 使用者名不能超過 32 個字元,OceanBase 使用者名不能超過 64 個字元。

下面我們看兩個命名規則的例子。

使用舉例

使用者名的組成

使用者名都是 u1 但 host 不同,代表着三個不同使用者。

create user 'u1'@'%' identified by '123456';
create user 'u1'@'localhost' identified by '123456';
create user 'u1'@'127.0.0.1' identified by '123456';
           

通過 current_user() 函數查詢目前登入使用者,可以看到使用者辨別為 user_name@host。

OceanBase 安全審計之身份鑒别

長度限制

建立使用者時,使用者名長度超出限制,MySQL 和 OceanBase 的報錯一緻,提示 too long for user name。

MySQL

OceanBase 安全審計之身份鑒别

OceanBase

OceanBase 安全審計之身份鑒别

注意:這裡的提示語部分有誤,後續版本修複。

密碼強度評定

為了防止惡意的密碼攻擊,OceanBase 和 MySQL 都提供設定密碼複雜度的相關功能,以此來提升資料庫的安全性。 OceanBase 和 MySQL 分别通過如下的一系列變量限制密碼的複雜度規則。

# OceanBase 4.1
obclient [oceanbase]> SHOW VARIABLES LIKE "validate_password%";
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| validate_password_check_user_name    | on    |
| validate_password_length             | 0     |
| validate_password_mixed_case_count   | 0     |
| validate_password_number_count       | 0     |
| validate_password_policy             | low   |
| validate_password_special_char_count | 0     |
+--------------------------------------+-------+
6 rows in set (0.003 sec)
  
# MySQL 8.x
mysql [localhost:8031] {msandbox} ((none)) > SHOW VARIABLES LIKE "validate_password%";
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password.check_user_name    | ON     |
| validate_password.dictionary_file    |        |
| validate_password.length             | 8      |
| validate_password.mixed_case_count   | 1      |
| validate_password.number_count       | 1      |
| validate_password.policy             | MEDIUM |
| validate_password.special_char_count | 1      |
+--------------------------------------+--------+
7 rows in set (0.00 sec)
           

差異對比

對比項 OceanBase MySQL
安裝方式 自帶系統變量,可以直接配置。 需要先安裝 validate_password 元件(INSTALL COMPONENT 'file://component_validate_password';),然後才可以使用相關變量做密碼限制 >
參數個數 6 個系統變量,沒有變量 validate_password.dictionary_file 7 個系統變量。 其中的 validate_password.dictionary_file 變量僅在 validate_password.policy=STRONG 時才會生效(目前 oceanbase 不支援 STRONG 政策)。
validate_password.policy 變量值 支援配置 LOW、MEDIUM 兩種密碼檢查政策 支援配置 LOW, MEDIUM, STRONG 三種密碼檢查政策;其中 STRONG 就是在 MEDIUM 政策的基礎上增加了字典檔案的檢查。

兩種資料庫的參數預設值大部分都不同,使用中需要注意。

密碼過期政策

主要包括手動設定密碼過期和設定全局的密碼過期政策。

MySQL

支援手動設定使用者密碼過期。

# 手動設定密碼過期
mysql [localhost:8031] {msandbox} ((none)) > alter user 'jeffrey'@'%' PASSWORD EXPIRE;
Query OK, 0 rows affected (0.04 sec)

# 密碼過期後執行語句受限
mysql [localhost:8031] {jeffrey} ((none)) > show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
           

支援設定全局的密碼過期政策:可以使用 default_password_lifetime 系統變量。

OceanBase

目前暫不支援。

登入失敗處理

對于多次登入失敗的使用者,資料庫會鎖定該使用者,以便防止惡意的密碼攻擊,進而保護資料庫,提升資料庫的安全性。

OceanBase

OceanBase 設計了幾個租戶級的參數,用來控制使用者連續錯誤登入的次數以及賬戶的鎖定時間。這是 OceanBase 特有而 MySQL 沒有的。主要是以下三個參數,可以通過指令查詢(SHOW PARAMETERS LIKE "connection_control_%";)。

  • connection_control_failed_connections_threshold:指定使用者連續錯誤登入的次數
  • connection_control_min_connection_delay:達到錯誤登入次數之後鎖定使用者的最小時長
  • connection_control_max_connection_delay:達到錯誤登入次數之後鎖定使用者的最大時長

在每次登入失敗時,OBServer 日志都會有相應的記錄。

[root@31aa8013555f log]# grep "denied" observer.log
[2023-05-04 09:32:18.689329] WDIAG [SERVER] load_privilege_info (obmp_connect.cpp:553) [782][MysqlQueueTh5][T1][Y0-0005FA34D4B800AC-0-0] [lt=11][errcode=-4043] User access denied(login_info={tenant_name:"sys", user_name:"root", client_ip:"127.0.0.1", db:"oceanbase", scramble_str:"?sE@PP"WqS*v7KUJQ8cj"}, ret=-4043)
           

另外也截了一段登入成功時的日志。

[2023-05-23 09:07:52.658015] INFO [SERVER] process (obmp_connect.cpp:369) [12383][MysqlQueueTh1][T1][Y0-0005FBC67C77F146-0-0] [lt=9] MySQL LOGIN(direct_client_ip="127.0.0.1", client_ip=127.0.0.1, tenant_name=sys, tenant_id=1, user_name=u1, host_name=%, sessid=3221576719, proxy_sessid=0, sess_create_time=0, from_proxy=false, from_java_client=false, from_oci_client=true, from_jdbc_client=false, capability=150974085, proxy_capability=49408, use_ssl=true, c/s protocol="OB_2_0_CS_TYPE", autocommit=true, proc_ret=0, ret=0)
           

MySQL

從 MySQL 8.0.19 開始,可以在 create user 和 alter user 語句中使用 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 選項為每個帳戶配置所需的登入失敗次數和鎖定時間。

  • FAILED_LOGIN_ATTEMPTS:指定連續錯誤密碼的次數
  • PASSWORD_LOCK_TIME:達到錯誤登入次數之後的鎖定時長(機關天)

使用舉例

CREATE USER 'u1'@'localhost' IDENTIFIED BY 'password'
  FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;
 
ALTER USER 'u2'@'localhost'
  FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME UNBOUNDED;
           

小結

OceanBase (MySQL 模式)在安全審計的身份鑒别方面與 MySQL 功能基本一緻。

繼續閱讀