官术网_书友最值得收藏!

6.6 MySQL的外部安全性

上一節介紹了如何保證MySQL數據文件的安全,本節繼續討論另一個方面:通過網絡訪問數據庫的安全性,也稱為MySQL的外部安全性。

6.6.1 通過授權表確認訪客

MySQL授權表用于控制客戶機對服務器的訪問權限。MySQL允許多種方法來設置授權表,授權機制非常靈活。如圖6-5所示。

圖6-5 MySQL授權表確認訪客機制

通常,可以通過GRANT和REVOKE語句來實現用戶權限控制。另外,在了解了授權表的結構,以及如何使用它們控制權限后,也可以通過直接修改授權表來實現權限控制,還可以進一步在檢查表時診斷權限的問題。

授權表在MySQL數據庫中,主要包括user、db、host、table_priv和columns_priv五個表,在首次安裝MySQL的時候初始化,通過下面命令可以查看到這些表:

    mysql> use mysql
    mysql> show tables;
    +----------------------    +
    |Tables_in_mysql           |
    +----------------------    +
    |columns_priv              |
    |db                        |
    |func                      |
    |host                      |
    |tables_priv               |
    |user                      |
    +----------------------    +

其中,func表管理MySQL可以執行的函數庫,與權限系統無關。

其余5個表都與MySQL的外部安全性相關。當一個用戶提交GRANT語句時,MySQL會在user表中為該用戶創建一條用戶記錄。如果語句指定全局權限(管理權限或適用于所有數據庫的權限),也將記錄在user表中;如果指定數據庫、表和列級權限,則會分別記錄在db、tables_priv和columns_priv表中。

6.6.2 檢查訪問用戶合法性

user表記錄所有合法用戶,以及他們的口令和全局權限信息。注意:在user表啟用的權限都是全局權限,可以在所有的數據庫上進行操作。例如,如果在user表中為一個用戶啟用了SELECT權限,那么該用戶可以從任何表中查詢任何記錄。

user表的結構如表6-3所示。

表6-3 user授權表

說明,在user表及下面所介紹的db和host表中,每個數據庫(表)的操作權限都作為單獨的列,用ENUM(“N”、“Y”)類型聲明,所有權限的默認值為“N”(off)。

下面詳細介紹user表的幾個列,這些列的含義及使用情況可能在下面所介紹的幾個表中都通用:

1.Host

該列可以是一個主機名或一個IP地址。特別地,localhost代表本地主機,僅當使用localhost而不是主機名連接時才匹配。例如,假定本地主機名為host.domian.net,且在user表中有兩項,一個Host值為localhost,而另一個為host.domian.net。帶有localhost值的項僅當連接到localhost時才進行匹配,而另一項僅當連接到host.domian.net時才匹配。簡言之,在Host中,localhost不等于主機名。

可以用通配符指定Host的值,可以使用SQL中的‘%’和‘_’,并與SQL查詢中具有相同的含義。

2.User

user表示用戶名,必須是常量或空值,空值表示任何用戶。user列不支持通配符。在user表中,當MySQL找到與登錄用戶相配的項后,發現包含user為空值時,這個用戶將被認為是匿名用戶。

3.Password

Password代表用戶口令,其值可以為空,不允許通配符,并以加密形式存儲。空口令并非與任何口令相配,而是表示用戶不必指定口令。

GRANT語句和mysqladmin password命令自動對口令進行加密,但使用INSERT、REPLACE、UPDATE或SETPASSWORD這樣的語句來直接操作權限表時,則必須用PASSWORD(“NEW_PASSWORD”)來對輸入的口令進行加密,而不能簡單地使用“new_password”。

例如,下面使用GRANT命令創建賬戶super_user、db_user和tbl_user,分別在全局級、數據庫級,以及表級上賦予查詢數據的權利:

    mysql> GRANT SELECT ON *.* TO super_user@localhost IDENTIFIED BY "my_password";
    mysql> GRANT SELECT ON student_course.* TO db_user@localhost IDENTIFIED BY
"my_password";
    mysql> GRANT SELECT ON student_course.students TO tbl_user @localhost IDENTIFIED BY
"my_password";

user表中相應添加的記錄:

    mysql>SELECT Host, User, password, Select_priv, Insert_priv FROM user WHERE user =
'super_user' OR user ='db_user' OR user = 'tbl_user';
    +-------------------  +-------------------   +--------------------------
    +-------------------+-------------------     +
    |Host             |User         |password    |        Select_priv  |Insert_priv |
    +-------------------  +-------------------   +--------------------------
    +-------------------+-------------------     +
    |localhost   |super_user  |4bec313a33935fce     |Y            |N            |
    |localhost   |db_user     |4bec313a33935fce     |N            |N            |
    |localhost   |tbl_user    |4bec313a33935fce     |N            |N            |
    +-------------------  +-------------------   +--------------------------
    +-------------------+-------------------     +

可以發現,對于db_user和tbl_user,其Select_priv值仍舊是N,而不是Y。這是因為,所授的權限限定于某個數據庫或某個表,而user表中記錄控制所有數據庫的全局權限。User表只有同下面所介紹的授權表一起,才能實現庫級和表級權限。

★ 注意 ★

授權表中的記錄是區分大小寫的,如果把“super_user”寫成了“Super_user”,則不會找到用戶信息。

6.6.3 控制庫級訪問

MySQL使用db授權表控制數據庫級別的訪問權限。db表列出所有的數據庫以及用戶擁有訪問這些數據庫的權限,并且指定的權限適用于數據庫中所有的表。db表的內容如表6-4所示。

表6-4 db授權表

其中,數據庫(表)操作權限同user表的內容相同,指定來自客戶端Host的用戶User在Db數據庫上所擁有的權限。

db表示所要控制權限的數據庫,在columns_priv和tables_priv表中,db值必須是直接的數據庫名,不允許通配符和空值。而在db和host表中,Db值可以用間接量,通過通配符‘%’或‘_’來指定%值或空值與任何數據庫相配。

同樣,在執行了上面的授權語句:

    mysql> GRANT SELECT ON *.* TO super_user@localhost IDENTIFIED BY "my_password";
    mysql> GRANT SELECT ON student_course.* TO db_user@localhost IDENTIFIED BY
"my_password";
    mysql> GRANT SELECT ON student_course.students TO tbl_user @localhost IDENTIFIED BY
"my_password";

后,db表中所添加的相應信息:

        mysql> SELECT Host, db, User, Select_priv, Insert_priv FROM db WHERE user = 'super_user'
OR user ='db_user' OR user = 'tbl_user';
        +-------------------  +-------------------   +-------------------
        +-------------------+-------------------     +
        |Host             |db           | User       |Select_priv |Insert_priv |
        +-------------------  +-------------------   +-------------------
        +-------------------+-------------------     +
        |localhost   |student_course| db_user        |Y            |N            |
        +-------------------  +-------------------   +-------------------
        +-------------------+-------------------     +

結果顯示了具有庫級權限的用戶db_user的權限信息,與之對應的用戶有:

(1)對于超級用戶suer_user,因為其查詢功能凌駕于所有數據庫之上,在db表中并沒有其信息;

(2)對于表級用戶tbl_user,其查詢功能僅僅限于某個表,其信息也未在db表中表現,而是需要使用到下面的table_priv表。

除db表之外,還有一個授權表host表,可以與db表結合使用,在更細的級別上控制對特定主機數據庫的訪問權限。但是,host表不受GRANT和REVOKE語句的影響,因此很少使用。

6.6.4 控制表級訪問

table_priv表指定用戶表級操作的權限,在其中所指定的權限適用于某個表。其結構信息如表6-5所示。

表6-5 table_priv授權表

這些列中的值必須是直接的表名或列名,不允許通配符和空白值。

對于表中的某些列,MySQL區分大小寫,另一些則不然。但Table_name列始終是區分大小寫的,即使SQL查詢中的表名是取決于服務器運行的文件系統,MySQL也區分其大小(在UNIX文件系統區分大小寫,而在Windows中不區分)。

在執行了授權語句:

    mysql> GRANT SELECT ON student_course.students TO tbl_user @localhost IDENTIFIED BY
"my_password";

后,tables_priv表中所添加的相應信息為:

    mysql>SELECT * FROM tables_priv WHERE user='tbl_user';
    Host    Db         User        Table_name  Grantor   Timestamp  Table_priv Column_priv
    Local   Student    tbl         students    ODBC@l    2006030214  Select
    Host    _course    _user                   ocalhost  3

可以看到,tbl_user用戶在數據庫student_course的students表上具有select權限,由于沒有進一步限定其權限于某一列上,因此column_priv為空。

6.6.5 控制列級訪問

columns_priv表指定用戶列級的操作權限,在這里所指定的權限適用于表中特定的列。其屬性信息如tables_priv基本一致,不同之處在于沒有table_priv屬性。

例如,使用下面的GRANT命令創建一個col_user,并指定其在students表的sname列上具有查詢的權限:

    mysql> GRANT SELECT(sname) ON student_course.students TO col_user @localhost;

columns_priv表的結果如:

    mysql> SELECT * FROM columns_priv WHERE user = 'col_user';
    +------------ +---------------+---------+-------------------+--------------------
    +-------------------  +---------------+
    |Host        |Db        |User  |Table_name  |Column_name|Timestamp    |Column_priv|
    +------------ +---------------+---------+-------------------+--------------------
    +-------------------  +---------------+
    |localhost   |student_course  |col_user |students    |sname   |20060302153856
    |Select|
    +------------ +---------------+---------+-------------------+--------------------
    +-------------------  +---------------+

6.6.6 一個應用示例

本節將通過示例,來說明如何手動使用授權表來完成GRANT和REVOKE所實現的用戶及權限管理,實現思路如下。

(1)當提交GRANT語句時,需要指定用戶名和主機號,可能還指定口令。此時,user表建立該用戶,這些登錄信息分別記錄在其User、Host和Password列中,通過INSERT語句來實現。

(2)如果GRANT指定了數據庫級的權限,用戶名和主機名將記錄在db表項的User和Host列中,所授權的數據庫記錄在Db列中,而所授予的權限記錄在權限列中,同樣可以使用INSERT語句來實現。表級和列級權限是類似的。

(3)當使用UPDATE直接修改授權表時,需要重新加載授權表,否則MySQL將不會知道權限的變化。可以通過執行mysqladmin flush-privileges或mysqladmin reload命令重新加載。如果忘記這步操作,服務器將不會刷新授權表。

示例1:建立超級用戶

下面的grant語句將創建一個擁有全部權限的超級用戶,其中包括向其他用戶授權的能力:

    GRANT ALL ON *.* TO super_user@localhost IDENTIFIED BY "my_password"
    WITH GRANT OPTION

該語句將創建user表的super_user@localhost的項,并開啟所有的操作權限。用INSERT進行同樣工作的語句是:

    INSERT INTO user VALUES

('localhost','super_user',PASSWORD('my_password')),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',' Y','Y','Y','Y')

這個INSERT語句可不好寫,這也就是GRANT語句存在的原因之一。

示例2:建立數據庫級用戶

下面的grant語句將創建一個擁有在數據庫student_course上全部權限的用戶,包括向其他用戶授權的能力:

    GRANT ALL ON student_course.* TO db_user@localhost IDENTIFIED BY "my_password"
    WITH GRANT OPTION

這些權限不是全局的,因此不能存儲在user表中。但仍需要在user表中創建一項以保存該用戶的登錄信息,同時還需要創建一個db表中的項來記錄數據庫級的權限:

    INSERT INTO user(host,user,password)
    VALUES('localhost','db_user',PASSWORD('my_password'));
    INSERT INTO db VALUES
('localhost','student_course','db_user','Y','Y','Y','Y','Y','Y','N','Y','Y','Y')

這個INSERT語句也不好寫。

為了設置表級或列級權限,需要對tables_priv或columns_priv表使用INSERT語句即可,在些不再贅述。如果要想修改某個已經存在的用戶的權限,無論是增加還是取消權限,應使用UPDATE而非INSERT語句。為刪除一個用戶,使用DELETE從該用戶所在的每個授權表中刪除其值。

主站蜘蛛池模板: 遂溪县| 分宜县| 安西县| 无棣县| 海安县| 大连市| 伊金霍洛旗| 兴隆县| 曲靖市| 筠连县| 高安市| 永吉县| 南投市| 永嘉县| 仲巴县| 丹东市| 长岛县| 德令哈市| 甘谷县| 崇义县| 新郑市| 安龙县| 饶阳县| 宁都县| 永寿县| 溧水县| 高州市| 噶尔县| 光山县| 罗平县| 奎屯市| 普兰店市| 长宁县| 修武县| 荥阳市| 抚州市| 闵行区| 南汇区| 湟中县| 定安县| 陕西省|