一個報錯
在使用客戶端登錄MySQL8.0時,我們經常會遇到下面這個報錯:
ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
網絡上很多帖子教我們將用戶認證插件修改成 mysql_native_password 來解決,事實上這是怎么一回事呢?本文就來探討一二。
caching_sha2_password 簡介
caching_sha2_password 是MySQL 8.0.4引入的一個新的身份驗證插件,它的特點被其命名揭露無疑:
- sha2_password:其實就是 sha256_password,這是 MySQL5.6 就引入的身份驗證插件,其優點是對加鹽密碼進行多輪 SHA256 哈希,以確保哈希轉換更安全。其缺點為它要求使用安全連接或使用 RSA 密鑰對進行密碼交換的未加密連接,因此其身份驗證的效率較低。
- caching:在 sha256_password 的基礎上增加緩存,有緩存的情況下不需要加密連接或 RSA 密鑰對,已達到安全和效率并存。
其實上面這個介紹不太容易懂,下面我們以問答方式來揭開 caching_sha2_password 的面紗。
Q:要求使用安全連接或使用 RSA 密鑰對進行密碼交換的未加密連接是什么意思?
caching_sha2_password 對密碼安全性要求更高,要求用戶認證過程中在網絡傳輸的密碼是加密的:
- 如果是 SSL 加密連接,則使用 SSL 證書和密鑰對來完成 "對稱加密密鑰對(在TSL握手中生成)" 的交換,后續使用“對稱加密密鑰對” 加密密碼和數據。具體見:MySQL:SSL 連接淺析;
- 如果是非 SSL 加密連接,則在連接建立時客戶端使用 MySQL Server 端的 RSA 公鑰加密用戶密碼,Server 端使用 RSA 私鑰解密驗證密碼的正確性,可以防止密碼在網絡傳輸時被窺探。
tips:SSL加密連接會不止會加密用戶密碼,還會加密數據(SQL請求、返回的結果);非加密連接只使用 RSA 密鑰對進行用戶密碼的加密。
Q:未加密連接是怎么使用 RSA 密鑰對進行密碼交換的?
當用戶驗證成功后,會把用戶密碼哈希緩存起來。新連接客戶端發起登錄請求時,MySQL Server 端會判斷是否命中緩存,如果沒有緩存,對于未加密的連接,caching_sha2_password 插件要求連接建立時使用 RSA 進行加密密碼交換,否則報錯,其過程為:
- 客戶端如果擁有服務端的 RSA 公鑰,則使用 --server-public-key-path 選項指定 RSA 公鑰文件;
- 客戶端使用 RSA 公鑰對用戶密碼進行加密,請求連接;
- 服務端使用 RSA 私鑰進行解密,驗證密碼的正確性。
如果客戶端沒有保存服務端的 RSA 公鑰文件,也可以使用 --get-server-public-key 選項從服務器請求公鑰,則在建立連接時,服務端會先將 RSA 公鑰發送給客戶端。
如果 --server-public-key-path、--get-server-public-key 都沒有指定,則會報下面這個經典的錯誤:
[root@172-16-21-5 ~] mysql -h172.16.21.4 -utest -ptestpass --ssl-mode=disable
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
指定 --get-server-public-key 則能成功登錄:
[root@172-16-21-5 ~] mysql -h172.16.21.4 -utest -ptestpass --ssl-mode=disable --get-server-public-key -e "select 1"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---+
| 1 |
+---+
| 1 |
+---+
如果 test 用戶登陸成功,有了緩存,則下次認證時未加密連接不再要求使用 RSA 密鑰對:
[root@172-16-21-5 ~] mysql -h172.16.21.4 -utest -ptestpass --ssl-mode=disable -e "select 1"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---+
| 1 |
+---+
| 1 |
+---+
注意:上述客戶端是指 mysql 默認命令行客戶端,--server-public-key-path、--get-server-public-key 參數也只適用于 mysql 客戶端
Q:RSA 密鑰對保存在哪里?
RSA密鑰對默認保存在MySQL的 datadir 下,用于非 SSL 連接時的密碼加密交換:使用RSA公鑰加密密碼,使用RSA私鑰解密:
private_key.pem RSA公鑰
public_key.pem RSA私鑰
Q:密碼哈希緩存何時失效?
當用戶驗證成功后,密碼哈希會緩存起來,緩存會在以下情況被清理:
- 當用戶的密碼被更改時;
- 當使用 RENAME USER 重命名用戶時;
- 執行 FLUSH PRIVILEGES 時;
- MySQL重啟。
Q:復制用戶使用 caching_sha2_password 插件需要注意什么?
對于MGR,如果設置 group_replication_ssl_mode=DISABLED,則也必須使用下面的變量來指定 RSA 公鑰,否則報錯:
- group_replication_recovery_get_public_key:向服務端請求 RSA 公鑰;
- group_replication_recovery_public_key_path:指定本地 RSA 公鑰文件。
設置一個就行,考慮拷貝 RSA 公鑰到各節點麻煩,建議設置 group_replication_recovery_get_public_key=ON。
對于異步/半同步復制,需要在 change master 命令中指定:MASTER_PUBLIC_KEY_PATH = 'key_file_path'
或 GET_MASTER_PUBLIC_KEY = {0|1}
含義同上,建議:GET_MASTER_PUBLIC_KEY = 1
參考資料
https://dev.mysql.com/blog-archive/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/
https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html