分享至

簡介

身份驗證與授權是管理和保護 MySQL 伺服器的重要考量。身份驗證(有時縮寫為「authn」)指的是驗證用戶端是否允許以特定使用者身分連線的政策和機制類別。授權(有時縮寫為「authz」)是在身份驗證之後發生的程序,用於判斷帳戶被允許執行的動作。

在本指南中,我們將看看 MySQL 提供的概念和組件,以管理此存取控制系統。我們將討論使用者、角色、身份驗證方法和權限之間的相互作用,它們共同解決了如何控制誰可以在 MySQL 資料庫伺服器上執行哪些操作的問題。

MySQL 如何設定身份驗證與授權?

MySQL 透過許多不同的相關系統來管理其身份驗證與授權需求。廣義來說,其組件部分為

  • 使用者: 使用者是在 MySQL 伺服器上設定的個別帳戶,其功能為身分。這些身分可以與身份驗證方法結合,以允許用戶端以使用者身分連線,並且可以被授予權限,以允許他們存取和控制不同粒度層級的不同資料庫物件。MySQL 中的使用者包含 User 名稱和使用者連線來源的 HostUser 名稱相同但從不同 Host 連線的使用者被視為不同的使用者。
  • 身份驗證方法: 身份驗證方法是判斷是否應允許連線用戶端使用特定使用者帳戶的方式。這些方法通常涉及接受和驗證來自用戶端的密碼,但也提供其他身份驗證方法。
  • 權限: 使用者的功能和存取層級由直接授予他們、透過角色成員資格或透過物件所有權授予的權限定義。這些權限在各種範圍內定義,並針對使用者嘗試的每個動作進行檢查。
  • 角色: 實際上,角色是可應用於使用者的權限集合。將相關的權限群組新增至角色,然後透過角色成員資格指派這些權限可以簡化權限管理。

實際的存取控制程序分為兩個不同的部分。首先,用戶端以特定使用者的身分向伺服器進行身份驗證。之後,每個動作都會根據使用者的授權權限進行檢查,以判斷是否允許或拒絕每個請求。

第 1 部分:身份驗證

MySQL 存取控制系統的第一階段是驗證連線。MySQL 根據以下因素決定是否接受連線請求

  • 您是否可以正確地以您請求的使用者帳戶進行身份驗證
  • 該使用者帳戶是否在系統內被鎖定

如果您連線的使用者未被鎖定,並且您可以正確地進行身份驗證,則 MySQL 會接受連線,並允許您繼續進行存取控制系統的第 2 部分。如果使用者被標記為已鎖定,如果您的身份驗證嘗試失敗,或者如果您提供的使用者無效,則 MySQL 將拒絕連線請求。

為了執行這些功能,MySQL 會查詢其內部 mysql 資料庫中 user 表格內的以下欄位

User

用戶端連線身分的使用者名稱可協助 MySQL 判斷如何驗證使用者。當與下方的 Host 欄位結合時,它會在 MySQL 中形成完整的唯一身分。

mysql.user 表格中,空白的 User 值將符合用戶端提供的任何使用者。但是,當發生這種情況時,在整個會話期間,用戶端將被視為匿名使用者。這對存取控制的第二階段有影響,伺服器將根據匿名使用者而不是用戶端提供的使用者檢查動作。

Host

用戶端連線來源的主機被視為使用者身分的關鍵部分。在 MySQL 中,唯一身分是由使用者名稱和他們連線來源的主機組合而成。

因此,來自 example.comuser1 與來自 test.orguser1 被視為不同。User 欄位和 Host 欄位共同告訴 MySQL 要嘗試驗證哪個帳戶。

plugin

一旦 MySQL 使用 UserHost 判斷要為連線請求檢索的正確記錄後,它就會使用 plugin 欄位來決定如何驗證用戶端。

使用者的 plugin 欄位定義了應用於驗證使用者憑證的身份驗證方法。預設插件 caching_sha2_password 將根據表格中儲存的密碼雜湊版本檢查使用者的密碼。

authentication_string

對於「原生」身份驗證插件(僅使用 mysql.user 表格內資訊驗證使用者的插件),authentication_string 欄位包含用於檢查使用者密碼的字串。大多數時候,這是密碼的雜湊版本。如果原生插件的 authentication_stringmysql.user 表格中為空白,則用戶端不得指定密碼才能成功進行身份驗證。

對於使用外部系統進行身份驗證的插件,authentication_string 通常用於指定外部系統正確驗證使用者所需的其他資訊(例如服務名稱、其他識別資訊等)。

account_locked

此欄位判斷此特定使用者帳戶是否在系統內被鎖定。帳戶可以由資料庫管理員手動鎖定。帳戶必須解除鎖定才能繼續。

判斷 mysql.user 表格中列的優先順序

MySQL 使用上述五個欄位來判斷是否接受連線。但是,在某些情況下,多個條目可能與用戶端的連線相符。例如,用戶端可能未提供主機,或者 mysql.user 表格可能包含沒有使用者的列。MySQL 需要一種方法來建立這些列的優先順序,以判斷如何驗證用戶端。

為此,當伺服器啟動或收到從磁碟重新載入其資訊的訊號時,MySQL 會將 mysql.user 表格中的列讀取到其記憶體中。當它讀取列時,它也會按特定性對它們進行排序,以便表格中的列從最特定到最不特定排序。

首先,MySQL 根據 Host 欄位的特定性對列進行排序。具有由完整網域名稱或 IP 位址組成的 Host 的列會排序到堆疊的最上方,其次是那些在 Host 欄位中使用萬用字元的列(將包含 %(全部符合的萬用字元)的列放在最後,作為最不特定的條目),最後是具有空白 Host 的列。

MySQL 使用 User 欄位作為輔助排序欄位。這表示如果兩列具有相同的 Host 特定性,則具有更特定 User 條目的列將被優先處理。User 欄位中不允許使用萬用字元。

User 欄位包含以下任一項

  • 必須完全符合提供的使用者名稱的字串,
  • 空白欄位,它將符合用戶端提供的任何使用者名稱,但會以匿名使用者身分繼續會話

MySQL 將僅使用 mysql.user 表格中的最多列來驗證用戶端連線。這表示如果身份驗證失敗或錯誤的列符合,它將不會檢查可能正確驗證的替代方案。為了判斷要用於驗證用戶端連線請求的列,MySQL 從排序列表的頂端開始。它依序檢查每一列,並使用它找到的第一個符合用戶端連線的列。

如果您不注意上面描述的排序順序,這可能會產生一些令人驚訝的影響。例如,包含 Host 值但沒有 User 的列將始終優先於包含 User 值但沒有 Host 的列被選取。了解此排序系統將幫助您避免一整類身份驗證問題。

如果您在以特定使用者身分進行身份驗證時遇到問題,請檢查以查看是否有更特定的條目符合。如果您可以連線,但您無法執行您認為您應該能夠執行的動作,請驗證 MySQL 是否允許您以您請求的使用者名稱而不是匿名使用者身分存取,如上所述,這種情況可能會發生。

此命令將印出您目前身份驗證的使用者:

SELECT CURRENT_USER()

第 2 部分:授權

一旦用戶端的憑證通過身份驗證,MySQL 就會建立連線,然後進入存取控制系統的第二部分,以判斷授權。MySQL 授權是一個持續進行的程序,它會根據使用者帳戶的特定權限檢查每個命令。如果命令落在使用者權限的範圍內,則允許該動作。否則,伺服器會拒絕該請求。

不同類型的權限

為了說明為什麼某些權限儲存在這裡,有必要談談 MySQL 中不同類型的權限。

權限範圍

權限可以在不同的範圍指派,這決定了授予權限的影響範圍。某些權限僅在特定範圍內有效,而其他權限可以在不同的範圍指派,具體取決於您希望啟用的粒度。

全域權限是不與特定資料庫綁定的權限。它們在整個 MySQL 伺服器中有效。許多全域權限與系統管理相關,並且與系統管理職責相關聯,而不是直接與資料管理相關聯。

資料庫權限與 MySQL 伺服器內的特定資料庫綁定。在資料庫範圍授予的權限會影響使用者可以對資料庫以及其中包含的任何資料庫物件(例如表格)執行的操作。資料庫權限可以授予特定資料庫,也可以一般授予資料庫。

物件權限讓您可以控制資料庫內的表格、索引等。這些權限可以針對特定物件、特定資料庫內特定類型的所有物件授予,也可以針對整個伺服器內特定類型的所有物件授予。

靜態權限與動態權限

在內部,權限可以分為靜態或動態。

靜態權限內建於伺服器中,無法取消註冊(停用)。無論伺服器上啟用了哪些組件,這些權限始終可用。一般來說,靜態權限通常是基本權限(例如讀取或寫入資料的能力),它們適用於所有或大多數系統。

另一方面,動態權限取決於定義它們的插件或組件的可用性。這些權限可以在執行階段註冊或取消註冊,以影響其可用性。未註冊的權限無法授予,但已授予的權限會在啟動時自動註冊。動態權限始終是全域範圍(適用於整個 MySQL 伺服器)。

權限的定義位置

MySQL 的權限在內部 mysql 系統資料庫中的許多不同表格中定義。其中定義的權限組合將決定使用者相對於動作或資料庫物件的特定權限。mysql 資料庫中的以下表格參與定義權限

  • user:除了定義用於身份驗證的使用者帳戶外,user 表格還定義了每個使用者的靜態全域權限。這些權限適用於整個 MySQL 伺服器,並且不受任何插件或組件可用性的影響。
  • global_grantsglobal_grants 表格定義了每個使用者的動態全域權限。由插件或組件定義的任何權限都將註冊在此表格中。
  • dbdb 表格定義了資料庫層級的權限。db 表格與使用者的 UserHost 值相符,就像 user 表格一樣,但也有一個名為 Db 的欄位,用於定義列的資料庫範圍。
  • tables_privtables_priv 表格以與 db 表格對資料庫執行操作類似的方式定義表格層級的權限。為了啟用表格層級範圍,除了 UserHostDb 之外,還提供了一個名為 Table_name 的欄位。
  • columns_priv:比 tables_priv 表格更進一步的是,columns_priv 表格決定了欄位層級的存取權限。為了增加這種額外的粒度,除了 tables_priv 表格中可用的欄位之外,還包含一個名為 Column_name 的欄位。
  • procs_privprocs_priv 表格定義了執行程序和函式的權限。它使用 UserHostDbRoutine_nameRoutine_type 欄位來限定使用者針對不同類型程序的權限範圍。
  • proxies_privproxies_priv 表格定義了使用者的代理權限。代理允許一個使用者充當另一個使用者,繼承他們的權限。proxies_priv 表格使用 UserHost 欄位來比對使用者,然後使用名為 Proxied_hostProxied_user 的個別欄位來定義比對的使用者可以充當誰。

這些表格的使用者帳戶比對功能與我們稍早描述的 mysql.user 表格讀取到記憶體並排序的方式類似。

若要顯示目前與使用者關聯的授權,您可以輸入

SHOW GRANTS FOR '<user>'@'<host>';

您也可以使用以下命令查看非權限帳戶屬性

SHOW CREATE USER '<user>'@'<host>';

角色

角色也是一個相關組件,也適用於授權程序。角色是權限的命名組合,可以由管理員建立,以簡化權限管理。一旦將一組權限授予角色,您就可以透過將使用者新增為角色的成員,將這些權限授予使用者。

因此,如果您想授予多個使用者在特定表格中插入和更新值的能力,您可以建立具有這些權限的角色。然後,您可以透過從該角色新增或移除使用者來控制誰可以在該表格上插入和更新。這為不同類型的使用者建立特定的已定義存取層級,並有助於確保跨帳戶一致地應用存取層級。

角色對其參與的身份驗證程序複雜性的影響微乎其微。但是,我們在這裡提及它們是因為它們作為一種管理權限的方式非常有用。

結論

身份驗證與授權是 MySQL 安全方法的重要需求。它們共同作為系統的存取控制控制器,透過規範誰可以連線到伺服器、他們可以看到和互動的結構以及他們可以存取的資料來運作。了解這些系統如何互動可以幫助您設定安全的政策,以保護您的資料,同時讓所有合法操作暢行無阻。

關於作者
Justin Ellingwood

Justin Ellingwood

Justin 自 2013 年以來一直撰寫關於資料庫、Linux、基礎架構和開發人員工具的文章。他目前與妻子和兩隻兔子住在柏林。他通常不必以第三人稱寫作,這對所有相關方來說都是一種解脫。