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