首頁  >  文章  >  資料庫  >  MySQL安全性指南 (1)(轉)

MySQL安全性指南 (1)(轉)

黄舟
黄舟原創
2016-12-17 15:04:03977瀏覽

MySQL安全性指南
作 者: 晏子


身為一個MySQL的系統管理員,你有責任維護你的MySQL資料庫系統的資料安全性和完整性。本文主要主要介紹如何建立一個安全的MySQL系統,從系統內部和外部網路兩個角度,為你提供一個指南。

本文主要考慮下列安全性有關的問題:

為什麼安全性很重要,你應該防範那些攻擊?
伺服器面臨的風險(內部安全性),如何處理?
連接伺服器的客戶端風險(外部安全性),如何處理?
MySQL管理員有責任確保資料庫內容的安全性,使得這些資料記錄只能被那些正確授權的使用者訪問,這涉及到資料庫系統的內部安全性和外部安全性。
內部安全性關心的是檔案系統層級的問題,即,防止MySQL資料目錄(DATADIR)被在伺服器主機有帳號的人(合法或竊取的)進行攻擊。如果資料目錄內容的權限過度授予,使得每個人均能簡單地替代對應於那些資料庫表的文件,那麼確保控制客戶透過網路存取的授權表設定正確,對此毫無意義。

外部安全性關心的是從外部透過網路連接伺服器的客戶的問題,即,保護MySQL伺服器免受來自透過網路對伺服器的連接的攻擊。你必須設定MySQL授權表(grant table),使得他們不允許存取伺服器管理的資料庫內容,除非提供有效的使用者名稱和口令。

下面就詳細介紹如何設定檔案系統和授權表mysql,實現MySQL的兩級安全性。


一、內部安全性-保證資料目錄存取的安全性
MySQL伺服器透過在MySQL資料庫中的授權表提供了一個靈活的權限系統。你可以設定這些表的內容,允許或拒絕客戶對資料庫的訪問,這提供了你防止未授權的網路訪問對你資料庫攻擊的安全手段,然而如果主機上其他使用者能直接存取資料目錄內容,建立對透過網路存取資料庫的良好安全性對你毫無幫助,除非你知道你是登入MySQL伺服器運行主機的唯一用戶,否則你需要關心在這台機器上的其他用戶獲得對資料目錄的存取的可能性。

以下是你應該保護的內容:

資料庫檔案。很明顯,你要維護伺服器管理的資料庫的私用性。資料庫擁有者通常並且應該考慮資料庫內容的安全性,即使他們不想,也應該考慮時資料庫內容公開化,而不是透過糟糕的資料目錄的安全性來暴露這些內容。
日誌檔。一般和更新日誌必須保證安全,因為他們包含查詢文字。對日誌檔案有存取權限的任何人可以監視資料庫進行過的操作。
更要重點考慮的日誌檔案安全性是諸如GRANT和SET PASSWord等的查詢也被記載了,一般和更新日誌包含有敏感查詢的文本,包括口令(MySQL使用口令加密,但它在已經完成設定後才運用於以後的連接建立。設定一個口令的過程設計象GRANT或SET PASSWORD等查詢,並且這些查詢以普通文字形式記載在日誌檔案中)。如果一個攻擊者猶如日檔案的讀取權限,只需在日誌檔案上執行grep尋找諸如GRANT和PASSWORD等字眼來發現敏感資訊。
顯然,你不想讓伺服器主機上的其他使用者有資料庫目錄檔案的寫權限,因為他們可以重寫你的狀態檔案或資料庫表文件,但是讀取權限也很危險。如果一個資料庫表檔案能被讀取,偷取檔案並得到MySQL本身,以普通文字顯示表格的內容也很麻煩,為什麼?因為你要做下列事情:

在伺服器主機上安裝你自己「特製」的MySQL伺服器,但有一個不同於官方伺服器版本的連接埠、套接字和資料目錄。
運行mysql_install_db初始化你的資料目錄,這賦予你作為MySQL root使用者存取你的伺服器的權限,所以你有對伺服器存取機制的完全控制,它也建立一個test資料庫。
將對應到你想要竊取表格檔案拷貝到你伺服器的資料庫目錄下的test目錄。
啟動你的伺服器。你可以隨意存取資料庫表,SHOW TABLES FROM test顯示你有一個偷來的表的拷貝,SELECT *顯示它們任何一個的全部內容。
如果你確實很惡毒,將權限公開給你伺服器的任何匿名用戶,這樣任何人能從任何地方連接伺服器存取你的test資料庫。你現在將偷來的資料庫表格公佈於眾了。
在考慮一下,從相反的角度,你想讓別人對你這樣嗎?當然不!你可以透過在資料庫錄下執行ls -l指令確定你的資料庫是否包含不安全的檔案和目錄。尋找有「群組」和「其他使用者」權限設定的檔案和目錄。以下是一個不安全資料目錄的一部分列出:

 
% ls -l
total 10148
drwxrwxr-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 menagerie
drwxrwxr-x   2  mysqladm wheel     512 Jan 25 20:40 mysql
drwxrwxr-x   7  mysqladm wheel     512 Aug 31  1998 sql-bench
drwxrwxr-x   2  mysqladm wheel    1536 May  6 06:11 test
drwx------   2  mysqladm mysqlgrp 1024 May  8 18:43 tmp
....


正如你所看到的,有些資料庫有正確的權限,而其他不是。本例的情形是經過一段時間後的結果。較少限制的權限由在權限設定方面比更新版本更不嚴格的較早版本伺服器設定的(注意更具限制的目錄menageria和tmp都有較近日期)。 MySQL目前版本確保這些檔案只能由執行伺服器的使用者讀取。

讓我們來修正這些權限,使得只用伺服器使用者可存取它們。你主要的保護工具來自於UNIX檔案系統本身提供的設定檔和目錄屬主和模式的工具。以下是我們要做的:

進入該目錄
% cd DATADIR

設定所有在資料目錄下的檔案屬主為由用於運行伺服器的帳號擁有(你必須以root執行這一步)。在本文使用mysqladm和mysqlgrp作為該帳號的使用者名稱和群組名稱。你可以使用下列指令之一來改變屬主:
# chown mysqladm.mysqlgrp .

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

設定你的資料目錄和資料庫目錄的模式使得他們只能由mysqladm讀取,這阻止其他使用者存取你資料庫目錄的內容。你可以用下列命令之一以root或mysqladm身份運行。
% chmod -R go-rwx  .

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

資料目錄內容的屬主和模式為mysqladm設定。現在你應該保證你總是以mysqladm使用者執行伺服器,因為現在這是唯一由存取資料庫目錄權限的使用者(除root)。
在完成這些設定後,你最終應該得到下面的資料目錄權限:

% ls -l
total 10148
drwxrwx---  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 menagerie
drwx------   2  mysqladm mysqlgrp  512 Jan 25 20:40 mysql
drwx------   7  mysqladm mysqlgrp  512 Aug 31  1998 sql-bench
drwx------   2  mysqladm mysqlgrp 1536 May  6 06:11 test
drwx------   2  mysqladm mysqlgrp 1024 May  8 18:43 tmp
....



二、外部安全性-保證網路存取的安全
MySQL的安全系統是很靈活的,它允許你以多種不同方式設定使用者權限。一般地,你可使用標準的SQL語句GRANT和REVOKE語句做,他們為你修改控制客戶存取的授權表,然而,你可能由一個不支援這些語句的舊版的MySQL(在3.22.11之前這些語句不起作用),或者你發覺用戶權限看起來不是以你想要的方式工作。對於這種情況,了解MySQL授權表的結構和伺服器如何利用它們決定存取權限是有幫助的,這樣的了解允許你透過直接修改授權表增加、刪除或修改使用者權限,它也允許你在檢查這些表時診斷權限問題。

關於如何管理使用者帳號,請參閱《MySQL的使用者管理》。而對GRANT和REVOKE語句詳細描述,請參閱《MySQL參考手冊》。

2.1 MySQL授權表的結構和內容
透過網路連接伺服器的客戶對MySQL資料庫的存取由授權表內容來控制。這些表位於mysql資料庫中,並在第一次安裝MySQL的過程中初始化(執行mysql_install_db腳本)。授權表共有5個資料表:user、db、host、tables_priv和columns_priv。

表1 user、db和host授權表結構
存取範圍列

user db host
Host Host Host
User Db Db
Password User  
資料庫/表格權限列
Alter_priv Alter_priv Alter_priv
Create_priv Create_priv Create_priv
Delete_priv Delete_priv Delete_priv
Drop_priv Drop_priv Drop_priv
Index_priv Index_priv Index_priv
Insert_priv Insert_priv Insert_priv
References_priv References_priv References_priv
Select_priv Select_priv Select_priv
Update_priv Update_priv Update_priv
File_priv Grant_priv Grant_priv
Grant_priv   
Process_priv   
Reload_priv   
Shutdown_priv   
 
表2 tables_priv和columns_priv屬權表結構

存取範圍列
tables_priv  columns_priv
Host  Host
Db  Db
User  User
Table_name  Table_name
Column_name   
權限列
Table_priv  Column_priv

授權表的內容有以下用途:

user表
user表列出可以連接伺服器的使用者及其口令,並且它指定他們有哪種全域(超級使用者)權限。在user表啟用的任何權限均為全域權限,並適用於所有資料庫。例如,如果你啟用了DELETE權限,在這裡列出的用戶可以從任何表中刪除記錄,所以在你這樣做之前要認真考慮。
db表
db表列出資料庫,而使用者有權限存取它們。在這裡指定的權限適用於一個資料庫中的所有表。
host表
host表與db表結合使用在一個較好層次上控制特定主機對資料庫的存取權限,這可能比單獨使用db好些。這個表不受GRANT和REVOKE語句的影響,所以,你可能發覺你根本不是用它。
tables_priv表
tables_priv表指定表級權限,在這裡指定的一個權限適用於一個表的所有列。
columns_priv表
columns_priv表指定列級權限。這裡指定的權限適用於一個表格的特定欄位。
在「不用GRANT設定使用者」一節裡,我們再討論GRANT語句如何對修改這些表格運作,和你怎麼能透過直接修改授權表達到同樣的效果。

tables_priv和columns_priv表在MySQL 3.22.11版引進(與GRANT語句同時)。如果你有較早版本的MySQL,你的mysql資料庫將只有user、db和host表。如果你從舊版升級到3.22.11或更新,而沒有tables_priv和columns_priv表,執行mysql_fix_privileges_tables腳本來建立它們。

MySQL沒有rows_priv表,因為它不提供記錄級權限,例如,你不能限制用戶於表中包含特定列值的行。如果你確實需要這種能力,你必須用應用程式設計來提供。如果你想執行建議的記錄級鎖定,你可用GET_LOCK()函數做到。

授權表包含兩種欄位:決定一個權限何時運用的範圍列和決定授予哪種權限的權限列。

2.1.1 授權表範圍列
授權表範圍列指定表中的權限何時運用。每個授權表條目包含User和Host列來指定權限何時運送用於一個給定使用者從給定主機的連線。其他資料表包含附加的範圍列,如db表包含一個Db列指出權限運用於哪個資料庫。類似地,tables_priv和columns_priv表包含範圍字段,縮小範圍到一個資料庫中的特定表或一個表的特定列。

2.1.2 授權表權限列
授權表也包含權限列,他們指出在範圍列中指定的使用者擁有何種權限。由MySQL支援的權限如下表所示。表格使用GRANT語句的權限名稱。對於絕大多數在user、db和host表中的權限列的名稱與GRANT語句中有明顯的連結。如Select_priv對應於SELECT權限。

 以上是MySQL安全性指南 (1)(轉)內容,更多相關文章請關注PHP中文網(www.php.cn)! 


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn