Pluggable Authentication(PAM,即可插拔式認證模塊)是一種高效且靈活的用戶級別的認證方式,廣泛應用于現代操作系統,特別是Linux服務器中。它允許數據庫管理員(DBAs)為MySQL用戶帳戶選擇和更改不同的認證方法。
1 身份驗證插件客戶端/服務器兼容性
可插拔身份驗證使MySQL帳戶在選擇身份驗證方法時具有靈活性,但在某些情況下,由于客戶端和服務器之間的身份驗證插件不兼容,無法建立客戶端連接。
客戶端成功連接到給定服務器上的給定帳戶的一般兼容性原則是,客戶端和服務器都必須支持帳戶所需的身份驗證方法。由于身份驗證方法是由身份驗證插件實現的,因此客戶端和服務器都必須支持帳戶所需的身份驗證插件。
身份驗證插件不兼容可能以各種方式出現。示例:
- 使用5.7.22或更低版本的MySQL 5.7客戶端連接到使用caching_sha2_password進行身份驗證的MySQL 8.0服務器帳戶。這失敗了,因為5.7客戶端無法識別MySQL 8.0中引入的插件。(這個問題在5.7.23版本的MySQL 5.7中得到了解決,當時MySQL客戶端庫和客戶端程序中添加了caching_sha2_password客戶端支持。)
- 使用MySQL 5.7客戶端連接到5.7之前的服務器帳戶,該帳戶使用MySQL_old_password進行身份驗證。失敗的原因有很多。首先,這樣的連接需要--secure-auth=0,這不再是受支持的選項。即使支持該插件,5.7客戶端也無法識別該插件,因為它已在MySQL 5.7中刪除。
- 使用社區分發版的MySQL 5.7客戶端連接到MySQL 5.7 Enterprise服務器帳戶,該帳戶使用僅限Enterprise的LDAP身份驗證插件之一進行身份驗證。此操作失敗,因為社區客戶端沒有訪問企業插件的權限。
一般來說,當在來自同一MySQL分發版的客戶端和服務器之間進行連接時,不會出現這些兼容性問題。當在不同MySQL系列的客戶端和服務器之間建立連接時,可能會出現問題。當MySQL引入新的驗證插件或刪除舊的驗證插件時,這些問題是開發過程中固有的。為了最大限度地減少不兼容的可能性,請定期及時升級服務器、客戶端和連接器。
2 身份驗證插件連接器編寫注意事項
MySQL客戶端/服務器協議存在各種實現。libmysqlclientC API客戶端庫就是一個實現。一些MySQL連接器(通常不是用C編寫的)提供了自己的實現。然而,并不是所有的協議實現都以相同的方式處理插件身份驗證。本節描述了協議實現者應該考慮的身份驗證問題。
在客戶端/服務器協議中,服務器告訴連接客戶端它認為默認的身份驗證插件。如果客戶端使用的協議實現嘗試加載默認插件,而該插件在客戶端不存在,則加載操作失敗。如果默認插件不是客戶端嘗試連接的帳戶實際需要的插件,則這是不必要的失敗。
如果客戶端/服務器協議實現沒有自己的默認身份驗證插件概念,并且總是試圖加載服務器指定的默認插件,則如果該插件不可用,則會失敗并出現錯誤。
為了避免這個問題,客戶端使用的協議實現應該有自己的默認插件,并應將其作為第一選擇(或者,在無法加載服務器指定的默認插件的情況下,返回到該默認插件)。例如:
- 在MySQL 5.7中,libmysqlclient使用MySQL_native_password或通過MySQL_options()的MySQL_default_AUTH選項指定的插件作為默認選項。
- 當5.7客戶端嘗試連接到8.0服務器時,服務器會指定caching_sha2_password作為其默認身份驗證插件,但客戶端仍會根據mysql_native_password或通過mysql_default_AUTH指定的任何內容發送憑據詳細信息。
- 客戶端加載服務器指定的插件的唯一時間是針對更改插件請求,但在這種情況下,它可以是任何插件,具體取決于用戶帳戶。在這種情況下,客戶端必須嘗試加載插件,如果該插件不可用,則錯誤不是可選的。
3 對可插拔身份驗證的限制
“本機身份驗證”是指根據存儲在mysql.user系統表中的密碼進行身份驗證。在實現可插拔身份驗證之前,這與舊的MySQL服務器提供的身份驗證方法相同。“Windows本機身份驗證”是指使用已登錄Windows的用戶的憑據進行身份驗證,由Windows本機驗證插件(簡稱“Windows插件”)實現。
3.1 常規可插拔身份驗證限制
- 連接器/C++:使用此連接器的客戶端只能通過使用本機身份驗證的帳戶連接到服務器。
異常:如果連接器是為了動態(而不是靜態)鏈接到libmysqlclient而構建的,并且如果安裝了當前版本的libmysqlclient,或者連接器是從源代碼重新編譯以鏈接到當前libmysqlclient的,則連接器支持可插式身份驗證。
- 連接器/NET:使用連接器/NET的客戶端可以通過使用本地身份驗證或Windows本地身份驗證的帳戶連接到服務器。
- 連接器/PHP:使用此連接器的客戶端只能通過使用本機身份驗證的帳戶連接到服務器,當使用MySQL PHP本機驅動程序(mysqlnd)進行編譯時。
- Windows本機身份驗證:通過使用Windows插件的帳戶進行連接需要安裝Windows域。如果沒有它,將使用NTLM身份驗證,然后只能進行本地連接;也就是說,客戶端和服務器必須在同一臺計算機上運行。
- 代理用戶:代理用戶支持的范圍是,客戶端可以通過使用實現代理用戶功能的插件(即,可以返回與連接用戶不同的用戶名的插件)驗證的帳戶進行連接。例如,PAM和Windows插件支持代理用戶。mysql_native_password和sha256_password身份驗證插件默認不支持代理用戶,但可以配置為支持代理用戶;請參閱服務器對代理用戶映射的支持。
- 復制:復制副本不僅可以使用使用本機身份驗證的復制用戶帳戶,而且如果所需的客戶端插件可用,還可以通過使用非本機身份證明的復制用戶賬戶進行連接。如果插件內置在libmysqlclient中,則默認情況下它是可用的。否則,插件必須安裝在復制副本一側的由復制副本的plugin_dir系統變量命名的目錄中。
- FEDERATED表:FEDERATED表只能通過使用本機身份驗證的遠程服務器上的帳戶訪問遠程表。
3.2 可插拔身份驗證和第三方連接器
第三方連接器開發人員可以使用以下指南來確定連接器是否準備好利用可插拔身份驗證功能,以及采取哪些步驟使其更符合要求:
- 未對其進行更改的現有連接器使用本機身份驗證,使用該連接器的客戶端只能通過使用本機驗證的帳戶連接到服務器。但是,您應該針對最新版本的服務器測試連接器,以驗證此類連接是否仍然正常工作。
異常:如果連接器動態(而不是靜態)鏈接到libmysqlclient,并且如果安裝了當前版本的libmysqlclient則加載該版本,則連接器可能在不進行任何更改的情況下使用可插入身份驗證。
- 為了利用可插入的身份驗證功能,應該根據當前版本的libmysqlclient重新鏈接基于libmysqlclient的連接器。這使連接器能夠支持通過需要客戶端插件的帳戶進行連接,這些插件現在內置在libmysqlclient中(例如PAM身份驗證所需的明文插件和Windows本機身份驗證所需要的Windows插件)。與當前的libmysqlclient鏈接還使連接器能夠訪問安裝在默認MySQL插件目錄中的客戶端插件(通常是由本地服務器的plugin_dir系統變量的默認值命名的目錄)。
如果連接器動態鏈接到libmysqlclient,則必須確保在客戶端主機上安裝了較新版本的libmysqlclient并且連接器在運行時加載它。
- 連接器支持給定身份驗證方法的另一種方式是直接在客戶端/服務器協議中實現它。Connector/NET使用此方法為Windows本機身份驗證提供支持。
- 如果連接器應該能夠從不同于默認插件目錄的目錄加載客戶端插件,那么它必須為客戶端用戶實現一些指定目錄的方法。這方面的可能性包括命令行選項或環境變量,連接器可以從中獲取目錄名。標準MySQL客戶端程序(如MySQL和mysqladmin)實現了一個--plugin-dir選項。
- 連接器對代理用戶的支持取決于其支持的身份驗證方法是否允許代理用戶。