簡介
使用者管理是任何希望管理 MySQL 資料庫系統的人員最重要的職責之一。建立、變更和刪除使用者帳戶,以最佳方式呈現您環境中的使用者和服務,有助於為鎖定存取權限、限制變更範圍,以及實作修改的稽核與問責制奠定基礎。
在本指南中,我們將討論如何在 MySQL 中管理使用者帳戶。首先,我們將討論 MySQL 中有效使用者的定義,並向您展示如何向系統新增其他使用者。接著,我們將討論如何為每位使用者設定身分驗證,以及系統如何從一系列可能性中選擇身分驗證選項。我們將繼續討論如何變更現有使用者、如何使用您建立的帳戶登入,以及如何刪除您不再需要的使用者。
先決條件
若要遵循本指南,您需要一個具有適當權限的 MySQL 伺服器帳戶。
我們將使用的指令
若要在 MySQL 中建立、修改和刪除使用者,您需要的核心指令如下:
CREATE USER
:建立新的使用者帳戶ALTER USER
:變更現有使用者帳戶DROP USER
:移除現有使用者帳戶
必要權限
若要執行上述指令,您需要使用具有 CREATE USER
權限的帳戶登入 MySQL。CREATE USER
權限允許您建立、修改、刪除和重新命名使用者,以及其他動作。我們也需要在 mysql
資料庫上擁有 SELECT
權限,才能查看有關現有使用者的資訊。
依偏好順序,您應該使用以下帳戶登入:
- 具有
CREATE USER
權限和mysql
資料庫上的SELECT
權限的受限帳戶 - 在 MySQL 中具有完整權限的
root
或管理員使用者
了解 MySQL 如何定義與解讀使用者帳戶
在我們開始建立新帳戶之前,先花一些時間熟悉 MySQL 用於建立和參照使用者的各種方法會很有幫助。您也需要熟悉 MySQL 的身分驗證演算法,才能了解它將使用哪個使用者帳戶來驗證連線。
MySQL 的使用者帳戶語法是什麼?
在 MySQL 中,使用者帳戶由兩個獨立的資訊組成,並以 at 符號 (@) 連接:
- 使用者名稱
- 使用者連線來源的主機
一般來說,系統上的使用者帳戶看起來會像這樣:
'<user>'@'<host>'
單引號可用於個別包裝使用者帳戶的使用者和主機元件,如上所示。如果其中一個元件包含其他情況下會被誤解的字元,則有時是必要的。一般來說,為了明確起見,始終建議新增它們。
因此,在 MySQL 中,完整帳戶名稱需要某種主機,例如 'john'@'localhost'
,而不是只有一個名為 'john'
的帳戶。這表示系統上可能有多個 'john'
帳戶,只要它們來自不同的網域,MySQL 就會將它們視為唯一帳戶。
話雖如此,可以定義沒有使用者或主機元件的使用者帳戶,但您必須了解重要的意涵。
您可以使用空字串來定義沒有使用者值的使用者帳戶:
''@'<host>'
例如,您可以將使用者建立為 ''@'localhost'
。此使用者將比對從本機電腦連線的任何使用者名稱。
同樣地,您可以擁有比對任何主機的使用者帳戶。對於主機值,您將使用 %
萬用字元,而不是使用空字串,如下所示:
'<user>'@'%'
例如,如果您建立 'john'@'%'
,該帳戶將比對從任何主機連線的 'john'
使用者。
MySQL 如何驗證使用者身分?
了解 MySQL 實際如何處理每個身分驗證請求非常重要,以避免因合理但錯誤的假設而導致常見的身分驗證問題。這在我們的 MySQL 身分驗證與授權簡介文章中已深入討論。
在驗證連線請求時,MySQL 會使用其內部 mysql
資料庫的 user
表格中的多個欄位,以決定是否允許連線。MySQL 將最多使用一個使用者帳戶記錄來嘗試驗證連線。這表示如果有多個帳戶可以比對連線,MySQL 需要一種方法來決定要使用哪個使用者帳戶。
MySQL 的使用者身分驗證演算法在伺服器啟動時開始運作。啟動時,MySQL 會將整個 mysql.user
表格載入記憶體。每當使用一般 MySQL 指令建立使用者帳戶時,它也會執行此操作。在載入表格時,它會將項目從最高優先順序到最低優先順序排序。
MySQL 使用 Host
欄位作為主要排序欄位,並優先處理具有更具體值的結果。因此,常值會排序到頂端作為最高優先順序,而使用萬用字元(如 %
)的常值則排序到底端。最後的項目是那些只包含 %
而沒有其他字元的項目,然後是主機完全空白的項目。
對於具有相同 Host
值的任何項目,User
欄位會用作次要排序欄位。再一次,更精確的比對會優先處理。由於 User
欄位無法使用萬用字元,因此除了具有空白 User
值的項目外,所有項目都處於同等地位。這些項目會排序到底端。如果選取任何具有空白 User
值的項目,則使用者將驗證為「匿名使用者」,這通常等於沒有任何權限。
現在,每當發出連線請求時,MySQL 都會從頂端到底端瀏覽其記憶體中的排序表格。它會使用找到的第一個項目來驗證使用者身分,無論是否有其他項目也符合比對條件。如果用戶端無法使用該項目定義的方法進行身分驗證,則連線將失敗,並且不會檢查其他項目。
在 MySQL 使用者帳戶定義中不包含使用者或主機的意涵是什麼?
由於 MySQL 的身分驗證演算法,如果您在建立沒有使用者或主機元件的使用者帳戶時不小心,可能會出現問題。這是因為 MySQL 決定要使用哪個記錄來驗證您的身分的方式可能不直觀且令人驚訝。
例如,如果使用者使用空白字串作為使用者部分向 MySQL 驗證身分,MySQL 會將他們視為「匿名使用者」,直到工作階段結束。通常,匿名使用者幾乎沒有權力,而且連線後幾乎無法執行任何操作。即使在使用不同的使用者帳戶嘗試驗證身分時,也可能會意外地驗證為匿名使用者。
對於使用者帳戶使用萬用字元主機的挑戰是,包含主機值的其他使用者帳戶可以輕鬆地遮蔽或使使用萬用字元的使用者帳戶無法使用。
例如,如果您有一個定義為 'emily'@'%'
的使用者帳戶,您可能會期望能夠從任何主機向 'emily'
驗證身分。但是,如果您有一個使用者帳戶,其使用者空白但主機值與 'emily'
連線來源的主機相符,則 MySQL 將改為使用該帳戶進行身分驗證(導致如上所述的匿名使用者登入)。
因此,舉例來說,MySQL 將以下帳戶排序為以下順序:
優先順序 | MySQL 帳戶 | 註解 |
---|---|---|
1 | 'emily'@'localhost' 和 'emily'@'example.com' | 這些具有相同的優先順序,這沒關係,因為它們中只有一個可能符合連線。 |
2 | ''@'localhost' 和 ''@'example.com' | 這兩個項目再次具有相同的優先順序。由於它們沒有使用者元件,但它們確實具有常值主機元件,因此它們會放置在具有精確主機值的項目的底部。 |
3 | 'emily'@'%.example.com' | 此項目在其主機元件中具有萬用字元,因此其優先順序低於具有精確主機值的項目。 |
4 | ''@'%.example.com' | 此項目與主機值中具有萬用字元的項目分組在一起。由於它沒有使用者元件,因此位於此群組的底部。 |
5 | 'emily'@'%' | 此項目的主機值僅由萬用字元組成。由於它比對任何主機,因此優先順序非常低。 |
7 | ''@'%' | 此項目可用於將來自任何主機的任何使用者驗證為匿名使用者。它的優先順序極低,因為它比對任何連線。 |
6 | 'emily'@'' | 此項目具有完全空白的主機值,其優先順序甚至低於僅包含萬用字元主機的主機。 |
8 | ''@'' | 這是最低可能的優先順序使用者。它不包含任何主機資訊,因此在主機排序期間放置在最後。由於它也包含空白使用者,因此放置在此群組中其他項目的下方。與所有沒有使用者的項目一樣,使用此項目驗證身分的連線將以匿名使用者身分登入。 |
如何建立使用者?
現在您已經了解 MySQL 處理使用者帳戶的方式,我們可以開始建立一些新使用者。請記住使用先決條件中描述的權限使用者登入。
基本語法
建立新使用者的基本語法相對簡單。您可以使用 CREATE USER
指令,然後指定新帳戶的使用者和主機:
CREATE USER '<user>'@'<host>';
這將建立一個基本帳戶,而無需設定使用者和主機之外的任何詳細資訊。
如何建立具有密碼的使用者?
通常,您希望在建立使用者時設定身分驗證。您可以透過將選用的 IDENTIFIED BY
子句新增到 CREATE USER
陳述式來執行此操作:
CREATE USER '<user>'@'<host>' IDENTIFED BY '<password>';
這會像之前一樣建立新的使用者帳戶,並同時為該帳戶指派密碼。稍後我們將介紹如何在事後指派密碼,或如何變更使用者的密碼。
如何建立具有 Unix socket 身分驗證的使用者?
雖然密碼身分驗證是大多數使用者最常見的身分驗證方法,但它並不是唯一的選擇。MySQL 提供了許多不同的內部和外部身分驗證機制,您可以設定使用者帳戶以使用這些機制。作為範例,我們將使用 Unix socket 身分驗證設定一個新帳戶。
Unix socket 身分驗證可用於 Linux 或類 Unix 環境,以便作業系統上的帳戶可以存取 MySQL 中的相同帳戶名稱,而無需進一步身分驗證。在此組態中,MySQL 管理員知道作業系統上的使用者帳戶受到嚴格控制。
因此,如果作業系統上有 mary
使用者,如果 Unix socket 身分驗證是定義的身分驗證機制,他們將能夠登入 MySQL 中的 'mary'@'localhost'
帳戶。讓我們立即設定它。
Socket 身分驗證需要 auth_socket
外掛程式,因此首先輸入以下內容來載入外掛程式:
INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
接下來,建立一個與您作業系統上的使用者帳戶相符的使用者帳戶。在本範例中,我們將使用上面討論的 mary
帳戶。如果您不使用與您的作業系統名稱之一相符的名稱,您將無法使用此使用者進行身分驗證。
若要使用 socket 身分驗證建立使用者,我們需要使用 IDENTIFIED WITH
子句(與先前使用的 IDENTIFIED BY
子句不同)來指定要使用的身分驗證外掛程式:
CREATE USER 'mary'@'localhost' IDENTIFIED WITH auth_socket;
現在,您應該能夠從作業系統上的 mary
使用者向 'mary'@'localhost'
MySQL 使用者驗證身分。以 mary
身分登入時,連線到資料庫,無需提供任何使用者名稱或密碼:
mysql
您應該透過您設定的 Unix socket 身分驗證自動登入。
如何顯示現有使用者?
接下來,讓我們看看如何尋找有關現有使用者的資訊。
若要顯示所有現有的 MySQL 使用者,包括他們的使用者和主機元件,以及他們目前使用的身分驗證外掛程式,您可以從 mysql.user
資料庫 SELECT
這些欄位:
SELECT user,host,plugin FROM mysql.user
+------------------+-----------+-----------------------+user | host | plugin |+------------------+-----------+-----------------------+mary | localhost | auth_socket |mysql.infoschema | localhost | caching_sha2_password |mysql.session | localhost | caching_sha2_password |mysql.sys | localhost | caching_sha2_password |root | localhost | caching_sha2_password |useradmin | localhost | caching_sha2_password |+------------------+-----------+-----------------------+6 rows in set (0.00 sec)
在這裡,我們可以看到系統上定義了六個使用者,所有使用者都只能在本機登入。五個帳戶設定為使用密碼身分驗證。'mary'@'localhost'
帳戶設定為使用 Unix socket 身分驗證。
我們可以使用 SHOW CREATE USER
指令找到有關使用者屬性的其他資訊。儘管名稱如此,但它會顯示使用者帳戶的所有目前屬性,而不一定是初始帳戶建立期間使用的屬性。
SHOW CREATE USER
指令會將帳戶名稱作為引數:
SHOW CREATE USER '<user>'@'<host>'\G
通常最好使用 \G
陳述式終止符而不是常用的冒號 (;
) 來結束指令,以便您可以更清楚地查看結果。
若要顯示 'useradmin'@'localhost'
帳戶的屬性,您將輸入:
SHOW CREATE USER 'useradmin'@'localhost'\G
*************************** 1. row ***************************CREATE USER for useradmin@localhost: CREATE USER 'useradmin'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$ORl7lM;@Gt{roB4EWchqDdYM142Lq7pfzcCNiK4yUxnRBlrAgr0sE3' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT1 row in set (0.00 sec)
如何變更現有 MySQL 使用者?
您可以使用 ALTER USER
指令在 MySQL 中變更現有使用者。這可用於變更帳戶的大多數使用者相關屬性,但帳戶權限除外,帳戶權限由 GRANT
和 REVOKE
指令控制。
ALTER USER
的基本語法如下:
ALTER USER <user> <properties_to_change>;
如何變更 MySQL 使用者的密碼?
對於大多數人來說,ALTER USER
最常見的用途是修改密碼。
例如,您可以輸入以下內容來修改 'kamal'@'localhost'
的密碼:
ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>';
如果您想為使用者設定臨時密碼,他們必須立即更換,您可以同時設定和過期密碼:
ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>' PASSWORD EXPIRE;
您隨時可以變更自己的密碼,即使沒有 CREATE USER
權限也是如此。最簡單的方法是使用 USER()
函式來自動填入您自己的使用者名稱:
ALTER USER USER() IDENTIFIED BY '<new_password>';
如何變更 MySQL 使用者的身分驗證外掛程式?
您也可以變更用於驗證帳戶的身分驗證機制或外掛程式。
在先前的範例中,我們將名為 'mary'@'localhost'
的帳戶設定為使用 Unix socket 身分驗證。如果我們稍後想將該帳戶變更為使用傳統密碼身分驗證,我們可以再次使用 ALTER USER
指令。
首先,識別伺服器的預設身分驗證外掛程式。如果它是基於密碼的身分驗證方法,最好重複使用預設選擇:
SHOW VARIABLES LIKE 'default_authentication_plugin';
在本例中,預設身分驗證外掛程式是 caching_sha2_password
,因此當我們切換到密碼身分驗證時,我們將使用它。
現在,將 'mary'@'localhost'
變更為使用 caching_sha2_password
外掛程式和新密碼:
ALTER USER 'mary'@'localhost' IDENTIFIED WITH 'caching_sha2_password' BY '<marys_password>';
'mary'@'localhost'
使用者將無法再使用 Unix socket 身分驗證登入,但他們可以使用提供的密碼登入。
如何登入 MySQL?
我們已經討論了如何建立和修改 MySQL 使用者帳戶,包括身分驗證。但是,我們尚未討論如何使用這些身分驗證方法實際登入。
mysql
用戶端是一個功能強大的命令列用戶端,可用於連線到本機和遠端資料庫。我們將使用它來討論如何使用我們上面設定的方法進行身分驗證。
如何使用密碼登入本機資料庫?
若要使用具有密碼的使用者帳戶登入本機託管的 MySQL 資料庫,基本語法如下:
mysql --user=<username> --password <dbname>
因此,如果 'kamal'@'localhost'
使用者想要登入 MySQL 並從系統託管的電腦連線到 testing
資料庫,他們可以輸入:
mysql --user=kamal --password testing
mysql
用戶端將提示輸入 'kamal'@'localhost'
的密碼。如果您提供正確的憑證,您將連線到 testing
資料庫。
在命令列上指定資料庫是選用的。如果未指定任何資料庫,您將連線到伺服器,但不會連線到特定資料庫。
如何使用 Unix socket 驗證登入本機資料庫?
若要使用 Unix socket 驗證登入本機 MySQL 伺服器,您需要以相符的帳戶名稱登入您的作業系統。因此,如果我們想要使用 Unix socket 驗證來驗證 'mary'@'localhost'
,我們首先必須使用名為 mary
的使用者名稱登入我們的電腦。
一旦您使用正確的作業系統帳戶,您就可以直接執行用戶端程式來連線到本機資料庫,無需任何選項。
mysql
和之前一樣,您可以選擇性地附加資料庫名稱以連線到您想要的特定資料庫。
如何使用密碼登入遠端資料庫?
如果您的 MySQL 伺服器並非在本機伺服器上執行,您必須指定用戶端程式應嘗試連線的主機。您可以使用加入 --host
選項來達成。
大多數時候,您會使用密碼驗證來連線遠端 MySQL 伺服器,因此指令看起來會像這樣
mysql --user=<username> --password --host=<host> <dbname>
因此,'tanya'@'<tanyas_domain>'
可以透過輸入以下指令來連線到位於 example.com
的 MySQL 伺服器
mysql --user='tanya' --password --host='example.com'
如何刪除 MySQL 使用者?
保留不再有用途的使用者帳戶是一種安全風險。您可以使用 DROP USER
指令輕鬆移除帳戶。
基本語法如下
DROP USER '<user>'@'<host>';
因此,若要刪除 'mary'@'localhost'
使用者,您會輸入
DROP USER 'mary'@'localhost';
如果您嘗試刪除不存在的使用者,您將會收到錯誤訊息
ERROR 1396 (HY000): Operation DROP USER failed for 'mary'@'localhost'
為了避免這種情況,您可以在帳戶名稱前加入 IF EXISTS
子句。如果使用者存在,它將會被刪除。如果不存在,則只會發出警告
Query OK, 0 rows affected, 1 warning (0.00 sec)
結論
MySQL 的使用者帳戶管理和驗證配置非常靈活。學習如何在 MySQL 中建立、修改和取得有關使用者的資訊,將有助於您更有效地管理您的資料庫系統。
安全性最佳實務建議您應該為每個獨特的使用案例建立帳戶,並且僅給予執行其範圍所需存取權限的等級。帳戶建立和驗證是此流程的第一階段。在另一份指南中,我們將討論授予和撤銷權限以實現該策略的另一部分。
常見問題解答
變更使用者密碼最常見的方式是使用 ALTER USER
。例如,您可以使用以下指令修改 'kamal'@'localhost'
的密碼
ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>';
您也可以使用以下指令設定臨時密碼
ALTER USER 'kamal'@'localhost' IDENTIFIED BY '<new_password>' PASSWORD EXPIRE;
您可以使用 DROP USER
指令在 MySQL 中刪除使用者。基本語法如下
DROP USER '<user>'@'<host>';
為了避免嘗試刪除不存在的使用者,您可以在帳戶名稱前包含 IF EXISTS
子句。
若要列出 MySQL 執行個體中的所有使用者,您可以使用 SELECT
陳述式查詢 mysql.user
資料庫。當同時包含 host
和 plugin
時,語法如下所示
SELECT user,host,plugin FROM mysql.user;
若要顯示目前使用者的權限,您可以使用以下語法
SHOW GRANTS;
對於其他使用者,您可以使用
SHOW GRANTS FOR '<user>'@'<host>';