1. 訪問控制
MySQL伺服器的安全基礎是:使用者應該對他們需要的資料具有適當的訪問權,既不能多也不能少。換句話說,使用者不能對過多的資料具有
過多的訪問權。
考慮以下內容:
-
多數使用者只需要對錶進行讀和寫,但少數使用者甚至需要能建立和刪除表;
-
某些使用者需要讀表,但可能不需要更新表;
-
你可能想允許使用者新增資料,但不允許他們刪除資料;
-
某些使用者(管理員)可能需要處理使用者賬號的許可權,但多數使用者不需要;
-
你可能想讓使用者透過儲存過程訪問資料,但不允許他們直接訪問資料;
-
你可能想根據使用者登入的地點限制對某些功能的訪問。
這些都只是例子,但有助於說明一個重要的事實,即你需要給使用者提供他們所需的訪問權,且僅提供他們所需的訪問權。這就是所謂的訪問控制,管理訪問控制需要建立和管理使用者賬號。
我們知道,為了執行資料庫操作,需要登入MySQL。MySQL建立一個名為root的使用者賬號,它對整個MySQL伺服器具有完全的控制。,在對非現實的資料庫試驗MySQL時,使用root進行登入很好。不過在現實世界的日常工作中,決不能使用root。應該建立一系列的賬號,有的用於管理,有的供使用者使用,有的供開發人員使用,等等。
補充
-
防止無意的錯誤:
重要的是注意到,訪問控制的目的不僅僅是防止使用者的惡意企圖。資料夢魘更為常見的是無意識錯誤的結果,如錯打MySQL語句,在不合適的資料庫中操作或其他一些使用者錯誤。透過保證使用者不能執行他們不應該執行的語句,訪問控制有助於避免這些情況的發生。
-
不要使用root:
應該嚴肅對待root登入的使用。僅在絕對需要時使用它(或許在你不能登入其他管理賬號時使用)。不應該在日常的MySQL操作中使用root。
2. 管理使用者
MySQL使用者賬號和資訊儲存在名為mysql的MySQL資料庫中。一般不需要直接訪問mysql資料庫和表(稍後會明白這一點),但有時需要直接訪問。需要直接訪問它的時機之一是在需要獲得所有使用者賬號列表時。
為此,可使用以下程式碼:
use mysql;
select user from user;
輸出如下:
mysql資料庫有一個名為user的表,它包含所有使用者賬號。user表有一個名為user的列,它儲存使用者登入名。新安裝的伺服器可能只有一個使用者,過去建立的伺服器可能具有很多使用者。
補充
- 用多個客戶機進行試驗:
試驗對使用者賬號和許可權進行更改的最好辦法是開啟多個資料庫客戶機(如mysql命令列實用程式的多個副本),一個作為管理登入,其他作為被測試的使用者登入。
2.1 建立使用者賬號
為了建立一個新使用者賬號,使用 CREATE USER
語句。
比如:
create user ben identified by 'p@$$w0rd';
CREATE USER建立一個新使用者賬號。在建立使用者賬號時不一定需要口令,不過這個例子用 IDENTIFIED BY 'p@$$wOrd'
給出了一個口令。
如果再次列出使用者賬號,將會在輸出中看到新賬號:
補充
-
指定雜湊口令:
IDENTIFIED BY
指定的口令為純文字,MySQL將在儲存到user表之前對其進行加密。為了作為雜湊值指定口令,使用IDENTIFIED BY PASSWORD
。插句題外話
對上面的話解釋下:
- IDENTIFIED BY 用於指定密碼:
當使用
IDENTIFIED BY 'password'
時,password 是以純文字的形式提供的密碼。MySQL 會自動將這個密碼進行加密(通常使用雜湊演算法),然後儲存在 mysql.user 系統表的 authentication_string 列中。- IDENTIFIED BY PASSWORD 用於直接指定加密後的雜湊值:
如果你使用
IDENTIFIED BY PASSWORD 'hash_value'
,你需要提供一個已經經過加密處理的密碼(雜湊值)。MySQL 不會再對這個值進行加密,而是直接將其儲存到 mysql.user 表中。 -
使用GRANT或INSERT:
GRANT語句(稍後介紹)也可以建立使用者賬號,但一般來說CREATE USER是最清楚和最簡單的句子。此外,也可以透過直接插入行到user表來增加使用者,不過為安全起見,一般不建議這樣做。MySQL用來儲存使用者賬號資訊的表(以及表模式等)極為重要,對它們的任何毀壞都可能嚴重地傷害到MySQL伺服器。因此,相對於直接處理來說,最好是用標記和函式來處理這些表。
為重新命名一個使用者賬號,使用RENAME USER語句,如下所示:
rename user ben to bforta;
發現發生改變:
補充
-
MySQL 5之前:
僅MySQL 5或之後的版本支援RENAME USER。為了在以前的MySQL中重新命名一個使用者,可使用UPDATE直接更新user表。
2.2 刪除使用者賬號
為了刪除一個使用者賬號(以及相關的許可權),使用 DROP USER
語句.
比如:
drop user bforta;
補充
-
MySQL 5之前:
自MySQL 5以來,DROP USER刪除使用者賬號和所有相關的賬號許可權。在MySQL 5以前,DROP USER只能用來刪除使用者賬號,不能刪除相關的許可權。因此,如果使用舊版本的MySQL,需要先用REVOKE刪除與賬號相關的許可權,然後
再用DROP USER刪除賬號。
2.3 設定訪問許可權
在建立使用者賬號後,必須接著分配訪問許可權。新建立的使用者賬號沒有訪問許可權。它們能登入MySQL,但不能看到資料,不能執行任何資料庫操作。
為看到賦予使用者賬號的許可權,使用 SHOW GRANTS FOR
,如下所示:
show grants for bforta;
輸出如下:
輸出結果顯示使用者bforta有一個許可權USAGE ON *.*
。USAGE表示根本沒有許可權,所以,此結果表示在任意資料庫和任意表上對任何東西沒有許可權。
補充
-
使用者定義為user@host:
MySQL的許可權用使用者名稱和主機名結合定義。如果不指定主機名,則使用預設的主機名%(授予使用者訪問許可權而不管主機名)。
為設定許可權,使用GRANT語句。GRANT要求你至少給出以下資訊:
-
要授予的許可權;
-
被授予訪問許可權的資料庫或表;
-
使用者名稱。
舉例說明:
grant select on crashcourse.* to bforta;
此GRANT允許使用者在 crashcourse.*
(crashcourse資料庫的所有表)上使用SELECT。透過只授予SELECT訪問許可權,使用者bforta對crashcourse資料庫中的所有資料具有隻讀訪問許可權。
SHOW GRANTS
反映這個更改:
show grants for bforta;
輸出如下:
每個GRANT新增(或更新)使用者的一個許可權。MySQL讀取所有授權,並根據它們確定許可權。
GRANT的反操作為REVOKE,用它來撤銷特定的許可權。
revoke select on crashcourse.* from bforta;
這條REVOKE語句取消剛賦予使用者bforta的SELECT訪問許可權。被撤銷的訪問許可權必須存在,否則會出錯。
GRANT和REVOKE可在幾個層次上控制訪問許可權:
-
整個伺服器,使用
GRANT ALL和REVOKE ALL
; -
整個資料庫,使用
ON database.*
; -
特定的表,使用
ON database.table
; -
特定的列;
-
特定的儲存過程。
表28-1列出可以授予或撤銷的每個許可權。
使用GRANT和REVOKE,再結合表28-1中列出的許可權,你能對使用者可以
就你的寶貴資料做什麼事情和不能做什麼事情具有完全的控制。
補充
-
未來的授權:
在使用GRANT和REVOKE時,使用者賬號必須存在,但對所涉及的物件沒有這個要求。這允許管理員在建立資料庫和表之前設計和實現安全措施。這樣做的副作用是,當某個資料庫或表被刪除時(用DROP語句),相關的訪問許可權仍然存在。而且,如果將來重新建立該資料庫或表,這些許可權仍然起作用。
-
簡化多次授權:
可透過列出各許可權並用逗號分隔,將多條GRANT語句串在一起,如下所示:
grant select, insert on crashcourse.* to bforta;
2.4 更改口令
為了更改使用者口令,可使用 SET PASSWORD
語句。新口令必須如下加密:
set password for bforta = password('n3w p@$$w0rd');
SET PASSWORD更新使用者口令。新口令必須傳遞到Password()
函式進行加密。
SET PASSWORD還可以用來設定你自己的口令:
set password = password('n3w p@$$w0rd');
在不指定使用者名稱時,SET PASSWORD更新當前登入使用者的口令。