mysql管理者應該知道如何設定mysql使用者賬号,指出哪個使用者可以連接配接伺服器,從哪裡連接配接,連接配接後能做什麼。mysql 3.22.11開始引入兩條語句使得這項工作更容易做:grant語句建立mysql使用者并指定其權限,而revoke語句删除權限。兩條語句扮演了mysql資料庫的前端角色,并提供與直接操作這些表的内容不同的另一種方法。create和revoke語句影響4個表:授權表
内容
user 能連接配接伺服器的使用者以及他們擁有的任何全局權限
db 資料庫級權限
tables_priv 表級權限
columns_priv 列級權限
還有第5個授權表(host),但它不受grant和revoke的影響。
當你對一個使用者發出一條grant語句時,在user表中為該使用者建立一條記錄。如果語句指定任何全局權限(管理權限或适用于所有資料庫的權限),這些也記錄在user表中。如果你指定資料庫、表和列級權限,他們被分别記錄在db、tables_priv和columns_priv表中。
用grant和revoke比直接修改授權表更容易些,然而,建議你閱讀一下《mysql安全性指南》。這些表異常重要,而且作為一名管理者,你應該了解它們如何超越grant和revoke語句的功能水準。
在下面的章節中,我們将介紹如何設定mysql使用者賬号并授權。我們也涉及如何撤權和從授權表中删除使用者。
你可能也想考慮使用mysqlaccess和mysql_setpermission腳本,它是mysql分發的一部分,它們是perl腳本,提供grant語句的另一種選擇設定使用者賬号。mysql_setpermission需要安裝dbi支援。
1 建立使用者并授權
grant語句的文法看上去像這樣:
grant privileges (columns) on what to user identified by “password” with grant option
要使用該語句,你需要填寫下列部分:
privileges
授予使用者的權限,下表列出可用于grant語句的權限指定符:
權限指定符
權限允許的操作
alter 修改表和索引
create 建立資料庫和表
delete 删除表中已有的記錄
drop 抛棄(删除)資料庫和表
index 建立或抛棄索引
insert 向表中插入新行
reference 未用
select 檢索表中的記錄
update 修改現存表記錄
file 讀或寫伺服器上的檔案
process 檢視伺服器中執行的線程資訊或殺死線程
reload 重載授權表或清空日志、主機緩存或表緩存。
shutdown 關閉伺服器
all 所有;all privileges同義詞
usage 特殊的“無權限”權限
上表顯示在第一組的權限指定符适用于資料庫、表和列,第二組數管理權限。一般,這些被相對嚴格地授權,因為它們允許使用者影響伺服器的操作。第三組權限特殊,all意味着“所有權限”,uasge意味着無權限,即建立使用者,但不授予權限。
columns
權限運用的列,它是可選的,并且你隻能設定列特定的權限。如果指令有多于一個列,應該用逗号分開它們。
what
權限運用的級别。權限可以是全局的(适用于所有資料庫和所有表)、特定資料庫(适用于一個資料庫中的所有表)或特定表的。可以通過指定一個columns字句是權限是列特定的。
user
權限授予的使用者,它由一個使用者名和主機名組成。在mysql中,你不僅指定誰能連接配接,還有從哪裡連接配接。這允許你讓兩個同名使用者從不同地方連接配接。mysql讓你區分他們,并彼此獨立地賦予權限。
mysql中的一個使用者名就是你連接配接伺服器時指定的使用者名,該名字不必與你的unix登入名或windows名聯系起來。預設地,如果你不明确指定一個名字,客戶程式将使用你的登入名作為mysql使用者名。這隻是一個約定。你可以在授權表中将該名字改為nobody,然後以nobody連接配接執行需要超級使用者權限的操作。
password
賦予使用者的密碼,它是可選的。如果你對新使用者沒有指定identified by子句,該使用者不賦給密碼(不安全)。對現有使用者,任何你指定的密碼将代替老密碼。如果你不指定密碼,老密碼保持不變,當你用identified by時,密碼字元串用改用密碼的字面含義,grant将為你編碼密碼,不要象你用set password 那樣使用password()函數。
with grant option子句是可選的。如果你包含它,使用者可以授予權限通過grant語句授權給其它使用者。你可以用該子句給與其它使用者授權的能力。
使用者名、密碼、資料庫和表名在授權表記錄中是大小寫敏感的,主機名和列名不是。
一般地,你可以通過詢問幾個簡單的問題來識别grant語句的種類:
誰能連接配接,從那兒連接配接?
使用者應該有什麼級别的權限,他們适用于什麼?
使用者應該允許管理權限嗎?
下面就讨論一些例子。
1.1 誰能連接配接,從那兒連接配接?
你可以允許一個使用者從特定的或一系列主機連接配接。有一個極端,如果你知道降職從一個主機連接配接,你可以将權限局限于單個主機:
grant all on samp_db. to boris@localhost identified by “ruby”grant all on samp_db. to [email protected] identified by “quartz”
(samp_db.*意思是“samp_db資料庫的所有表)另一個極端是,你可能有一個經常旅行并需要能從世界各地的主機連接配接的使用者max。在這種情況下,你可以允許他無論從哪裡連接配接:
grant all on samp_db.* to max@% identified by “diamond”
“%”字元起通配符作用,與like模式比對的含義相同。在上述語句中,它意味着“任何主機”。是以max和max@%等價。這是建立使用者最簡單的方法,但也是最不安全的。
取其中,你可以允許一個使用者從一個受限的主機集合通路。例如,要允許mary從snake.net域的任何主機連接配接,用一個%.snake.net主機指定符:
grant all on samp_db.* to [email protected] identified by “quartz”;
如果你喜歡,使用者辨別符的主機部分可以用ip位址而不是一個主機名來給定。你可以指定一個ip位址或一個包含模式字元的位址,而且,從mysql 3.23,你還可以指定具有指出用于網絡号的位數的網絡掩碼的ip号:
grant all on samp_db. to [email protected] identified by “ruby” grant all on samp_db. to [email protected].% identified by “quartz” grant all on samp_db.* to [email protected]/17 identified by “ruby”
第一個例子指出使用者能從其連接配接的特定主機,第二個指定對于c類子網192.168.128的ip模式,而第三條語句中,192.168.128.0/17指定一個17位網絡号并比對具有192.168.128頭17位的ip位址。
如果mysql抱怨你指定的使用者值,你可能需要使用引号(隻将使用者名和主機名部分分開加引号)。
grant all on samp_db.president to “my friend”@”boa.snake.net”
1.2 使用者應該有什麼級别的權限和它們應該适用于什麼?
你可以授權不同級别的權限,全局權限是最強大的,因為它們适用于任何資料庫。要使ethel成為可做任何事情的超級使用者,包括能授權給其它使用者,發出下列語句:
grant all on . to ethel@localhost identified by “coffee” with grant option
on子句中的.意味着“所有資料庫、所有表”。從安全考慮,我們指定ethel隻能從本地連接配接。限制一個超級使用者可以連接配接的主機通常是明智的,因為它限制了試圖破解密碼的主機。
有些權限(file、process、reload和shutdown)是管理權限并且隻能用”on .”全局權限指定符授權。如果你願意,你可以授權這些權限,而不授權資料庫權限。例如,下列語句設定一個flush使用者,他隻能發出flush語句。這可能在你需要執行諸如清空日志等的管理腳本中會有用:
grant reload on . to flushl@localhost identified by “flushpass”
一般地,你想授權管理權限,吝啬點,因為擁有它們的使用者可以影響你的伺服器的操作。
資料庫級權限适用于一個特定資料庫中的所有表,它們可通過使用on db_name.*子句授予:
grant all on samp_db to [email protected] indetified by “rock” grant select on samp_db to ro_user@% indetified by “rock”
第一條語句向bill授權samp_db資料庫中所有表的權限,第二條建立一個嚴格限制通路的使用者ro_user(隻讀使用者),隻能通路samp_db資料庫中的所有表,但隻有讀取,即使用者隻能發出select語句。
你可以列出一系列同時授予的各個權限。例如,如果你想讓使用者能讀取并能修改現有資料庫的内容,但不能建立新表或删除表,如下授予這些權限:
grant select,insert,delete,update on samp_db to [email protected] indetified by “rock”
對于更精緻的通路控制,你可以在各個表上授權,或甚至在表的每個列上。當你想向使用者隐藏一個表的部分時,或你想讓一個使用者隻能修改特定的列時,列特定權限非常有用。如:
grant select on samp_db.member to bill@localhost indetified by “rock”grant update (expiration) on samp_db. member to bill@localhost
第一條語句授予對整個member表的讀權限并設定了一個密碼,第二條語句增加了update權限,當隻對expiration列。沒必要再指定密碼,因為第一條語句已經指定了。
如果你想對多個列授予權限,指定一個用逗号分開的清單。例如,對assistant使用者增加member表的位址字段的update權限,使用如下語句,新權限将加到使用者已有的權限中:
grant update (street,city,state,zip) on samp_db to assistant@localhost
通常,你不想授予任何比使用者确實需要的權限寬的權限。然而,當你想讓使用者能建立一個臨時表以儲存中間結果,但你又不想讓他們在一個包含他們不應修改内容的資料庫中這樣做時,發生了要授予在一個資料庫上的相對寬松的權限。你可以通過建立一個分開的資料庫(如tmp)并授予開資料庫上的所有權限來進行。例如,如果你想讓來自mars.net域中主機的任何使用者使用tmp資料庫,你可以發出這樣的grant語句:
grant all on tmp.* to “”@mars.net
在你做完之後,使用者可以建立并用tmp.tbl_name形式引用tmp中的表(在使用者指定符中的””建立一個匿名使用者,任何使用者均比對空白使用者名)。
1.3 使用者應該被允許管理權限嗎?
你可以允許一個資料庫的擁有者通過授予資料庫上的所有擁有者權限來控制資料庫的通路,在授權時,指定with grant option。例如:如果你想讓alicia能從big.corp.com域的任何主機連接配接并具有sales資料庫中所有表的管理者權限,你可以用如下grant語句:
grant all on sales.* to alicia@%.big.corp.com indetified by “applejuice” with grant option
在效果上with grant option子句允許你把通路授權的權利授予另一個使用者。要注意,擁有grant權限的兩個使用者可以彼此授權。如果你隻給予了第一個使用者select權限,而另一個使用者有grant加上select權限,那麼第二個使用者可以是第一個使用者更“強大”。
2 撤權并删除使用者
要取消一個使用者的權限,使用revoke語句。revoke的文法非常類似于grant語句,除了to用from取代并且沒有indetifed by和with grant option子句:
revoke privileges (columns) on what from user
user部分必須比對原來grant語句的你想撤權的使用者的user部分。privileges部分不需比對,你可以用grant語句授權,然後用revoke語句隻撤銷部分權限。
revoke語句隻删除權限,而不删除使用者。即使你撤銷了所有權限,在user表中的使用者記錄依然保留,這意味着使用者仍然可以連接配接伺服器。要完全删除一個使用者,你必須用一條delete語句明确從user表中删除使用者記錄:
%mysql -u root mysqlmysql>delete from user ->where user=”user_name” and host=”host_name”;mysql>flush privileges;
delete語句删除使用者記錄,而flush語句告訴伺服器重載授權表。(當你使用grant和revoke語句時,表自動重載,而你直接修改授權表時不是。)