麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > PHP > 正文

MySQL安全性指南

2019-09-08 23:11:15
字體:
供稿:網(wǎng)友

作為一個(gè)MySQL的系統(tǒng)管理員,你有責(zé)任維護(hù)你的MySQL數(shù)據(jù)庫系統(tǒng)的數(shù)據(jù)安全性和完整性。本文主要主要介紹如何建立一個(gè)安全的MySQL系統(tǒng),從系統(tǒng)內(nèi)部和外部網(wǎng)絡(luò)兩個(gè)角度,為你提供一個(gè)指南。

本文主要考慮下列安全性有關(guān)的問題:


    ?為什么安全性很重要,你應(yīng)該防范那些攻擊?
    ?服務(wù)器面臨的風(fēng)險(xiǎn)(內(nèi)部安全性),如何處理?
    ?連接服務(wù)器的客戶端風(fēng)險(xiǎn)(外部安全性),如何處理?
MySQL管理員有責(zé)任保證數(shù)據(jù)庫內(nèi)容的安全性,使得這些數(shù)據(jù)記錄只能被那些正確授權(quán)的用戶訪問,這涉及到數(shù)據(jù)庫系統(tǒng)的內(nèi)部安全性和外部安全性。 內(nèi)部安全性關(guān)心的是文件系統(tǒng)級(jí)的問題,即,防止MySQL數(shù)據(jù)目錄(DATADIR)被在服務(wù)器主機(jī)有賬號(hào)的人(合法或竊取的)進(jìn)行攻擊。如果數(shù)據(jù)目錄內(nèi)容的權(quán)限過分授予,使得每個(gè)人均能簡單地替代對(duì)應(yīng)于那些數(shù)據(jù)庫表的文件,那么確保控制客戶通過網(wǎng)絡(luò)訪問的授權(quán)表設(shè)置正確,對(duì)此毫無意義。 外部安全性關(guān)心的是從外部通過網(wǎng)絡(luò)連接服務(wù)器的客戶的問題,即,保護(hù)MySQL服務(wù)器免受來自通過網(wǎng)絡(luò)對(duì)服務(wù)器的連接的攻擊。你必須設(shè)置MySQL授權(quán)表(grant table),使得他們不允許訪問服務(wù)器管理的數(shù)據(jù)庫內(nèi)容,除非提供有效的用戶名和口令。 下面就詳細(xì)介紹如何設(shè)置文件系統(tǒng)和授權(quán)表mysql,實(shí)現(xiàn)MySQL的兩級(jí)安全性。

一、內(nèi)部安全性-保證數(shù)據(jù)目錄訪問的安全

MySQL服務(wù)器通過在MySQL數(shù)據(jù)庫中的授權(quán)表提供了一個(gè)靈活的權(quán)限系統(tǒng)。你可以設(shè)置這些表的內(nèi)容,允許或拒絕客戶對(duì)數(shù)據(jù)庫的訪問,這提供了你防止未授權(quán)的網(wǎng)絡(luò)訪問對(duì)你數(shù)據(jù)庫攻擊的安全手段,然而如果主機(jī)上其他用戶能直接訪問數(shù)據(jù)目錄內(nèi)容,建立對(duì)通過網(wǎng)絡(luò)訪問數(shù)據(jù)庫的良好安全性對(duì)你毫無幫助,除非你知道你是登錄MySQL服務(wù)器運(yùn)行主機(jī)的唯一用戶,否則你需要關(guān)心在這臺(tái)機(jī)器上的其他用戶獲得對(duì)數(shù)據(jù)目錄的訪問的可能性。

以下是你應(yīng)該保護(hù)的內(nèi)容:


    ?數(shù)據(jù)庫文件。很明顯,你要維護(hù)服務(wù)器管理的數(shù)據(jù)庫的私用性。數(shù)據(jù)庫擁有者通常并且應(yīng)該考慮數(shù)據(jù)庫內(nèi)容的安全性,即使他們不想,也應(yīng)該考慮時(shí)數(shù)據(jù)庫內(nèi)容公開化,而不是通過糟糕的數(shù)據(jù)目錄的安全性來暴露這些內(nèi)容。
    ?日志文件。一般和更新日志必須保證安全,因?yàn)樗麄儼樵兾谋尽?duì)日志文件有訪問權(quán)限的任何人可以監(jiān)視數(shù)據(jù)庫進(jìn)行過的操作。
    更要重點(diǎn)考慮的日志文件安全性是諸如GRANTSET PASSWORD等的查詢也被記載了,一般和更新日志包含有敏感查詢的文本,包括口令(MySQL使用口令加密,但它在已經(jīng)完成設(shè)置后才運(yùn)用于以后的連接建立。設(shè)置一個(gè)口令的過程設(shè)計(jì)象GRANTSET PASSWORD等查詢,并且這些查詢以普通文本形式記載在日志文件中)。如果一個(gè)攻擊者猶如日文件的讀權(quán)限,只需在日志文件上運(yùn)行grep尋找諸如GRANTPASSWORD等詞來發(fā)現(xiàn)敏感信息。
顯然,你不想讓服務(wù)器主機(jī)上的其他用戶有數(shù)據(jù)庫目錄文件的寫權(quán)限,因?yàn)樗麄兛梢灾貙懩愕臓顟B(tài)文件或數(shù)據(jù)庫表文件,但是讀權(quán)限也很危險(xiǎn)。如果一個(gè)數(shù)據(jù)庫表文件能被讀取,偷取文件并得到MySQL本身,以普通文本顯示表的內(nèi)容也很麻煩,為什么?因?yàn)槟阋鱿铝惺虑椋?

    ?在服務(wù)器主機(jī)上安裝你自己“特制”的MySQL服務(wù)器,但是有一個(gè)不同于官方服務(wù)器版本的端口、套接字和數(shù)據(jù)目錄。
    ?運(yùn)行mysql_install_db初始化你的數(shù)據(jù)目錄,這賦予你作為MySQL root用戶訪問你的服務(wù)器的權(quán)限,所以你有對(duì)服務(wù)器訪問機(jī)制的完全控制,它也建立一個(gè)test數(shù)據(jù)庫。
    ?將對(duì)應(yīng)于你想偷取得表文件拷貝到你服務(wù)器的數(shù)據(jù)庫目錄下的test目錄。
    ?啟動(dòng)你的服務(wù)器。你可以隨意訪問數(shù)據(jù)庫表,SHOW TABLES FROM test顯示你有一個(gè)偷來的表的拷貝,SELECT *顯示它們?nèi)魏我粋€(gè)的全部內(nèi)容。
    ?如果你確實(shí)很惡毒,將權(quán)限公開給你服務(wù)器的任何匿名用戶,這樣任何人能從任何地方連接服務(wù)器訪問你的test數(shù)據(jù)庫。你現(xiàn)在將偷來的數(shù)據(jù)庫表公布于眾了。
在考慮一下,從相反的角度,你想讓別人對(duì)你這樣嗎?當(dāng)然不!你可以通過在數(shù)據(jù)庫錄下執(zhí)行l(wèi)s -l命令確定你的數(shù)據(jù)庫是否包含不安全的文件和目錄。查找有“組”和“其他用戶”權(quán)限設(shè)置的文件和目錄。下面是一個(gè)不安全數(shù)據(jù)目錄的一部分列出:

 % ls -ltotal 10148drwxrwxr-x  11  mysqladm wheel    1024 May  8 12:20 .drwxr-xr-x  22  root     wheel     512 May  8 13:31 ..drwx------   2  mysqladm mysqlgrp  512 Apr 16 15:57 menageriedrwxrwxr-x   2  mysqladm wheel     512 Jan 25 20:40 mysqldrwxrwxr-x   7  mysqladm wheel     512 Aug 31  1998 sql-benchdrwxrwxr-x   2  mysqladm wheel    1536 May  6 06:11 testdrwx------   2  mysqladm mysqlgrp 1024 May  8 18:43 tmp....

正如你看到的,有些數(shù)據(jù)庫有正確的權(quán)限,而其他不是。本例的情形是經(jīng)過一段時(shí)間后的結(jié)果。較少限制的權(quán)限由在權(quán)限設(shè)置方面比更新版本更不嚴(yán)格的較早版本服務(wù)器設(shè)置的(注意更具限制的目錄menageria和tmp都有較近日期)。MySQL當(dāng)前版本確保這些文件只能由運(yùn)行服務(wù)器的用戶讀取。

讓我們來修正這些權(quán)限,使得只用服務(wù)器用戶可訪問它們。你的主要保護(hù)工具來自于由UNIX文件系統(tǒng)本身提供的設(shè)置文件和目錄屬主和模式的工具。下面是我們要做的:


    ?進(jìn)入該目錄 % cd DATADIR


    ?設(shè)置所有在數(shù)據(jù)目錄下的文件屬主為由用于運(yùn)行服務(wù)器的賬號(hào)擁有(你必須以root執(zhí)行這步)。在本文使用mysqladm和mysqlgrp作為該賬號(hào)的用戶名和組名。你可以使用下列命令之一改變屬主:

    # chown mysqladm.mysqlgrp .

    # find . -follow -type d -print | xargs chown mysqladm.mysqlgrp


    ?設(shè)置你的數(shù)據(jù)目錄和數(shù)據(jù)庫目錄的模式使得他們只能由mysqladm讀取,這阻止其他用戶訪問你數(shù)據(jù)庫目錄的內(nèi)容。你可以用下列命令之一以root或mysqladm身份運(yùn)行。

    % chmod -R go-rwx  .

    % find . -follow -type d -print | xargs chmod go-rwx


    ?數(shù)據(jù)目錄內(nèi)容的屬主和模式為mysqladm設(shè)置。現(xiàn)在你應(yīng)該保證你總是以mysqladm用戶運(yùn)行服務(wù)器,因?yàn)楝F(xiàn)在這是唯一由訪問數(shù)據(jù)庫目錄權(quán)限的用戶(除root)。

在完成這些設(shè)置后,你最終應(yīng)該得到下面的數(shù)據(jù)目錄權(quán)限:

% ls -ltotal 10148drwxrwx---  11  mysqladm mysqlgrp 1024 May  8 12:20 .drwxr-xr-x  22  root     wheel     512 May  8 13:31 ..drwx------   2  mysqladm mysqlgrp  512 Apr 16 15:57 menageriedrwx------   2  mysqladm mysqlgrp  512 Jan 25 20:40 mysqldrwx------   7  mysqladm mysqlgrp  512 Aug 31  1998 sql-benchdrwx------   2  mysqladm mysqlgrp 1536 May  6 06:11 testdrwx------   2  mysqladm mysqlgrp 1024 May  8 18:43 tmp....

二、外部安全性-保證網(wǎng)絡(luò)訪問的安全

MySQL的安全系統(tǒng)是很靈活的,它允許你以多種不同方式設(shè)置用戶權(quán)限。一般地,你可使用標(biāo)準(zhǔn)的SQL語句GRANT和REVOKE語句做,他們?yōu)槟阈薷目刂瓶蛻粼L問的授權(quán)表,然而,你可能由一個(gè)不支持這些語句的老版本的MySQL(在3.22.11之前這些語句不起作用),或者你發(fā)覺用戶權(quán)限看起來不是以你想要的方式工作。對(duì)于這種情況,了解MySQL授權(quán)表的結(jié)構(gòu)和服務(wù)器如何利用它們決定訪問權(quán)限是有幫助的,這樣的了解允許你通過直接修改授權(quán)表增加、刪除或修改用戶權(quán)限,它也允許你在檢查這些表時(shí)診斷權(quán)限問題。

關(guān)于如何管理用戶賬號(hào),見《MySQL的用戶管理》。而對(duì)GRANT和REVOKE語句詳細(xì)描述,見《MySQL參考手冊(cè)》。

2.1 MySQL授權(quán)表的結(jié)構(gòu)和內(nèi)容

通過網(wǎng)絡(luò)連接服務(wù)器的客戶對(duì)MySQL數(shù)據(jù)庫的訪問由授權(quán)表內(nèi)容來控制。這些表位于mysql數(shù)據(jù)庫中,并在第一次安裝MySQL的過程中初始化(運(yùn)行mysql_install_db腳本)。授權(quán)表共有5個(gè)表:userdbhosttables_privcolumns_priv

表1 user、db和host授權(quán)表結(jié)構(gòu)

訪問范圍列

userdbhost
HostHostHost
UserDbDb
PasswordUser
數(shù)據(jù)庫/表權(quán)限列
Alter_privAlter_privAlter_priv
Create_privCreate_privCreate_priv
Delete_privDelete_privDelete_priv
Drop_privDrop_privDrop_priv
Index_privIndex_privIndex_priv
Insert_privInsert_privInsert_priv
References_privReferences_privReferences_priv
Select_privSelect_privSelect_priv
Update_privUpdate_privUpdate_priv
File_privGrant_privGrant_priv
Grant_priv
Process_priv
Reload_priv
Shutdown_priv
 

表2 tables_priv和columns_priv屬權(quán)表結(jié)構(gòu)

訪問范圍列
tables_privcolumns_priv
HostHost
DbDb
UserUser
Table_nameTable_name
Column_name
權(quán)限列
Table_privColumn_priv

授權(quán)表的內(nèi)容有如下用途:


    ?user表
    user表列出可以連接服務(wù)器的用戶及其口令,并且它指定他們有哪種全局(超級(jí)用戶)權(quán)限。在user表啟用的任何權(quán)限均是全局權(quán)限,并適用于所有數(shù)據(jù)庫。例如,如果你啟用了DELETE權(quán)限,在這里列出的用戶可以從任何表中刪除記錄,所以在你這樣做之前要認(rèn)真考慮。

    ?db表
    db表列出數(shù)據(jù)庫,而用戶有權(quán)限訪問它們。在這里指定的權(quán)限適用于一個(gè)數(shù)據(jù)庫中的所有表。

    ?host表
    host表與db表結(jié)合使用在一個(gè)較好層次上控制特定主機(jī)對(duì)數(shù)據(jù)庫的訪問權(quán)限,這可能比單獨(dú)使用db好些。這個(gè)表不受GRANT和REVOKE語句的影響,所以,你可能發(fā)覺你根本不是用它。

    ?tables_priv表
    tables_priv表指定表級(jí)權(quán)限,在這里指定的一個(gè)權(quán)限適用于一個(gè)表的所有列。

    ?columns_priv表
    columns_priv表指定列級(jí)權(quán)限。這里指定的權(quán)限適用于一個(gè)表的特定列。
在“不用GRANT設(shè)置用戶”一節(jié)里,我們?cè)儆懻揋RANT語句如何對(duì)修改這些表起作用,和你怎樣能通過直接修改授權(quán)表達(dá)到同樣的效果。

tables_priv和columns_priv表在MySQL 3.22.11版引進(jìn)(與GRANT語句同時(shí))。如果你有較早版本的MySQL,你的mysql數(shù)據(jù)庫將只有user、db和host表。如果你從老版本升級(jí)到3.22.11或更新,而沒有tables_priv和columns_priv表,運(yùn)行mysql_fix_privileges_tables腳本創(chuàng)建它們。

MySQL沒有rows_priv表,因?yàn)樗惶峁┯涗浖?jí)權(quán)限,例如,你不能限制用戶于表中包含特定列值的行。如果你確實(shí)需要這種能力,你必須用應(yīng)用編程來提供。如果你想執(zhí)行建議的記錄級(jí)鎖定,你可用GET_LOCK()函數(shù)做到。

授權(quán)表包含兩種列:決定一個(gè)權(quán)限何時(shí)運(yùn)用的范圍列和決定授予哪種權(quán)限的權(quán)限列。

2.1.1 授權(quán)表范圍列

授權(quán)表范圍列指定表中的權(quán)限何時(shí)運(yùn)用。每個(gè)授權(quán)表?xiàng)l目包含User和Host列來指定權(quán)限何時(shí)運(yùn)用于一個(gè)給定用戶從給定主機(jī)的連接。其他表包含附加的范圍列,如db表包含一個(gè)Db列指出權(quán)限運(yùn)用于哪個(gè)數(shù)據(jù)庫。類似地,tables_priv和columns_priv表包含范圍字段,縮小范圍到一個(gè)數(shù)據(jù)庫中的特定表或一個(gè)表的特定列。

2.1.2 授權(quán)表權(quán)限列

授權(quán)表還包含權(quán)限列,他們指出在范圍列中指定的用戶擁有何種權(quán)限。由MySQL支持的權(quán)限如下表所示。該表使用GRANT語句的權(quán)限名稱。對(duì)于絕大多數(shù)在user、db和host表中的權(quán)限列的名稱與GRANT語句中有明顯的聯(lián)系。如Select_priv對(duì)應(yīng)于SELECT權(quán)限。

2.1.3 數(shù)據(jù)庫和表權(quán)限

下列權(quán)限運(yùn)用于數(shù)據(jù)庫和表上的操作。


    ?ALTER
    允許你使用ALTER TABLE語句,這其實(shí)是一個(gè)簡單的第一級(jí)權(quán)限,你必須由其他權(quán)限,這看你想對(duì)數(shù)據(jù)庫實(shí)施什么操作。

    ?CREATE
    允許你創(chuàng)建數(shù)據(jù)庫和表,但不允許創(chuàng)建索引。

    ?DELETE
    允許你從表中刪除現(xiàn)有記錄。

    ?DROP
    允許你刪除(拋棄)數(shù)據(jù)庫和表,但不允許刪除索引。

    ?INDEX
    允許你創(chuàng)建并刪除索引。

    ?REFERENCES
    目前不用。

    ?SELECT
    允許你使用SELECT語句從表中檢索數(shù)據(jù)。對(duì)不涉及表的SELECT語句就不必要,如SELECT NOW()或SELECT 4/2。

    ?UPDATE
    允許你修改表中的已有的記錄。

2.1.4 管理權(quán)限

下列權(quán)限運(yùn)用于控制服務(wù)器或用戶授權(quán)能力的操作的管理性操作。

    ?FILE
    允許你告訴服務(wù)器讀或?qū)懛?wù)器主機(jī)上的文件。該權(quán)限不應(yīng)該隨便授予,它很危險(xiǎn),見“回避授權(quán)表風(fēng)險(xiǎn)”。服務(wù)器確實(shí)較謹(jǐn)慎地保持在一定范圍內(nèi)使用該權(quán)限。你只能讀任何人都能讀的文件。你正在寫的文件必須不是現(xiàn)存的文件,這防止你迫使服務(wù)器重寫重要文件,如/etc/passwd或?qū)儆趧e人的數(shù)據(jù)庫的數(shù)據(jù)目錄。 如果你授權(quán)FILE權(quán)限,確保你不以UNIX的root用戶運(yùn)行服務(wù)器,因?yàn)閞oot可在文件系統(tǒng)的任何地方創(chuàng)建新文件。如果你以一個(gè)非特權(quán)用戶運(yùn)行服務(wù)器,服務(wù)器只能在給用戶能訪問的目錄中創(chuàng)建文件。


    ?GRANT
    允許你將你自己的權(quán)限授予別人,包括GRANT。

    ?PROCESS
    允許你通過使用SHOW PROCESS語句或mysqladmin process命令查看服務(wù)器內(nèi)正在運(yùn)行的線程(進(jìn)程)的信息。這個(gè)權(quán)限也允許你用KILL語句或mysqladmin kill命令殺死線程。

    你總是能看到或殺死你自己的線程。PROCESS權(quán)限賦予你對(duì)任何線程做這些事情的能力。


    ?RELOAD
    允許你執(zhí)行大量的服務(wù)器管理操作。你可以發(fā)出FLUSH語句,你也能指性mysqladmin的reload、refresh、flush-hosts、flush-logs、flush-privileges和flush-tables等命令。

    ?SHUTDOWN
    允許你用mysqladmin shutdown關(guān)閉服務(wù)器。

在user、db和host表中,每一個(gè)權(quán)限以一個(gè)單獨(dú)的列指定。這些列全部聲明為一個(gè)ENUM("N","Y")類型,所以每個(gè)權(quán)的缺省值是“N”。在tables_priv和columns_priv中的權(quán)限以一個(gè)SET表示,它允許權(quán)限用一個(gè)單個(gè)列以任何組合指定。這兩個(gè)表比其他三個(gè)表更新,這就是為什么它們使用更有效的表示方式的原因。(有可能在未來,user、db和host表也用一個(gè)SET類型表示。)

在tables_priv表中的Table_priv列被定義成:

SET('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter')在coloums_priv表中的Column_priv列被定義成: 

SET('Select','Insert','Update','References')列權(quán)限比表權(quán)限少,因?yàn)榱屑?jí)較少的權(quán)限有意義。例如你能創(chuàng)建一個(gè)表,但你不能創(chuàng)建一個(gè)孤立的列。

user表包含某些在其他授權(quán)表不存在的權(quán)限的列:File_priv、Process_priv、Reload_priv和Shutdown_priv。這些權(quán)限運(yùn)用于你讓服務(wù)器執(zhí)行的與任何特定數(shù)據(jù)庫或表不相關(guān)的操作。如允許一個(gè)用戶根據(jù)當(dāng)前數(shù)據(jù)庫是什么來關(guān)閉數(shù)據(jù)庫是毫無意義的。

2.2 服務(wù)器如何控制客戶訪問

在你使用MySQL時(shí),客戶訪問控制有兩個(gè)階段。第一階段發(fā)生在你試圖連接服務(wù)器時(shí)。服務(wù)器查找user表看它是否能找到一個(gè)條目匹配你的名字、你正在從那兒連接的主機(jī)和你提供的口令。如果沒有匹配,你就不能連接。如果有一個(gè)匹配,建立連接并繼續(xù)第二階段。在這個(gè)階段,對(duì)于每一個(gè)你發(fā)出的查詢,服務(wù)器檢查授權(quán)表看你是否有足夠的權(quán)限執(zhí)行查詢,第二階段持續(xù)到你與服務(wù)器對(duì)話的結(jié)束。

本小節(jié)詳細(xì)介紹MySQL服務(wù)器用于將授權(quán)表?xiàng)l目匹配到來的連接請(qǐng)求或查詢的原則,這包括在授權(quán)表范圍列中合法的值的類型、結(jié)合授權(quán)表中的權(quán)限信息的方式和表中條目被檢查的次序。

2.2.1 范圍列內(nèi)容

一些范圍列要求文字值,但它們大多數(shù)允許通配符或其他特殊值。


    ?Host 一個(gè)Host列值可以是一個(gè)主機(jī)名或一個(gè)IP地址。值localhost意味著本地主機(jī),但它只在你用一個(gè)localhost主機(jī)名時(shí)才匹配,而不是你在使用主機(jī)名時(shí)。假如你的本地主機(jī)名是pit.snake.net并且在user表中有對(duì)你的兩條記錄,一個(gè)有一個(gè)Host值或localhost,而另一個(gè)有pit.snake.net,有l(wèi)ocalhost的記錄將只當(dāng)你連接localhost時(shí)匹配,其他在只在連接pit.snake.net時(shí)才匹配。如果你想讓客戶能以兩種方式連接,你需要在user表中有兩條記錄。

    你也可以用通配符指定Host值。可以使用SQL的模式字符“%”和“_”并具有當(dāng)你在一個(gè)查詢中使用LIKE算符同樣的含義(不允許regex算符)。 SQL模式字符都能用于主機(jī)名和IP地址。如%wisc.edu匹配任何wisc.edu域內(nèi)的主機(jī),而%.edu匹配任何教育學(xué)院的主機(jī)。類似地,192.168.%匹配任何在192.168 B類子網(wǎng)的主機(jī),而192.168.3.%匹配任何在192.168.3 C類子網(wǎng)的主機(jī)。

    %值匹配所有主機(jī),并可用于允許一個(gè)用戶從任何地方連接。一個(gè)空白的Host值等同于%。(例外:在db表中,一個(gè)空白Host值含義是“進(jìn)一步檢查host表”,該過程在“查詢?cè)L問驗(yàn)證”中介紹。)

    從MySQL 3.23起,你也可以指定帶一個(gè)表明那些為用于網(wǎng)絡(luò)地址的網(wǎng)絡(luò)掩碼的IP地址,如192.168.128.0/17指定一個(gè)17位網(wǎng)絡(luò)地址并匹配其IP地址是192.168.128前17位的任何主機(jī)。


    ?User

    用戶名必須是文字的或空白。一個(gè)空白值匹配任何用戶。%作為一個(gè)User值不意味著空白,相反它匹配一個(gè)字面上的%名字,這可能不是你想要的。

    當(dāng)一個(gè)到來的連接通過user表被驗(yàn)證而匹配的記錄包含一個(gè)空白的User值,客戶被認(rèn)為是一個(gè)匿名用戶。


    ?Password

    口令值可以是空或非空,不允許用通配符。一個(gè)空口令不意味著匹配任何口令,它意味著用戶必須不指定口令。

    口令以一個(gè)加密過的值存儲(chǔ),不是一個(gè)字面上的文本。如果你在Password列中存儲(chǔ)一個(gè)照字面上的口令,用戶將不能連接!GRANT語句和mysqladmin password命令為你自動(dòng)加密口令,但是如果你用諸如INSERT、REPLACE、UPDATE或SET PASSWORD等命令,一定要用PASSWORD("new_password")而不是簡單的"new_password"來指定口令。


    ?Db
    在columns_priv和tables_priv表中,Db值必須是真正的數(shù)據(jù)庫名(照字面上),不允許模式和空白。在db和host中,Db值可以以字面意義指定或使用SQL模式字符'%'或'_'指定一個(gè)通配符。一個(gè)'%'或空白匹配任何數(shù)據(jù)庫。

    ?Table_name,Column_name
    這些列中的值必須是照字面意思的表或列名,不允許模式和空白。

    某些范圍列被服務(wù)器視為大小寫敏感的,其余不是。這些原則總結(jié)在下表中。特別注意Table_name值總是被看作大小寫敏感的,即使在查詢中的表名的大小寫敏感性對(duì)待視服務(wù)器運(yùn)行的主機(jī)的文件系統(tǒng)而定(UNIX下是大小寫敏感,而Windows不是)。

表3 授權(quán)表范圍列的大小寫敏感性

Host
User
Password
Db
Table_name
Column_name

大小寫敏感性

No
Yes
Yes
Yes
Yes
No

2.2.2 查詢?cè)L問驗(yàn)證

每次你發(fā)出一個(gè)查詢,服務(wù)器檢查你是否有足夠的權(quán)限執(zhí)行它,它以u(píng)ser、db、tables_priv和columns_priv的順序檢查,知道它確定你有適當(dāng)?shù)脑L問權(quán)限或已搜索所有表而一無所獲。更具體的說:


    ?服務(wù)器檢查user表匹配你開始連接的記錄以查看你有什么全局權(quán)限。如果你有并且它們對(duì)查詢足夠了,服務(wù)器則執(zhí)行它。
    ?如果你的全局權(quán)限不夠,服務(wù)器為你在db表中尋找并將該記錄中的權(quán)限加到你的全局權(quán)限中。如果結(jié)果對(duì)查詢足夠,服務(wù)器執(zhí)行它。
    ?如果你的全局和數(shù)據(jù)庫級(jí)組合的權(quán)限不夠,服務(wù)器繼續(xù)查找,首先在tables_priv表,然后columns_priv表。
    ?如果你在檢查了所有表之后仍無權(quán)限,服務(wù)器拒絕你執(zhí)行查詢的企圖。
用布爾運(yùn)算的術(shù)語,授權(quán)表中的權(quán)限被服務(wù)器這樣使用:

user OR tables_priv OR columns_priv

你可能疑惑為什么前面的描述只引用4個(gè)授權(quán)表,而實(shí)際上有5個(gè)。實(shí)際上服務(wù)器是這樣檢查訪問權(quán)限:

user OR (db AND host) OR tables_priv OR columns_priv

第一個(gè)較簡單的表達(dá)式是因?yàn)閔ost表不受GRANT和REVOKE語句影響。如果你總是用GRANT和REVOKE管理用戶權(quán)限,你絕不需要考慮host表。但是其工作原理你用該知道:


    ?當(dāng)服務(wù)器檢查數(shù)據(jù)庫級(jí)權(quán)限時(shí),它對(duì)于客戶查找db表。如果Host列是空的,它意味著“檢查host表以找出哪一個(gè)主機(jī)能訪問數(shù)據(jù)庫”。

    ?服務(wù)器在host表中查找有與來自db表的記錄相同的Db列值。如果沒有host記錄匹配客戶主機(jī),則沒有授予數(shù)據(jù)庫級(jí)權(quán)限。如果這些記錄的任何一個(gè)的確有一個(gè)匹配連接的客戶主機(jī)的Host列值,db表記錄和host表記錄結(jié)合產(chǎn)生客戶的數(shù)據(jù)庫級(jí)權(quán)限。 然而,權(quán)限用一個(gè)邏輯AND(與)結(jié)合起來,這意味著除非一個(gè)給定的權(quán)限在兩個(gè)表中都有,否則客戶就不具備該權(quán)限。以這種方式,你可以在db表中授予一個(gè)基本的權(quán)限集,然后使用host表對(duì)特定的主機(jī)有選擇地禁用它們。如你可以允許從你的域中的所有主機(jī)訪問數(shù)據(jù)庫,但關(guān)閉了那些在較不安全區(qū)域的主機(jī)的數(shù)據(jù)庫權(quán)限。

前面的描述毫無疑問使訪問檢查聽起來一個(gè)相當(dāng)復(fù)雜的過程,特別是你以為服務(wù)器對(duì)你發(fā)出的每個(gè)查詢進(jìn)行權(quán)限檢查,然而此過程是很快的,因?yàn)榉?wù)器其實(shí)不從授權(quán)表對(duì)每個(gè)查詢查找信息,相反,它在啟動(dòng)時(shí)將表的內(nèi)容讀入內(nèi)存,然后驗(yàn)證查詢用的是內(nèi)存中的副本。這大大提高了訪問檢查操作的性能。但有一個(gè)非常明顯的副作用。如果你直接修改授權(quán)表的內(nèi)容,服務(wù)器將不知道權(quán)限的改變。

例如,如果你用一條INSERT語句向user表加入一個(gè)新記錄來增加一個(gè)新用戶,命名在記錄中的用戶將不能連接服務(wù)器。這對(duì)管理員新手(有時(shí)對(duì)有經(jīng)驗(yàn)的老手)是很困惑的事情,當(dāng)時(shí)解決方法很簡單:在你改變了它們之后告訴服務(wù)器重載授權(quán)表內(nèi)容,你可以發(fā)一條FLUSH PRIVILEGES或執(zhí)行mysqladmin flush-privileges(或如果你有一個(gè)不支持flush-privileges的老版本,用mysqladmin reload。)。

2.2.3 范圍列匹配順序

MySQL服務(wù)器按一種特定方式排序符授權(quán)表中的記錄,然后通過按序?yàn)g覽記錄匹配到來的連接。找到的第一個(gè)匹配決定了被使用的記錄。理解MySQL使用的排序順序很重要,特別是對(duì)user表。

當(dāng)服務(wù)器讀取user表內(nèi)容時(shí),它根據(jù)在Host和User列中的值排序記錄,Host值起決定作用(相同的Host值排在一起,然后再根據(jù)User值排序)。然而,排序不是典序(按詞排序),它只是部分是。要牢記的是字面上的詞優(yōu)先于模式。這意味著如果你正從client.your.net連接服務(wù)器而Host有client.your.net和%.your.net兩個(gè)值,則第一個(gè)先選。類似地,%.your.net優(yōu)先于%.net,然后是%。IP地址的匹配也是這樣的。

總之一句話,越具體越優(yōu)先。可以參見本文附錄的實(shí)例。

2.3 避免授權(quán)表風(fēng)險(xiǎn)

本屆介紹一些在你授權(quán)時(shí)的一些預(yù)防措施,以及不明值的選擇帶來的風(fēng)險(xiǎn)。一般地,你要很“吝嗇”地授予超級(jí)用戶權(quán)限,即不要啟用user表中條目中的權(quán)限,而使用其它授權(quán)表,以將用戶權(quán)限限制于數(shù)據(jù)庫、表、或列。在user表中的權(quán)限允許于影響到你的服務(wù)器操作或能訪問任何數(shù)據(jù)庫中的任何表。

不要授予對(duì)mysql數(shù)據(jù)庫的權(quán)限。一個(gè)擁有包含授權(quán)表數(shù)據(jù)庫權(quán)限的用戶可能會(huì)修改表以獲取對(duì)其他任何數(shù)據(jù)庫的權(quán)限。授予允許一個(gè)用戶修改mysql數(shù)據(jù)庫表的權(quán)限也實(shí)際上給了用戶以一個(gè)全局GRANT權(quán)限。如果用戶能直接修改表,這也等價(jià)于能夠發(fā)出任何你能想象的任何GRANT語句。

FILE權(quán)限尤其危險(xiǎn),不要輕易授權(quán)它。以下是一個(gè)擁有FILE權(quán)限的人能干除的事情:

CREATE TABLE etc_passwd (pwd_entry TEXT);    LOAD DATA INFILE "/etc/passwd" into TABLE etc_passwd;    SELECT * FROM etc_passwd;在發(fā)出這些語句后,用戶已經(jīng)擁有了你的口令文件的內(nèi)容了。實(shí)際上,服務(wù)器上任何公開可讀文件的內(nèi)容都可被擁有FILE權(quán)限的用戶通過網(wǎng)絡(luò)訪問。

FILE權(quán)限也能被利用來危害沒有設(shè)置足夠權(quán)限制的文件權(quán)限的系統(tǒng)上的數(shù)據(jù)庫。這就是你為什么應(yīng)該設(shè)置數(shù)據(jù)目錄只能由服務(wù)器讀取的原因。如果對(duì)應(yīng)于數(shù)據(jù)庫表的文件可被任何人讀取,不只是用戶服務(wù)器賬號(hào)的用戶可讀,任何有FILE權(quán)限的用戶也可通過網(wǎng)絡(luò)連接并讀取它們。下面演示這個(gè)過程:


    ?創(chuàng)建一個(gè)有一個(gè)LONGBLOB列的表: USER test;CREATE TABLE tmp (b LONGBLOB);
    ?使用該表讀取每個(gè)對(duì)應(yīng)于你想偷取的數(shù)據(jù)庫表文件的內(nèi)容,然后將表內(nèi)容寫入你自己數(shù)據(jù)庫的一個(gè)文件中:
    LOAD DATA INFILE "./other_db/x.frm" INTO TABLE tmp     FIELDS ESCAPED BY "" LINES TERMINATED BY "";SELECT * FROM tmp INTO OUTFILE "y.frm"     FIELDS ESCAPED BY "" LINES TERMINATED BY "";DELETE FROM tmp;LOAD DATA INFILE "./other_db/x.ISD" INTO TABLE tmp     FIELDS ESCAPED BY "" LINES TERMINATED BY "";SELECT * FROM tmp INTO OUTFILE "y.ISD"     FIELDS ESCAPED BY "" LINES TERMINATED BY "";DELETE FROM tmp;LOAD DATA INFILE "./other_db/x.ISM" INTO TABLE tmp     FIELDS ESCAPED BY "" LINES TERMINATED BY "";SELECT * FROM tmp INTO OUTFILE "y.ISM"
    ?現(xiàn)在你擁有了一個(gè)新表y,它包含other_db.x的內(nèi)容并且你有全權(quán)訪問它。
為避免讓人以同樣的方式攻擊,根據(jù)“第一部分 內(nèi)部安全性-保護(hù)你的數(shù)據(jù)目錄”中的指令設(shè)置你的數(shù)據(jù)目錄上的權(quán)限。你也可以在你啟動(dòng)服務(wù)器時(shí)使用--skip-show-database選項(xiàng)限制用戶對(duì)于他們沒用訪問權(quán)限的數(shù)據(jù)庫使用SHOW DATABASES和SHOW TABLES。這有助于防止用戶找到關(guān)于它們不能訪問的數(shù)據(jù)庫和表的信息。

ALTER權(quán)限能以不希望的方式使用。假定你想讓user1可以訪問table1但不能訪問tables2。一個(gè)擁有ALTER權(quán)限的用戶可以通過使用ALTER TABLE將table2改名為table1來偷梁換柱。

當(dāng)心GRANT權(quán)限。兩個(gè)由不同權(quán)限但都有GRANT權(quán)限的用戶可以使彼此的權(quán)利更強(qiáng)大。

2.4 不用GRANT設(shè)置用戶

如果你有一個(gè)早于3.22.11的MySQL版本,你不能使用GRANT(或REVOKE)語句設(shè)置用戶及其訪問權(quán)限,但你可以直接修改授權(quán)表的內(nèi)容。如果你理解GRANT語句如何修改授權(quán)表,這很容易。那么你通過手工發(fā)出INSERT語句就能自己做同樣的事情。

當(dāng)你發(fā)出一條GRANT語句時(shí),你指定一個(gè)用戶名和主機(jī)名,可能還有口令。對(duì)該用戶生成一個(gè)user表記錄,并且這些值記錄在User、Host和Password列中。如果你在GRANT語句中指定全局權(quán)限,這些權(quán)限記錄在記錄的權(quán)限列中。其中要留神的是GRANT語句為你加密口令,而INSERT不是,你需要在INSERT中使用PASSWORD()函數(shù)加密口令。

如果你指定數(shù)據(jù)庫級(jí)權(quán)限,用戶名和主機(jī)名被記錄在db表的User和Host列。你為其授權(quán)的數(shù)據(jù)庫記錄在Db列中,你授予的權(quán)限記錄在權(quán)限列中。

對(duì)于表級(jí)和列級(jí)權(quán)限,效果是類似的。在tables_priv和columns_priv表中創(chuàng)建記錄以記錄用戶名、主機(jī)名和數(shù)據(jù)庫,還有相關(guān)的表和列。授予的權(quán)限記錄在權(quán)限列中。

如果你還記得前面的介紹,你應(yīng)該能即使不用GRANT語句也能做GRANT做的事情。記住在你直接修改授權(quán)表時(shí),你將通知服務(wù)器重載授權(quán)表,否則他不知道你的改變。你可以執(zhí)行一個(gè)mysqladmin flush-privileges或mysqladmin reload命令強(qiáng)迫一個(gè)重載。如果你忘記做這個(gè),你會(huì)疑惑為什么服務(wù)器不做你想做的事情。

下列GRANT語句創(chuàng)建一個(gè)擁有所有權(quán)的超級(jí)用戶。包括授權(quán)給別人的能力:

GRANT ALL ON *.* TO anyname@localhost IDENTIFIED BY "passwd"    WITH GRANT OPTION該語句將在user表中為anyname@localhost創(chuàng)建一個(gè)記錄,打開所有權(quán)限,因?yàn)檫@里是超級(jí)用戶(全局)權(quán)限存儲(chǔ)的地方,要用INSERT語句做同樣的事情,語句是:

INSERT INTO user  VALUES("localhost","anyname",PASSWORD("passwd"),    "Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y","Y")你可能發(fā)現(xiàn)它不工作,這要看你的MySQL版本。授權(quán)表的結(jié)構(gòu)已經(jīng)改變而且你在你的user表可能沒有14個(gè)權(quán)限列。用SHOW COLUMNS找出你的授權(quán)表包含的每個(gè)權(quán)限列,相應(yīng)地調(diào)整你的INSERT語句。 下列GRANT語句也創(chuàng)建一個(gè)擁有超級(jí)用戶身份的用戶,但是只有一個(gè)單個(gè)的權(quán)限:

GRANT RELOAD ON *.* TO flush@localhost IDENTIFIED BY "flushpass"本例的INSERT語句比前一個(gè)簡單,它很容易列出列名并只指定一個(gè)權(quán)限列。所有其它列將設(shè)置為缺省的"N":

INSERT INTO user (Host,Password,Reload) VALUES("localhost","flush",PASSWORD("flushpass"),"Y")數(shù)據(jù)庫級(jí)權(quán)限用一個(gè)ON db_name.*子句而不是ON *.*進(jìn)行授權(quán):

GRANT ALL ON sample.* TO boris@localhost IDENTIFIED BY "ruby"這些權(quán)限不是全局的,所以它們不存儲(chǔ)在user表中,我們?nèi)匀恍枰趗ser表中創(chuàng)建一條記錄(使得用戶能連接),但我們也需要?jiǎng)?chuàng)建一個(gè)db表記錄記錄數(shù)據(jù)庫集權(quán)限:

INSERT INTO user (Host,User,Password) VALUES("localhost","boris",PASSWORD("ruby"))

INSERT INTO db VALUES("localhost","sample_db","boris","Y","Y","Y","Y","Y","Y","N","Y","Y","Y")

"N"列是為GRANT權(quán)限;對(duì)末尾的一個(gè)數(shù)據(jù)庫級(jí)具有WITH GRANT OPTION的GRANT語句,你要設(shè)置該列為"Y"。

要設(shè)置表級(jí)或列級(jí)權(quán)限,你對(duì)tables_priv或columns_priv使用INSERT語句。當(dāng)然,如果你沒有GRANT語句,你將沒有這些表,因?yàn)樗鼈冊(cè)贛ySQL中同時(shí)出現(xiàn)。如果你確實(shí)有這些表并且為了某些原因想要手工操作它們,要知道你不能用單獨(dú)的列啟用權(quán)限。

你設(shè)置tables_priv.Table_priv或columns_priv.Column_priv列來設(shè)置包含你想啟用的權(quán)限值。例如,要對(duì)一個(gè)表啟用SELECT和INSERT權(quán)限,你要在相關(guān)的tables_priv的記錄中設(shè)置Table_priv為"Select,Insert"。

如果你想對(duì)一個(gè)擁有MySQL賬號(hào)的用戶修改權(quán)限,使用UPDATE而不是INSERT,不管你增加或撤銷權(quán)限都是這樣。要完全刪除一個(gè)用戶,從用戶使用的每個(gè)表中刪除記錄。

如果你愿意避免發(fā)一個(gè)查詢來直接修改全權(quán)表,你可以看一下MySQL自帶的mysqlaccess和mysql_setpermissions腳本。

附錄1 小測(cè)驗(yàn)

在你剛剛新安裝了一個(gè)MySQL服務(wù)器,在你增加了一個(gè)允許連接MySQL的用戶,用下列語句:

GRANT ALL ON samp_db.* TO fred@*.snake.net IDENTIFIED "cocoa"

而fred碰巧在服務(wù)器主機(jī)上有個(gè)賬號(hào),所以他試圖連接服務(wù)器:

%mysql -u fred -pcocoa samp_db
ERROR 1045: Access denied for user: 'fred@localhost' (Using password: YES)

為什么?

原因是: 先考慮一下mysql_install_db如何建立初始權(quán)限表和服務(wù)器如何使用user表記錄匹配客戶連接。在你用mysql_install_db初始化你的數(shù)據(jù)庫時(shí),它創(chuàng)建類似這樣的user表:

HostUser
localhost
pit.snake.net
localhost
pit.snake.net
root
root

頭兩個(gè)記錄允許root指定localhost或主機(jī)名連接本地服務(wù)器,后兩個(gè)允許匿名用戶從本地連接。當(dāng)增加fred用戶后,

HostUser
localhost
pit.snake.net
localhost
pit.snake.net
%.snake.net
root
root


fred

在服務(wù)器啟動(dòng)時(shí),它讀取記錄并排序它們(首先按主機(jī),然后按主機(jī)上的用戶),越具體越排在前面:

HostUser
localhost
localhost
pit.snake.net
pit.snake.net
%.snake.net
root

root

fred

有l(wèi)ocalhost的兩個(gè)記錄排在一起,而對(duì)root的記錄排在第一,因?yàn)樗瓤罩蹈唧w。pit.snake.net的記錄也類似。所有這些均是沒有任何通配符的字面上的Host值,所以它們排在對(duì)fred記錄的前面,特別是匿名用戶排在fred之前。

結(jié)果是在fred試圖從localhost連接時(shí),Host列中的一個(gè)空用戶名的記錄在包含%.snake.net的記錄前匹配。該記錄的口令是空的,因?yàn)槿笔〉哪涿脩魶]有口令。因?yàn)樵趂red連接時(shí)指定了一個(gè)口令,由一個(gè)錯(cuò)配且連接失敗。

這里要記住的是,雖然用通配符指定用戶可以從其連接的主機(jī)是很方便。但你從本地主機(jī)連接時(shí)會(huì)有問題,只要你在table表中保留匿名用戶記錄。

一般地,建議你刪除匿名用戶記錄:

mysql> DELETE FROM user WHERE User="";

更進(jìn)一步,同時(shí)刪除其他授權(quán)表中的任何匿名用戶,有User列的表有db、tables_priv和columns_priv。

附錄2 使一個(gè)新的MySQL安裝更安全

在你自己安裝了一個(gè)新的MySQL服務(wù)器后,你需要為MySQL的root用戶指定一個(gè)目錄(缺省無口令),否則如果你忘記這點(diǎn),你將你的MySQL處于極不安全的狀態(tài)(至少在一段時(shí)間內(nèi))。

在Unix(Linux)上,在按照手冊(cè)的指令安裝好MySQL后,你必須運(yùn)行mysql_install_db腳本建立包含授權(quán)表的mysql數(shù)據(jù)庫和初始權(quán)限。在Windows上,運(yùn)行分發(fā)中的Setup程序初始化數(shù)據(jù)目錄和mysql數(shù)據(jù)庫。假定服務(wù)器也在運(yùn)行。

當(dāng)你第一次在機(jī)器上安裝MySQL時(shí),mysql數(shù)據(jù)庫中的授權(quán)表是這樣初始化的:


    ?你可以從本地主機(jī)(localhost)上以root連接而不指定口令。root用戶擁有所有權(quán)限(包括管理權(quán)限)并可做任何事情。(順便說明,MySQL超級(jí)用戶與Unix超級(jí)用戶有相同的名字,他們彼此毫無關(guān)系。)
    ?匿名訪問被授予用戶可從本地連接名為test和任何名字以test_開始的數(shù)據(jù)庫。匿名用戶可對(duì)數(shù)據(jù)庫做任何事情,但無管理權(quán)限。
從本地主機(jī)多服務(wù)器的連接是允許的,不管連接的用戶使用一個(gè)localhost主機(jī)名或真實(shí)主機(jī)名。如:

% mysql -h localhost test

% mysql -h pit.snake.net test

你以root連接MySQL甚至不指定口令的事實(shí)只是意味著初始安裝不安全,所以作為管理員的你首先要做的應(yīng)該是設(shè)置root口令,然后根據(jù)你設(shè)置口令使用的方法,你也可以告訴服務(wù)器重載授權(quán)表是它知道這個(gè)改變。(在服務(wù)器啟動(dòng)時(shí),它重載表到內(nèi)存中而可能不知道你已經(jīng)修改了它們。)

對(duì)MySQL 3.22和以上版本,你可以用mysqladmin設(shè)置口令:

% mysqladmin -u root password yourpassword

對(duì)于MySQL的任何版本,你可以用mysql程序并直接修改mysql數(shù)據(jù)庫中的user授權(quán)表:

% mysql -u root mysql
mysql>UPDATE user SET password=PASSWORD("yourpassword") WHERE User="root";

如果你有MySQL的老版本,使用mysql和UPDATE。

在你設(shè)置完口令后,通過運(yùn)行下列命令檢查你是否需要告訴服務(wù)器重載授權(quán)表:

% mysqladmin -u root status

如果服務(wù)器仍然讓你以root而不指定口令而連接服務(wù)器,重載授權(quán)表:

% mysqladmin -u root reload

在你設(shè)置了root的口令后(并且如果需要重載了授權(quán)表),你將需要在任何時(shí)候以root連接服務(wù)器時(shí)指定口令。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 日本网站一区二区三区 | 成人毛片一区 | 一级在线免费 | 91精品国产乱码久久久久久久久 | 一级毛片电影院 | 欧美特黄一级高清免费的香蕉 | 综合在线一区 | 欧美一级高潮 | 毛片毛片免费看 | 国产精品久久久久久久久久久久久久久久 | 久久撸视频 | 搜一级毛片 | 亚洲一区二区免费 | av电影手机在线看 | 看免费5xxaaa毛片 | 欧美精品一区二区性色 | 蜜桃麻豆视频 | 大奶一级片 | 成人福利视频 | 午夜丰满少妇高清毛片1000部 | 牛牛热这里只有精品 | 成人在线视频免费看 | 操网 | 欧美亚洲国产成人 | 久久久久免费精品国产小说色大师 | 91美女啪啪 | 天天操天天碰 | 亚洲精品 在线播放 | av影片在线观看 | av在线免费看网站 | 毛片电影网址 | 91av国产在线| 精品呦女| 国产精品99一区二区 | 午夜在线视频一区二区三区 | 成人国产精品久久久 | 免费国产人成网站 | 久久久久久久久久亚洲 | 亚洲日本韩国在线观看 | 一级成人黄色片 | 久久最新网址 |