Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2493340
  • 博文数量: 709
  • 博客积分: 12251
  • 博客等级: 上将
  • 技术积分: 7905
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-17 00:00
个人简介

实现有价值的IT服务

文章存档

2012年(7)

2011年(147)

2009年(3)

2008年(5)

2007年(74)

2006年(431)

2005年(42)

分类: Mysql/postgreSQL

2006-06-28 09:41:04

MySQL 存取權限系統
MySQL有一個先進但非標准的安全/權限系統。本節描述它的工作原理。
6.1 權限系統做什麼
MySQL權限系統的主要功能是証實連接到一台給定主機的一個用戶,並且賦予該用戶在一個數據庫上select、 insert、update和delete的權限。
附加的功能包括有一個匿名的用戶和對于MySQL特定的功能例如LOAD DATA INFILE進行授權及管理操作的能力。
6.2 MySQL 用戶名和口令
由MySQL使用用戶名和口令的方法與Unix或Windows使用的方式有很多不同之處:
MySQL使用于認証目的的用戶名,與Unix用戶名(登錄名字)或Windows用戶名無關。缺省地,大多數MySQL客戶嘗試使用當前Unix用戶名作為MySQL用戶名登錄,但是這僅僅為了方便。客戶程序允許用-u或--user選項指定一個不同的名字,這意味著無論如何你不能使得一個數據庫更安全,除非所有的MySQL用戶名都有口令。任何人可以試圖用任何名字連接服務器,而且如果他們指定了沒有口令的任何名字,他們將成功。
MySQL用戶名最長可以是16各字符;典型地,Unix用戶名限制為8個字符。
MySQL口令與Unix口令沒關系。在你使用登錄到一台Unix機器口令和你使用在那台機器上存取一個數據庫的口令之間沒有必要有關聯。
MySQL加密口令使用了一個Unix登錄期間所用的不同算法,見7.4.12 雜項函數一節中描述PASSWORD()和ENCRYPT()函數部分。
6.3 與MySQL服務器連接
當你想要存取一個MySQL服務器時,MySQL客戶程序一般要求你指定連接參數:你想要聯接的主機、你的用戶名和你的口令。例如,mysql客戶可以象這樣啟動(可選的參數被包括在“[”和“]”之間):
shell> mysql [-h host_name][-u user_name][-pyour_pass ]
-h, -u和-p選項的另一種形式是--host=host_name、--user=user_name和--password=your_pass。注意在-p或--password=與跟隨它後面的口令之間沒有空格。
注意:在命令行上指定一個口令是不安全的!隨後在你系統上的任何用戶可以通過打類似這樣的命令發現你的口令:ps auxww。見4.15.4 選項文件。
對于命令行沒有的聯接參數,mysql使用缺省值:
缺省主機名是localhost。
缺省用戶名是你的Unix登錄名。
如果沒有-p,則沒有提供口令。
這樣, 對一個Unix用戶joe,下列命令是等價的:
shell>mysql -h localhost -u joe
shell>mysql -h localhost
shell>mysql -u joe
shell>mysql
其它MySQL客戶程序有同樣表現。
在Unix系統上,當你進行一個連接時,你可以指定要使用的不同的缺省值,這樣你不必每次在你調用一個客戶程序是在命令行上輸入他們。這可以有很多方法做到:
你能在你的主目錄下“.my.cnf”的配置文件的[client]小節里指定連接參數。文件的相關小節看上去可能像這樣:
[client]
host=host_name
user=user_name
password=your_pass
見4.15.4 選項文件。
你可以用環境變量指定連接參數。主機可用MYSQL_HOST指定,MySQL用戶名字可用USER指定(僅對 Windows),口令可用MYSQL_PWD指定(但是這不安全,見下一節) 。
如果連接參數以多種方法被指定,在命令行上被指定的值優先于在配置文件和環境變量中指定的值,而在配置文件指定的值優先于在環境變量指定的值。
6.4 使你的口令安全
以一種暴露的可被其他用戶發現的方式指定你的口令是不妥當的。當你運行客戶程序時,你可以使用下列方法指定你的口令,還有每個方法的風險評估:
使用一個在命令行上-pyour_pass或--password=your_pass的選項。這很方便但是不安全,因為你的口令對系統狀態程序(例如ps)變得可見,它可以被其他的用戶調用來顯示命令行。(一般MySQL客戶在他們的初始化順序期間用零覆蓋命令行參數,但是仍然有一個短暫間隔時間內參數值可見的。)
使用一個-p或--password選項(沒有指定your_pass值)。在這種情況下,客戶程序請求來自終端的口令:
shell>mysql - u  user_name - p
Enter password: ********
客戶回應“*”字符到作為輸入你的口令的終端使得旁觀者不能看見它。因為它對其他用戶不可見,與在命令行上指定它相比,這樣進入你的口令更安全。然而,這個輸入一個口令的方法僅僅為你交互式運行程序是合適的。如果你想要從非交互式運行的一個腳本調用一個客戶,就沒有從終端輸入入口令的機會。
在一個配置文件中存儲你的口令。例如,你可你的主目錄的“.my.cnf”文件中的[client]節列出你的口令:
[client]
password=your_pass
如果你在“.my.cnf”里面存儲口令,文件應該不是組或世界可讀或可寫的。保証文件的存取模式是400或600。見4.15.4 選項文件。
你可在MYSQL_PWD環境變量中存儲口令,但是這個方法必須想到是極不安全的且應該不使用。ps的某些版本包括顯示運行進程的環境的選項;如果你設定MYSQL_PWD,你的口令將對所有人是顯而易見的,甚至在沒有這樣一個版本的ps系統上,假設沒有其他方法觀察到進程環境是不明智的。
總之,最安全的方法是讓客戶程序提示口令或在一個適當保護的“.my.cnf”文件中指定口令。
6.5   MySQL提供的權限
權限信息用user、db、host、tables_priv和columns_priv表被存儲在mysql數據庫中(即在名為mysql的數據庫中)。在MySQL啟動時和在6.9 權限修改何時生效所說的情況時,服務器讀入這些數據庫表內容。
本手冊所用的涉及由MySQL提供的權限名稱顯示在下表,還有在授權表中每個權限的表列名稱和每個權限有關的上下文:
權限  列  上下文 
select  Select_priv  表
insert  Insert_priv  表
update  Update_priv  表
delete  Delete_priv  表
index  Index_priv  表
alter  Alter_priv  表
create  Create_priv  數據庫、表或索引
drop  Drop_priv  數據庫或表
grant  Grant_priv  數據庫或表
references  References_priv  數據庫或表
reload  Reload_priv  服務器管理
shutdown  Shutdown_priv  服務器管理
process  Process_priv  服務器管理
file  File_priv  在服務器上的文件存取
select、insert、update和delete權限允許你在一個數據庫現有的表上實施操作。
SELECT語句只有在他們真正從一個表中檢索行是才需要select權限,你可以執行某個SELECT語句,甚至沒有任何到服務器上的數據庫里的存取任何東西的許可。例如,你可使用mysql客戶作為一個簡單的計算器:
mysql> SELECT 1+1;
mysql> SELECT PI()*2;
index權限允許你創建或拋棄(刪除)索引。
alter權限允許你使用ALTER TABLE。
create和drop權限允許你創建新的數據庫和表,或拋棄(刪除)現存的數據庫和表。
注意:如果你將mysql數據庫的drop權限授予一個用戶,該用戶能拋棄存儲了MySQL存取權限的數據庫!
grant權限允許你把你自己擁有的那些權限授給其他的用戶。
file權限給予你用LOAD DATA INFILE和SELECT ... INTO OUTFILE語句讀和寫服務器上的文件,任何被授予這個權限的用戶都能讀或寫MySQL服務器能讀或寫的任何文件。
其余的權限用于管理性操作,它使用mysqladmin程序實施。下表顯示mysqladmin支配每個管理性權限允許你執行的命令:
優惠  權限擁有者允許執行的命令 
reload  reload, refresh, flush-privileges, flush-hosts, flush-logs, flush-tables 
shutdown  shutdown 
precess  processlist, kill 
reload命令告訴服務器再讀入授權表,refresh命令清洗所有表並打開和關閉記錄文件,flush-privileges是reload的一個同義詞,其它flush-*命令執行類似refresh的功能,但是範圍更有限,並且在某些情況下可能更好用。例如,如果你只是想清洗記錄文件,flush-logs比refresh是更好的選擇。
shutdown命令關掉服務器。
processlist命令顯示在服務器內執行的線程的信息。kill命令殺死服務器線程。你總是能顯示或殺死你自己的線程,但是你需要process權限來顯示或殺死其他用戶啟動的線程。
總的說來,只授予權限給需要他們的那些用戶是一個好主意,但是你應該在授予某個權限時試驗特定的警告:
grant權限允許用戶放棄他們的權限給其他用戶。2個有不同的權限並有grant權限的用戶可以合並權限。
alter權限可以用于通過重新命名表來推翻權限系統。
file權限可以被濫用在服務器上讀取任何世界可讀(world-readable,即任何人可讀)的文件到一張數據庫表,然後其內容能用SELECT被存取。
shutdown權限通過終止服務器可以被濫用完全拒絕為其他用戶服務, 。
precess權限能被用來察看當前執行的查詢的普通文本,包括設定或改變口令查詢。
在mysql數據庫上的權限能被用來改變口令和其他存取權限信息。(口令被加密存儲,所以一個惡意的用戶不能簡單地讀取他們。然而,有足夠的權限,同一個用戶能用不同的一個代替一個口令。)
有一些事情你不能用MySQL權限系統做到:
你不能明顯地指定一個給定用戶應該被拒絕存取。即,你不能明顯地匹配一個用戶並且然後拒絕連接。
你不能指定一個用戶有權創建立或拋棄一個數據庫中的表,也不能創建或拋棄數據庫本身。
6.6 權限系統工作原理
MySQL權限系統保証所有的用戶可以嚴格地做他們假定被允許做的事情。當你連接一個MySQL服務器時, 你的身份由你從那連接的主機和你指定的用戶名來決定,系統根據你的身份和你想做什麼來授予權限。
MySQL在認定身份中考慮你的主機名和用戶名字,是因為有很小的原因假定一個給定的用戶在因特網上屬于同一個人。例如,用戶從whitehouse.gov連接的bill不必和從mosoft.com連接bill是同一個人。 MySQL通過允許你區分在不同的主機上碰巧有同樣名字用戶來處理它:你可以對從whitehouse.gov連接授與bill一個權限集,而為從microsoft.com的連接授予一個不同的權限集。
MySQL存取控制包含2個階段:
階段1:服務器檢查你是否允許連接。
階段2:假定你能連接,服務器檢查你發出的每個請求。看你是否有足夠的權限實施它。例如,如果你從數據庫中一個表精選(select)行或從數據庫拋棄一個表,服務器確定你對表有select權限或對數據庫有drop權限。
服務器在存取控制的兩個階段使用在mysql的數據庫中的user、db和host表,在這些授權表中字段如下:
表名稱  user  db  host 
範圍字段  Host  Host  Host 
 User  Db  Db 
 Password  User  
權限字段  Select_priv  Select_priv  Select_priv 
 Insert_priv  Insert_priv  Insert_priv 
 Update_priv  Update_priv  Update_priv 
 Delete_priv  Delete_priv  Delete_priv 
 Index_priv  Index_priv  Index_priv 
 Alter_priv  Alter_priv  Alter_priv 
 Create_priv  Create_priv  Create_priv 
 Drop_priv  Drop_priv  Drop_priv 
 Grant_priv  Grant_priv  Grant_priv 
 Reload_priv   
 Shutdown_priv   
 Process_priv   
 File_priv   
對存取控制的第二階段(請求証實),如果請求涉及表,服務器可以另外參考tables_priv和columns_priv表。這些表的字段如下:
表名稱 tables_priv  columns_priv 
範圍字段  Host  Host 
 Db  Db 
 User  User 
 Table_name  Table_name 
  Column_name 
權限字段  Table_priv  Column_priv 
 Column_priv  
其他字段  Timestamp  Timestamp 
 Grantor  
每個授權表包含範圍字段和權限字段。
範圍字段決定表中每個條目的範圍,即,條目適用的上下文。例如, 一個user表條目的Host和User值為'thomas.loc.gov'和'bob'將被用于証實來自主機thomas.loc.gov的bob對服務器的連接。同樣,一個db表條目的Host、User和Db字段的值是'thomas.loc.gov'、'bob'和'reports'將用在bob從主機聯接thomas.loc.gov存取reports數據庫的時候。 tables_priv和columns_priv表包含範圍字段,指出每個條目適用的表或表/列的組合。
對于檢查存取的用途,比較Host值是忽略大小寫的。User、Password、Db和Table_name值是區分大小寫的。Column_name值在MySQL3.22.12或以後版本是忽略大小寫的。
權限字段指出由一個表條目授予的權限,即,可實施什麼操作。服務器組合各種的授權表的信息形成一個用戶權限的完整描述。為此使用的規則在6.8 存取控制, 階段2:請求証實描述。
範圍字段是字符串,如下所述;每個字段的缺省值是空字符串:
字段名  類型 
Host  CHAR(60) 
User  CHAR(16) 
Password  CHAR(16) 
Db  CHAR(64)  (tables_priv和columns_priv表為CHAR(60))
在user、db和host表中,所有權限字段被聲明為ENUM('N','Y')--每一個都可有值'N'或'Y',並且缺省值是'N'.
在tables_priv和columns_priv表中,權限字段被聲明為SET字段:
表名  字段名  可能的集合成員 
tables_priv  Table_priv  'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter' 
tables_priv  Column_priv  'Select', 'Insert', 'Update', 'References' 
columns_priv  Column_priv  'Select', 'Insert', 'Update', 'References' 
簡單地說,服務器使用這樣的授權表:
user表範圍字段決定是否允許或拒絕到來的連接。對于允許的連接,權限字段指出用戶的全局(超級用戶)權限。
db和host表一起使用:
db表範圍字段決定用戶能從哪個主機存取哪個數據庫。權限字段決定允許哪個操作。
當你想要一個給定的db條目應用于若幹主機時,host表作為db表的擴展被使用。例如,如果你想要一個用戶能在你的網絡從若幹主機使用一個數據庫,在用戶的db表的Host條目設為空值,然後將那些主機的每一個移入host表。這個機制詳細描述在6.8 存取控制, 階段2:請求証實。
tables_priv和columns_priv表類似于db表,但是更精致:他們在表和列級應用而非在數據庫級。
注意管理權限(reload, shutdown, 等等)僅在user表中被指定。這是因為管理性操作是服務器本身的操作並且不是特定數據庫,因此沒有理由在其他授權表中列出這樣的權限。事實上,只需要請教user表來決定你是否執行一個管理操作。
file權限也僅在user表中指定。它不是管理性權限,但你讀或謝在服務器主機上的文件的的能力獨立于你正在存取的數據庫。
當mysqld服務器啟動時,讀取一次授權表內容。對授權表的更改生效在6.9 權限更改何時生效描述。
當你修改授權表的內容時,確保你按你想要的方式更改權限設置是一個好主意。為幫助診斷問題,見6.13 “存取拒絕引起”錯誤的原因。對于安全問題上的忠告,見6.14 怎麼對使MySQL安全對抗解密高手。
一個有用的診斷工具是mysqlaccess腳本,由Carlier Yves 提供給MySQL分發。使用--help選項調用mysqlaccess查明它怎樣工作。注意:mysqlaccess僅用user、db和host表僅檢查存取。它不檢查表或列級權限。
6.7 存取控制, 階段1:連接証實
當你試圖聯接一個MySQL服務器時,服務器基于你的身份和你是否能通過供應正確的口令驗証身份來接受或拒絕連接。如果不是,服務器完全具結你的存取,否則,服務器接受連接,然後進入階段2並且等待請求。
你的身份基于2個信息:
你從那個主機連接
你的MySQL用戶名
身份檢查使用3個user表(Host, User和Password)範圍字段執行。服務器只有在一個user表條目匹配你的主機名和用戶名並且你提供了正確的口令時才接受連接。
在user表範圍字段可以如下被指定:
一個Host值可以是主機名或一個IP數字,或'localhost'指出本地主機。
你可以在Host字段里使用通配符字符“%”和“_”。
一個Host值'%'匹配任何主機名,一個空白Host值等價于'%'。注意這些值匹配能創建一個連接到你的服務器的任何主機!
通配符字符在User字段中不允許,但是你能指定空白的值,它匹配任何名字。如果user表匹配到來的連接的條目有一個空白的用戶名,用戶被認為是匿名用戶(沒有名字的用戶),而非客戶實際指定的名字。這意味著一個空白的用戶名被用于在連接期間的進一步的存取檢查(即,在階段2期間)。
Password字段可以是空白的。這不意味著匹配任何口令,它意味著用戶必須不指定一個口令進行連接。
非空白Password值代表加密的口令。 MySQL不以任何人可以看的純文本格式存儲口令,相反,正在試圖聯接的一個用戶提供的口令被加密(使用PASSWORD()函數),並且與存儲了user表中的已經加密的版本比較。如果他們匹配,口令是正確的。
下面的例子顯示出各種user表中Host和User條目的值的組合如何應用于到來的連接:
Host 值  User 值  被條目匹配的連接 
'thomas.loc.gov'  'fred'  fred, 從thomas.loc.gov 連接
'thomas.loc.gov'  ''  任何用戶, 從thomas.loc.gov連接 
'%'  'fred'  fred, 從任何主機連接
'%'  ''  任何用戶, 從任何主機連接
'%.loc.gov'  'fred'  fred, 從在loc.gov域的任何主機連接
'x.y.%'  'fred'  fred, 從x.y.net、x.y.com,x.y.edu等聯接。(這或許無用)
'144.155.166.177'  'fred'  fred, 從有144.155.166.177 IP 地址的主機連接
'144.155.166.%'  'fred'  fred, 從144.155.166 C類子網的任何主機連接
既然你能在Host字段使用IP通配符值(例如,'144.155.166.%'匹配在一個子網上的每台主機),有可能某人可能企圖探究這種能力,通過命名一台主機為144.155.166.somewhere.com。為了阻止這樣的企圖,MySQL不允許匹配以數字和一個點起始的主機名,這樣,如果你用一個命名為類似1.2.foo.com的主機,它的名字決不會匹配授權表中Host列。只有一個IP數字能匹配IP通配符值。
一個到來的連接可以被在user表中的超過一個條目匹配。例如,一個由fred從thomas.loc.gov的連接匹配多個條目如上所述。如果超過一個匹配,服務器怎麼選擇使用哪個條目呢?服務器在啟動時讀入user表後通過排序來解決這個問題,然後當一個用戶試圖連接時,以排序的順序瀏覽條目,第一個匹配的條目被使用。
user表排序工作如下,假定user表看起來像這樣:
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-
當服務器在表中讀取時,它以最特定的Host值為先的次序排列('%'在Host列里意味著“任何主機”並且是最不特定的)。有相同Host值的條目以最特定的User值為先的次序排列(一個空白User值意味著“任何用戶”並且是最不特定的)。最終排序的user表看起來像這樣:
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-
當一個連接被嘗試時,服務器瀏覽排序的條目並使用找到的第一個匹配。對于由jeffrey從localhost的一個連接,在Host列的'localhost'條目首先匹配。那些有空白用戶名的條目匹配連接的主機名和用戶名。('%'/'jeffrey'條目也將匹配,但是它不是在表中的第一匹配。)
這是另外一個例子。假定user桌子看起來像這樣:
+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-
排序後的表看起來像這樣:
+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-
一個由jeffrey從thomas.loc.gov的連接被第一個條目匹配,而一個由jeffrey從whitehouse.gov的連接被第二個匹配。
普遍的誤解是認為,對一個給定的用戶名,當服務器試圖對連接尋找匹配時,明確命名那個用戶的所有條目將首先被使用。這明顯不是事實。先前的例子說明了這點,在那里一個由jeffrey從thomas.loc.gov的連接沒被包含'jeffrey'作為User字段值的條目匹配,但是由沒有用戶名的題目匹配!
如果你有服務器連接的問題,打印出user表並且手工排序它看看第一個匹配在哪兒進行。
6.8 存取控制,階段2:請求証實
一旦你建立了一個連接,服務器進入階段2。對在此連接上進來的每個請求,服務器檢查你是否有足夠的權限來執行它,它基于你希望執行的操作類型。這正是在授權表中的權限字段發揮作用的地方。這些權限可以來子user、db、host、tables_priv或columns_priv表的任何一個。授權表用GRANT和REVOKE命令操作。見7.26 GRANT和REVOKE 句法。(你可以發覺參考6.6 權限系統怎樣工作很有幫助,它列出了在每個權限表中呈現的字段。)
user表在一個全局基礎上授予賦予你的權限,該權限不管當前的數據庫是什麼均適用。例如,如果user表授予你delete權限, 你可以刪除在服務器主機上從任何數據庫刪除行!換句話說,user表權限是超級用戶權限。只把user表的權限授予超級用戶如服務器或數據庫主管是明智的。對其他用戶,你應該把在user表中的權限設成'N'並且僅在一個特定數據庫的基礎上授權, 使用db和host表。
db和host表授予數據庫特定的權限。在範圍字段的值可以如下被指定:
通配符字符“%”和“_”可被用于兩個表的Host和Db字段。
在db表的'%'Host值意味著“任何主機”,在db表中一個空白Host值意味著“對進一步的信息咨詢host表”。
在host表的一個'%'或空白Host值意味著“任何主機”。
在兩個表中的一個'%'或空白Db值意味著“任何數據庫”。
在兩個表中的一個空白User值匹配匿名用戶。
db和host表在服務器啟動時被讀取和排序(同時它讀user表)。db表在Host、Db和User範圍字段上排序,並且host表在Host和Db範圍字段上排序。對于user表,排序首先放置最特定的值然後最後最不特定的值,並且當服務器尋找匹配入條目時,它使用它找到的第一個匹配。
tables_priv和columns_priv表授予表和列特定的權限。在範圍字段的值可以如下被指定:
通配符“%”和“_”可用在使用在兩個表的Host字段。
在兩個表中的一個'%'或空白Host意味著“任何主機”。
在兩個表中的Db、Table_name和Column_name字段不能包含通配符或空白。
tables_priv和columns_priv表在Host、Db和User字段上被排序。這類似于db表的排序,盡管因為只有Host字段可以包含通配符,但排序更簡單。
請求証實進程在下面描述。(如果你熟悉存取檢查的源代碼,你會注意到這里的描述與在代碼使用的算法略有不同。描述等價于代碼實際做的東西;它只是不同于使解釋更簡單。)
對管理請求(shutdown、reload等等),服務器僅檢查user表條目,因為那是唯一指定管理權限的表。如果條目許可請求的操作,存取被授權了,否則拒絕。例如,如果你想要執行mysqladmin shutdown,但是你的user表條目沒有為你授予shutdown權限,存取甚至不用檢查db或host表就被拒絕。(因為他們不包含Shutdown_priv行列,沒有這樣做的必要。)
對數據庫有關的請求(insert、update等等),服務器首先通過查找user表條目來檢查用戶的全局(超級用戶)權限。如果條目允許請求的操作,存取被授權。如果在user表中全局權限不夠,服務器通過檢查db和host表確定特定的用戶數據庫權限:
服務器在db表的Host、Db和User字段上查找一個匹配。 Host和User對應連接用戶的主機名和MySQL用戶名。Db字段對應用戶想要存取的數據庫。如果沒有Host和User的條目,存取被拒絕。
如果db表中的條目有一個匹配而且它的Host字段不是空白的,該條目定義用戶的數據庫特定的權限。
如果匹配的db表的條目的Host字段是空白的,它表示host表列舉主機應該被允許存取數據庫的主機。在這種情況下,在host表中作進一步查找以發現Host和Db字段上的匹配。如果沒有host表條目匹配,存取被拒絕。如果有匹配,用戶數據庫特定的權限以在db和host表的條目的權限,即在兩個條目都是'Y'的權限的交集(而不是並集!)計算。(這樣你可以授予在db表條目中的一般權限,然後用host表條目按一個主機一個主機為基礎地有選擇地限制它們。)
在確定了由db和host表條目授予的數據庫特定的權限後,服務器把他們加到由user表授予的全局權限中。如果結果允許請求的操作,存取被授權。否則,服務器檢查在tables_priv和columns_priv表中的用戶的表和列權限並把它們加到用戶權限中。基于此結果允許或拒絕存取。
用布爾術語表示,前面關于一個用戶權限如何計算的描述可以這樣總結:
global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
它可能不明顯,為什麼呢,如果全局user條目的權限最初發現對請求的操作不夠,服務器以後把這些權限加到數據庫、表和列的特定權限。原因是一個請求可能要求超過一種類型的權限。例如,如果你執行一個INSERT ... SELECT語句,你就都要insert和select權限。你的權限必須如此以便user表條目授予一個權限而db表條目授予另一個。在這種情況下,你有必要的權限執行請求,但是服務器不能自己把兩個表區別開來;兩個條目授予的權限必須組合起來。
host表能被用來維護一個“安全”服務器列表。在TcX,host表包含一個在本地的網絡上所有的機器的表,這些被授予所有的權限。
你也可以使用host表指定不安全的主機。假定你有一台機器public.your.domain,它位于你不認為是安全的一個公共區域,你可以用下列的host表條目子允許除了那台機器外的網絡上所有主機的存取:
+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (所有權限設為 'N')
| %.your.domain      | %  | ... (所有權限設為 'Y')
+--------------------+----+-
當然,你應該總是測試你在授權表中的條目(例如,使用mysqlaccess)讓你確保你的存取權限實際上以你認為的方式被設置。
6.9 權限更改何時生效
當mysqld啟動時,所有的授權表內容被讀進存儲器並且從那點生效。
用GRANT、REVOKE或SET PASSWORD對授權表施行的修改會立即被服務器注意到。
如果你手工地修改授權表(使用INSERT、UPDATE等等),你應該執行一個FLUSH PRIVILEGES語句或運行mysqladmin flush-privileges告訴服務器再裝載授權表,否則你的改變將不生效,除非你重啟服務器。
當服務器注意到授權表被改變了時,現存的客戶連接有如下影響:
表和列權限在客戶的下一次請求時生效。
數據庫權限改變在下一個USE db_name命令生效。
全局權限的改變和口令改變在下一次客戶連接時生效。
6.10 建立初始的MySQL權限
在安裝MySQL後,你通過運行scripts/mysql_install_db安裝初始的存取權限。見4.7.1 快速安裝概述。 scripts/mysql_install_db腳本啟動mysqld服務器,然後初始化授權表,包含下列權限集合:
MySQL root用戶作為可做任何事情的一個超級用戶被創造。連接必須由本地主機發出。注意:出世的root口令是空的,因此任何人能以root而沒有一個口令進行連接並且被授予所有權限。
一個匿名用戶被創造,他可對有一個'test'或以'test_'開始的名字的數據庫做任何時期事情,連接必須由本地主機發出。這意味著任何本地用戶能連接並且視為匿名用戶。
其他權限被拒絕。例如,一般用戶不能使用mysqladmin shutdown或mysqladmin processlist。
注意:對Win32的初始權限是不同的。見4.12.4 在Win32上運行MySQL。
既然你的安裝初始時廣開大門,你首先應該做的事情之一是為MySQL root用戶指定一個口令。你可以做如下(注意,你使用PASSWORD()函數指定口令):
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('new_password')
           WHERE user='root';
mysql> FLUSH PRIVILEGES;
在MySQL 3.22和以上版本中,你可以使用SET PASSWORD語句:
shell> mysql -u root mysql
mysql> SET PASSWORD FOR root=PASSWORD('new_password');
設置口令的另一種方法是使用mysqladmin命令:
shell> mysqladmin -u root password new_password
注意:如果你使用第一種方法在user表里直接更新口令,你必須告訴服務器再次讀入授權表(用FLUSH PRIVILEGES),因為否則改變將不被注意到。
一旦root口令被設置,此後當你作為root與服務器連接時,你必須供應那個口令。
你可能希望讓root口令為空白以便當你施行附加的安裝時,你不需要指定它或測試,但是保証在任何真實的生產工作中使用你的安裝之前,設置它。
看看scripts/mysql_install_db腳本,看它如何安裝缺省的權限。你可用它作為一個研究如何增加其他用戶的基礎。
如果你想要初始的權限不同于上面描述的那些,在你運行mysql_install_db之前,你可以修改它。
為了完全重建權限表,刪除在包含mysql數據庫的目錄下所有“*.frm”,“*.MYI”和“*.MYD”文件。(這是在數據庫目錄下面命名為“mysql”的目錄,當你運行mysqld --help時,它被列出。)然後運行mysql_install_db腳本,可能在首先編輯它擁有你想要的權限之後。
注意:對于比MySQL 3.22.10舊的版本,你不應該刪除“*.frm”文件。如果你偶然做了,你應該在運行mysql_install_db之前你的MySQL分發中拷回它們。
6.11 向MySQL增加新用戶權限
你可以有2個不同的方法增加用戶:通過使用GRANT語句或通過直接操作MySQL授權表。比較好的方法是使用GRANT語句,因為他們是更簡明並且好像錯誤少些。
下面的例子顯示出如何使用mysql客戶安裝新用戶。這些例子假定權限根據以前的章節描述的缺省被安裝。這意味著為了改變,你必須在mysqld正在運行同一台機器上,你必須作為MySQL root用戶連接,並且root用戶必須對mysql數據庫有insert權限和reload管理權限。另外,如果你改變了root用戶口令,你必須如下的mysql命令指定它。
你可以通過發出GRANT語句增加新用戶:
shell> mysql --user=root mysql
mysql> GRANT ALL PRIVILEGES ON *.* TO
           IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO "
           IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO ;
mysql> GRANT USAGE ON *.* TO ;
這些GRANT語句安裝3個新用戶:
monty
可以從任何地方連接服務器的一個完全的超級用戶,但是必須使用一個口令('something'做這個。注意,我們必須對和"發出GRANT語句。如果我們增加localhost條目,對localhost的匿名用戶條目在我們從本地主機連接接時由mysql_install_db創建的條目將優先考慮,因為它有更特定的Host字段值,所以以user表排列順序看更早到來。
admin
可以從localhost沒有一個口令進行連接並且被授予reload和process管理權限的用戶。這允許用戶執行mysqladmin reload、mysqladmin refresh和mysqladmin flush-*命令,還有mysqladmin processlist。沒有授予數據庫有關的權限。他們能在以後通過發出另一個GRANT語句授權。
dummy
可以不用一個口令連接的一個用戶,但是只能從本地主機。全局權限被設置為'N'--USAGE權限類型允許你無需權限就可設置一個用戶。它假定你將在以後授予數據庫相關的權限。
你也可以直接通過發出INSERT語句增加同樣的用戶存取信息,然後告訴服務器再次裝入授權表:
shell> mysql --user=root mysql
mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('something'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
mysql> INSERT INTO user VALUES('%','monty',PASSWORD('something'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
mysql> INSERT INTO user SET Host='localhost',User='admin',
                 Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
                        VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;
取決于你的MySQL版本,對上述,你可能必須使用一個不同數目'Y'值(在3.22.11以前的版本有更少的權限列)。對admin用戶,只用在3.22.11開始的版本具有的更加可讀的INSERT擴充的語法。
注意,為了設置一個超級用戶,你只需創造一個user表條目,其權限字段設為'Y'。不需要db或host表的條目。
在user表中的權限列不是由最後一個INSERT語句明確設置的(對dummy用戶),因此那些列被賦予缺省值'N'。這是GRANT USAGE做的同樣的事情。
下列例子增加一個用戶custom,他能從主機localhost、server.domain和whitehouse.gov連接。他只想要從localhost存取bankaccount數據庫,從whitehouse.gov存取expenses數據庫和從所有3台主機存取customer數據庫。他想要從所有3台主機上使用口令stupid。
為了使用GRANT語句設置個用戶的權限,運行這些命令:
shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON bankaccount.*
           TO custom@localhost
           IDENTIFIED BY 'stupid';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON expenses.*
           TO custom@whitehouse.gov
           IDENTIFIED BY 'stupid';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON customer.*
           TO custom@'%'
           IDENTIFIED BY 'stupid';
通過直接修改授權表設置用戶權限,運行這些命令(注意,在結束時FLUSH PRIVILEGES):
shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
       VALUES('localhost','custom',PASSWORD('stupid'));
mysql> INSERT INTO user (Host,User,Password)
       VALUES('server.domain','custom',PASSWORD('stupid'));
mysql> INSERT INTO user (Host,User,Password)
       VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
mysql> INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES
       ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES
       ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;
頭3個INSERT語句增加user表條目,允許用戶custom用給定口令從不同的主機進行連接,但是沒有授予任何許可(所有權限被設置為缺省值'N')。後3個INSERT語句增加db表條目,授予custom以bankaccount、expenses和customer數據庫權限,但是只能在從正確的主機存取時。通常,在授權表直接被修改時,服務器必須被告知再次裝入他們(用FLUSH PRIVILEGES)以便使權限修改生效。
如果你想要給特定的用戶從一個給定的域上的任何機器上存取權限,你可以發出一個如下的GRANT語句:
mysql> GRANT ...
           ON *.*
           TO "
           IDENTIFIED BY 'mypassword';
為了通過直接修改授權表做同樣的事情,這樣做:
mysql> INSERT INTO user VALUES ('%.mydomainname.com', 'myusername',
           PASSWORD('mypassword'),...);
mysql> FLUSH PRIVILEGES;
你也可以使用xmysqladmin、mysql_webadmin甚至xmysql在授權表中插入、改變和更新值。你可以在MySQL的Contrib目錄找到這些實用程序。
6.12 怎樣設置口令
在前面小節的例子里說明了一個重要的原則:當你使用INSERT或UPDATE語句存儲一個非空的口令時,你必須使用PASSWORD()函數加密它。這是因為在user表中以加密形式存儲口令,而不是作為純文本。如果你忘記這個事實,你可能像這樣試圖設置口令:
shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password) VALUES('%','jeffrey','biscuit');
mysql> FLUSH PRIVILEGES
結果是純文本值'biscuit'作為口令被存儲在user表中。在用戶jeffrey試圖用這個口令連接服務器時,mysql客戶用PASSWORD()加密它並且將結果送給服務器,服務器比較在user表中的值(它是純文本值'biscuit')和加密的口令(而不是 'biscuit'),比較失敗並且服務器拒絕連接:
shell> mysql -u jeffrey -pbiscuit test
Access denied
因為當他們被插入user表時,口令必須被加密,相反,INSERT語句應該象這樣被指定:
mysql> INSERT INTO user (Host,User,Password)
       VALUES('%','jeffrey',PASSWORD('biscuit'));
當你使用SET PASSWORD語句時,你也必須使用PASSWORD()函數:
mysql> SET PASSWORD FOR " = PASSWORD('biscuit');
如果你使用GRANT ... IDENTIFIED BY語句或mysqladmin password命令設置口令,PASSWORD()函數是不必要的。他們都考慮到為你加密口令,多以你可像這樣指定一個口令'biscuit':
mysql> GRANT USAGE ON *.* TO " IDENTIFIED BY 'biscuit';
shell> mysqladmin -u jeffrey password biscuit
注意: PASSWORD()不是以在Unix口令加密的同樣方法施行口令加密。你不應該假定如果你的Unix口令和你的MySQL口令是一樣的,PASSWORD()將導致與在Unix口令文件被存儲的同樣的加密值。見6.2 MySQL 用戶名和口令。
6.13 Access denied錯誤的原因
當你試著聯接MySQL服務器時,如果你碰到Access denied錯誤,顯示在下面的表指出一些你能用來更正這個問題的動作:
你是在安裝MySQL以後運行mysql_install_db的腳本,來設置初始授權表內容嗎?如果不是,這樣做。見6.10 設置初始MySQL權限。通過執行這個命令測試初始權限:
shell> mysql -u root test
服務器應該讓你無誤地連接。你也應該保証你在MySQL數據庫目錄有一個文件“user.MYD”。通常,它是“PATH/var/mysql/user.MYD”,在此PATH是MySQL安裝根目錄的路徑。
在一個新的安裝以後,你應該連接服務器並且設置你的用戶及其存取許可:
shell> mysql -u root mysql
服務器應該讓你連接,因為MySQL root用戶初始時沒有口令。既然那也是一個安全風險,當你正在設置其他MySQL用戶時,設定root口令是一件重要的事請。如果你作為root嘗試連接並且得到這個錯誤:
Access denied for user: to database mysql
這意味著,你沒有一個條目在user表中的一個User列值為'root'並且mysqld不能為你的客庫解析主機名。在這種情況下,你必須用--skip-grant-tables選項重啟服務器並且編輯你的“/etc/hosts”或“\windows\hosts”文件為你的主機增加一個條目。
如果你從一個3.22.11以前的版本更新一個現存的MySQL安裝到3.22.11版或以後版本,你運行了mysql_fix_privilege_tables腳本嗎?如果沒有,運行它。在GRANT語句變得能工作時,授權表的結構用MySQL 3.22.11修改 。
如果你直接對授權表做修改(使用INSERT或UPDATE語句)並且你的改變似乎被忽略,記住,你必須發出一個FLUSH PRIVILEGES語句或執行一個mysqladmin flush-privileges命令導致服務器再次讀入表,否則你的改變要道下一次服務器被重啟時再生效。記住在你設定root口令以後,你將不需要指定它,直到在你清洗(flush)權限以後,因為服務器仍然不會知道你改變了口令!
如果你的權限似乎在一個會話(session)當中改變了,可能是一個超級用戶改變了他們。再次裝入授權表作用于新客戶連接,但是它也影響現存的連接,如6.9 權限改變何時生效小節所述。
為了測試,用--skip-grant-tables選項啟動mysqld守護進程,然後你可以改變MySQL授權表並且使用mysqlaccess腳本檢查你的修改是否有如期的效果。當你對你的改變滿意時,執行mysqladmin flush-privileges告訴mysqld服務器開始使用新的權限表。注意:再次裝入授權表覆蓋了--skip-grant-tables選項。這允許你告訴服務器開始使用授權表,而不用停掉並重啟它。
如果你有一個Perl、Python或ODBC程序的存取問題,試著用mysql -u user_name db_name或mysql -u user_name -pyour_pass db_name與服務器連接。如果你能用mysql客戶連接,這是你程序的一個問題而不是存取權限的問題。(注意在-p和口令之間沒有空格;你也能使用--password=your_pass句法指定口令。)
如果你不能讓口令工作,記得如果你用INSERT, UPDATE或SET PASSWORD語句設置口令,你必須使用PASSWORD()函數。如果你用GRANT ... INDENTIFIED BY語句或mysqladmin password命令指定口令,PASSWORD()函數是不需要的。見6.12 怎樣設置口令。
localhost是你本地主機名的一個同義詞,並且也是如果你不明確地指定主機而客戶嘗試連接的缺省主機。然而,如果你正在運行于一個使用MIT-pthreads的系統上,連接localhost是不行的(localhost連接使用Unix套接字進行,它沒被 MIT-pthreads支持),為了在這樣的系統上避免這個問題,你應該使用--host選項明確地命名服務器主機,這將做一個 TCP/IP連接到mysqld服務器。在這種情況下,你必須有在服務器主機上的user表中條目的你真實的主機名。(即使你在服務器同一台的主機上運行一個客戶程序,這也是真的。)
當嘗試用mysql -u user_name db_name與數據庫連接時,如果你得到一個Access denied錯誤,你可能有與user桌有關的問題,通過執行mysql -u root mysql並且發出下面的SQL語句檢查:
mysql> SELECT * FROM user;
結果應該包含一個有Host和User列的條目匹配你的計算機主機名和你的MySQL用戶名。
Access denied錯誤消息將告訴你,你正在用哪個用戶嘗試登錄,你正在試圖用連接哪個主機,並且你是否正在使用一個口令。通常,你應該在user表中有一個條目,正確地匹配在錯誤消息給出的主機名和用戶名。
如果當你試著從一個不是MySQL服務器正在運行的主機上連接時,你得到下列錯誤,那麼在user表中沒有匹配那台主機行:
Host ... is not allowed to connect to this MySQL server
你可以通過使用mysql命令行工具(在服務器主機上!)修正它,把你正在試圖連接的用戶/主機名組合新加一行到user表中。如果你不在運行MySQL 3.22並且你不知道你正在從它連接的機器的IP數字或主機名,你應該把一個'%'條目作為Host列值放在user表中並且在服務器機器上使用--log選項重啟mysqld。在試圖從客戶機器連接以後,在MySQL記錄文件中的信息將顯示你如何真正進行連接。(然後用在記錄文件上面顯示出的實際的主機名代替user表中的'%'條目。否則,你將有一個不安全的系統。)
如果mysql -u root test工作但是mysql -h your_hostname -u root test導致Access denied,那麼在user表中你可能沒有你的主機的正確名字。這里的一個普遍的問題是在user表條目中的Host值指定一個唯一的主機名,但是你系統的名字解析例程返回一個完全正規的域名(或相反)。例如,如果你在user表中有一個主機是'tcx'的條目,但是你的 DNS告訴MySQL你的主機名是'tcx.subnet.se',條目將不工作。嘗試把一個條目加到user表中,它包含你主機的IP數字作為Host列的值。(另外,你可以把一個條目加到user表中,它有包含一個通配符如'tcx.%'的Host值。然而,使用以“%”結尾的主機名是不安全的並且不推薦!)
如果mysql -u user_name test工作但是mysql -u user_name other_db_name不工作,對other_db_name,你在db表中沒有沒有一個條目列出。
當在服務器機器上執行mysql -u user_name db_name時,它工作,但是在其它客戶機器上執行mysql -h host_name -u user_name db_name時,它卻不工作,你沒有把客戶機器列在user表或db表中。
如果你不能弄明白你為什麼得到Access denied,從user表中刪除所有Host包含通配符值的條目(包含“%”或“_”的條目)。一個很普遍的錯誤是插入用Host='%'和User='some user'插入一個新條目,認為這將允許你指定localhost從同一台機器進行連接。它不工作的原因是缺省權限包括一個有Host='localhost'和User=''的條目,因為那個條目一個比'%'更具體的Host值'localhost',當從localhost連接時,它用于指向新條目!正確的步驟是插入Host='localhost'和User='some_user'的第2個條目,或刪除Host='localhost'和User=''條目。
如果你得到下列錯誤,你可以有一個與db或host表有關的問題:
Access to database denied
如果從db表中選擇了在Host列有空值的條目,保証在host表中有一個或多個相應的條目,指定運用db表中的哪些主機。如果在使用SQL命令SELECT ... INTO OUTFILE或LOAD DATA INFILE時,你得到錯誤,在user表中的你的條目可能啟用file權限。
記住,客戶程序將使用在配置文件或環境變量被指定了的連接參數。如果當你不在命令行上指定他們時,一個客戶似乎正在發送錯誤的缺省連接參數,檢查你的環境和在你的主目錄下的“.my.cnf”文件。你也可以檢查系統範圍的MySQL配置文件,盡管更不可能將在那里指定那個客戶的連接參數。見4.15.4 選項文件。如果當你沒有任何選項運行一個客戶時,你得到Access denied,確認你沒在任何選項文件里指定一個舊的口令!見4.15.4 選項文件。
如果任何其它事情失敗,用調試選項(例如,--debug=d,general,query)啟動mysqld守護進程。這將打印有關嘗試連接的主機和用戶信息,和發出的每個命令的信息。見G.1 調試一個MySQL服務器。
如果你有任何與MySQL授權表的其它問題,而且覺得你必須郵寄這個問題到郵寄表,總是提供一個MySQL授權表的傾倒副本(dump)。你可用mysqldump mysql命令傾倒數據庫表。象平時一樣,用mysqlbug腳本郵寄你的問題。在一些情況下你可能用--skip-grant-tables重啟mysqld以便能運行mysqldump。
6.14 怎樣使MySQL安全以對抗解密高手
當你連接一個MySQL服務器時,你通常應該使用一個口令。口令不以明文在連接上傳輸。
所有其它信息作為能被任何人讀懂的文本被傳輸。如果你擔心這個,你可使用壓縮協議(MySQL3.22和以上版本)使事情變得更難。甚至為了使一切更安全,你應該安裝ssh(見)。用它,你能在一個MySQL服務器與一個MySQL客戶之間得到一個加密的TCP/IP連接。
為了使一個MySQL系統安全,強烈要求你考慮下列建議:
對所有MySQL用戶使用口令。記住,如果other_user沒有口令,任何人能簡單地用mysql -u other_user db_name作為任何其它的人登錄。對客戶機/服務器應用程序,客戶可以指定任何用戶名是常見的做法。在你運行它以前,你可以通過編輯mysql_install_db腳本改變所有用戶的口令,或僅僅MySQL root的口令,象這樣:
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('new_password')
           WHERE user='root';
mysql> FLUSH PRIVILEGES;
不要作為Unix的root用戶運行MySQL守護進程。mysqld能以任何用戶運行,你也可以創造一個新的Unix用戶mysql使一切更安全。如果你作為其它Unix用戶運行mysqld,你不需要改變在user表中的root用戶名,因為MySQL用戶名與Unix 用戶名沒關系。你可以作為其它Unix用戶編輯mysql.server啟動腳本mysqld。通常這用su命令完成。對于更多的細節,見18.8 怎樣作為一個一般用戶運行MySQL。
如果你把一個Unix root用戶口令放在mysql.server腳本中,確保這個腳本只能對root是可讀的。
檢查那個運行mysqld的Unix用戶是唯一的在數據庫目錄下有讀/寫權限的用戶。
不要把process權限給所有用戶。mysqladmin processlist的輸出顯示出當前執行的查詢正文,如果另外的用戶發出一個UPDATE user SET password=PASSWORD('not_secure')查詢,被允許執行那個命令的任何用戶可能看得到。mysqld為有process權限的用戶保留一個額外的連接, 以便一個MySQL root用戶能登錄並檢查,即使所有的正常連接在使用。
不要把file權限給所有的用戶。有這權限的任何用戶能在擁有mysqld守護進程權限的文件系統那里寫一個文件!為了使這更安全一些,用SELECT ... INTO OUTFILE生成的所有文件對每個人是可讀的,並且你不能覆蓋已經存在的文件。file權限也可以被用來讀取任何作為運行服務器的Unix用戶可存取的文件。這可能被濫用,例如,通過使用LOAD DATA裝載“/etc/passwd”進一個數據庫表,然後它能用SELECT被讀入。
如果你不信任你的DNS,你應該在授權表中使用IP數字而不是主機名。原則上講,--secure選項對mysqld應該使主機名更安全。在任何情況下,你應該非常小心地使用包含通配符的主機名!
下列mysqld選項影響安全:
--secure
由gethostbyname()系統調用返回的IP數字被檢查,確保他們解析回到原來的主機名。這對某些外人通過模仿其它主機獲得存取權限變得更難。這個選項也增加一些聰明的主機名檢查。在MySQL3.21里,選擇缺省是關掉的,因為它有時它花很長時間執行反向解析。MySQL 3.22緩存主機名並缺省地啟用了這個選項。
--skip-grant-tables
這個選項導致服務器根本不使用權限系統。這給每個人以完全存取所有的數據庫的權力!(通過執行mysqladmin reload,你能告訴一個正在運行的服務器再次開始使用授權表。)
--skip-name-resolve
主機名不被解析。所有在授權表的Host的列值必須是IP數字或localhost。
--skip-networking
在網絡上不允許TCP/IP連接。所有到mysqld的連接必須經由Unix套接字進行。這個選項對使用MIT-pthreads的系統是不合適的,因為MIT-pthreads包不支持Unix套接字。
=======================
Refer to
如果你想连接你的mysql的时候发生这个错误:

ERROR 1130: Host '192.168.1.3' is not allowed to connect to this MySQL server

解决方法:
1。 改表法。可能是你的帐号不允许从远程登陆,只能在localhost。这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 "user" 表里的 "host" 项,从"localhost"改称"%"

mysql -u root -pvmwaremysql>use mysql;mysql>update user set host = '%' where user = 'root';mysql>select host, user from user;

2. 授权法。例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话。

GRANT ALL PRIVILEGES ON *.* TO IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
如果你想允许用户myuser从ip为192.168.1.3的主机连接到mysql服务器,并使用mypassword作为密码
GRANT ALL PRIVILEGES ON *.* TO IDENTIFIED BY 'mypassword' WITH GRANT OPTION;

PS: 对我的情况.....没用,也许是我的mysql问题或者什么. 可能你们有用。just have a try and good luck
阅读(1882) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~