MYSQL數據庫安全設置

數據庫做爲數據管理的平臺,它的安全性首先由系統的內部安全和網絡安全兩部分來決定。對於系統管理員來講,首先要保證系統自己的安全,在安裝MySQL數據庫時,須要對基礎環境進行較好的配置。

一、修改root用戶口令,刪除空口令
缺省安裝的MySQL的root用戶是空密碼的,爲了安全起見,必須修改成強密碼,所謂的強密碼,至少8位,由字母、數字和符號組成的不規律密碼。使用 MySQL自帶的命令mysaladmin修改root密碼,同時也能夠登錄數據庫,修改數據庫mysql下的user表的字段內容,修改方法以下所示:

# /usr/local/mysql/bin/mysqladmin -u root password 「upassword」 //使用mysqladmin
#mysql> use mysql;
#mysql> update user set password=password('upassword') where user='root';
#mysql> flush privileges; //強制刷新內存受權表,不然用的仍是在內存緩衝的口令

二、刪除默認數據庫和數據庫用戶
通常狀況下,MySQL數據庫安裝在本地,而且也只須要本地的php腳本對mysql進行讀取,因此不少用戶不須要,尤爲是默認安裝的用戶。MySQL初始化後會自動生成空用戶和test庫,進行安裝的測試,這會對數據庫的安全構成威脅,有必要所有刪除,最後的狀態只保留單個root便可,固然之後根據須要增長用戶和數據庫。

#mysql> show databases;
#mysql> drop database test; //刪除數據庫test
#use mysql;
#delete from db; //刪除存放數據庫的表信息,由於尚未數據庫信息。
#mysql> delete from user where not (user='root') ; // 刪除初始非root的用戶
#mysql> delete from user where user='root' and password=''; //刪除空密碼的root,儘可能重複操做
Query OK, 2 rows affected (0.00 sec)
#mysql> flush privileges; //強制刷新內存受權表。

三、改變默認mysql管理員賬號
系統mysql的管理員名稱是root,而通常狀況下,數據庫管理員都沒進行修改,這必定程度上對系統用戶窮舉的惡意行爲提供了便利,此時修改成複雜的用戶名,請不要在設定爲admin或者administraror的形式,由於它們也在易猜的用戶字典中。

mysql> update user set user="newroot" where user="root"; //改爲不易被猜想的用戶名
mysql> flush privileges;

四、關於密碼的管理
密碼是數據庫安全管理的一個很重要因素,不要將純文本密碼保存到數據庫中。若是你的計算機有安全危險,入侵者能夠得到全部的密碼並使用它們。相反,應使用 MD5()、SHA1()或單向哈希函數。也不要從詞典中選擇密碼,有專門的程序能夠破解它們,請選用至少八位,由字母、數字和符號組成的強密碼。在存取密碼時,使用mysql的內置函數password()的sql語句,對密碼進行加密後存儲。例如如下方式在users表中加入新用戶。

#mysql> insert into users values (1,password(1234),'test');

五、使用獨立用戶運行msyql
絕對不要做爲使用root用戶運行MySQL服務器。這樣作很是危險,由於任何具備FILE權限的用戶可以用root建立文件(例如,~root/.bashrc)。mysqld拒絕使用root運行,除非使用--user=root選項明顯指定。應該用普通非特權用戶運行 mysqld。正如前面的安裝過程同樣,爲數據庫創建獨立的linux中的mysql帳戶,該帳戶用來只用於管理和運行MySQL。

要想用其它Unix用戶啓動mysqld,,增長user選項指定/etc/my.cnf選項文件或服務器數據目錄的my.cnf選項文件中的[mysqld]組的用戶名。
#vi /etc/my.cnf
[mysqld]
user=mysql
該命令使服務器用指定的用戶來啓動,不管你手動啓動或經過mysqld_safe或mysql.server啓動,都能確保使用mysql的身份。也能夠在啓動數據庫是,加上user參數。

# /usr/local/mysql/bin/mysqld_safe --user=mysql &
做爲其它linux用戶而不用root運行mysqld,你不須要更改user表中的root用戶名,由於MySQL帳戶的用戶名與linux帳戶的用戶名無關。確保mysqld運行時,只使用對數據庫目錄具備讀或寫權限的linux用戶來運行。

六、禁止遠程鏈接數據庫
在命令行netstat -ant下看到,默認的3306端口是打開的,此時打開了mysqld的網絡監聽,容許用戶遠程經過賬號密碼鏈接數本地據庫,默認狀況是容許遠程鏈接數據的。爲了禁止該功能,啓動skip-networking,不監聽sql的任何TCP/IP的鏈接,切斷遠程訪問的權利,保證安全性。假如須要遠程管理數據庫,可經過安裝PhpMyadmin來實現。假如確實須要遠程鏈接數據庫,至少修改默認的監聽端口,同時添加防火牆規則,只容許可信任的網絡的 mysql監聽端口的數據經過。

# vi /etc/my.cf
將#skip-networking註釋去掉。
# /usr/local/mysql/bin/mysqladmin -u root -p shutdown //中止數據庫
#/usr/local/mysql/bin/mysqld_safe --user=mysql & //後臺用mysql用戶啓動mysql

七、限制鏈接用戶的數量
數據庫的某用戶屢次遠程鏈接,會致使性能的降低和影響其餘用戶的操做,有必要對其進行限制。能夠經過限制單個帳戶容許的鏈接數量來實現,設置my.cnf文件的mysqld中的max_user_connections變量來完成。GRANT語句也能夠支持 資源控制選項來限制服務器對一個帳戶容許的使用範圍。

#vi /etc/my.cnf
[mysqld]
max_user_connections 2

八、用戶目錄權限限制
默認的mysql是安裝在/usr/local/mysql,而對應的數據庫文件在/usr/local/mysql/var目錄下,所以,必須保證該目錄不能讓未經受權的用戶訪問後把數據庫打包拷貝走了,因此要限制對該目錄的訪問。確保mysqld運行時,只使用對數據庫目錄具備讀或寫權限的linux用戶來運行。
# chown -R root /usr/local/mysql/  //mysql主目錄給root
# chown -R mysql.mysql /usr/local/mysql/var //確保數據庫目錄權限所屬mysql用戶

九、命令歷史記錄保護
數據庫相關的shell操做命令都會分別記錄在.bash_history,若是這些文件不慎被讀取,會致使數據庫密碼和數據庫結構等信息泄露,而登錄數據庫後的操做將記錄在.mysql_history文件中,若是使用update表信息來修改數據庫用戶密碼的話,也會被讀取密碼,所以須要刪除這兩個文件,同時在進行登錄或備份數據庫等與密碼相關操做時,應該使用-p參數加入提示輸入密碼後,隱式輸入密碼,建議將以上文件置空。

# rm .bash_history .mysql_history //刪除歷史記錄
# ln -s /dev/null .bash_history  //將shell記錄文件置空
# ln -s /dev/null .mysql_history //將mysql記錄文件置空

十、禁止MySQL對本地文件存取
在mysql中,提供對本地文件的讀取,使用的是load data local infile命令,默認在5.0版本中,該選項是默認打開的,該操做令會利用MySQL把本地文件讀到數據庫中,而後用戶就能夠非法獲取敏感信息了,假如你不須要讀取本地文件,請務必關閉。

測試:首先在測試數據庫下創建sqlfile.txt文件,用逗號隔開各個字段
# vi sqlfile.txt
1,sszng,111
2,sman,222
#mysql> load data local infile 'sqlfile.txt' into table users fields terminated by ','; //讀入數據
#mysql> select * from users;
+--------+------------+----------+
| userid | username   | password |
+--------+------------+----------+
|     1 | sszng    | 111   |
|     2 | sman    | 222  |
+--------+------------+----------+ 

成功的將本地數據插入數據中,此時應該禁止MySQL中用「LOAD DATA LOCAL INFILE」命令。網絡上流傳的一些攻擊方法中就有用它LOAD DATA LOCAL INFILE的,同時它也是不少新發現的SQL Injection攻擊利用的手段!黑客還能經過使用LOAD DATALOCAL INFILE裝載「/etc/passwd」進一個數據庫表,而後能用SELECT顯示它,這個操做對服務器的安全來講,是致命的。能夠在my.cnf中添加local-infile=0,或者加參數local-infile=0啓動mysql。

#/usr/local/mysql/bin/mysqld_safe --user=mysql --local-infile=0 &
#mysql> load data local infile 'sqlfile.txt' into table users fields terminated by ',';
#ERROR 1148 (42000): The used command is not allowed with this MySQL version

--local-infile=0選項啓動mysqld從服務器端禁用全部LOAD DATA LOCAL命令,假如須要獲取本地文件,須要打開,可是建議關閉。

十一、MySQL服務器權限控制
MySQL 權限系統的主要功能是證明鏈接到一臺給定主機的用戶,而且賦予該用戶在數據庫上的SELECT、INSERT、UPDATE和DELETE等權限(詳見 user超級用戶表)。它的附加的功能包括有匿名的用戶並對於MySQL特定的功能例如LOAD DATA INFILE進行受權及管理操做的能力。

管理員能夠對user,db,host等表進行配置,來控制用戶的訪問權限,而user表權限是超級用戶權限。只把user表的權限授予超級用戶如服務器或數據庫主管是明智的。對其餘用戶,你應該把在user表中的權限設成'N'而且僅在特定數據庫的基礎上受權。你能夠爲特定的數據庫、表或列受權,FILE 權限給予你用LOAD DATA INFILE和SELECT ... INTO OUTFILE語句讀和寫服務器上的文件,任何被授予FILE權限的用戶都能讀或寫MySQL服務器能讀或寫的任何文件。(說明用戶能夠讀任何數據庫目錄下的文件,由於服務器能夠訪問這些文件)。 FILE權限容許用戶在MySQL服務器具備寫權限的目錄下建立新文件,但不能覆蓋已有文件在user表的File_priv設置Y或N。,因此當你不須要對服務器文件讀取時,請關閉該權限。

#mysql> load data infile 'sqlfile.txt' into table loadfile.users fields terminated by ',';
Query OK, 4 rows affected (0.00 sec) //讀取本地信息sqlfile.txt'
Records: 4 Deleted: 0  Skipped: 0  Warnings: 0
#mysql> update user set File_priv='N' where user='root'; //禁止讀取權限
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1  Warnings: 0
mysql> flush privileges; //刷新受權表
Query OK, 0 rows affected (0.00 sec)
#mysql> load data infile 'sqlfile.txt' into table users fields terminated by ','; //重登錄讀取文件
#ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) //失敗
# mysql> select * from loadfile.users into outfile 'test.txt' fields terminated by ',';
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
爲了安全起見,隨時使用SHOW GRANTS語句檢查查看誰已經訪問了什麼。而後使用REVOKE語句刪除再也不須要的權限。

十二、使用chroot方式來控制MySQL的運行目錄
Chroot是linux中的一種系統高級保護手段,它的創建會將其與主系統幾乎徹底隔離,也就是說,一旦遭到什麼問題,也不會危及到正在運行的主系統。這是一個很是有效的辦法,特別是在配置網絡服務程序的時候。

1三、關閉對Web訪問的支持
若是不打算讓Web訪問使用MySQL數據庫,沒有提供諸如 PHP 這樣的Web語言的時候,從新設置或編譯你的PHP,取消它們對MySQL的默認支持。假如服務器中使用php等web程序,試試用Web形式非法的請求,若是獲得任何形式的MySQL錯誤,當即分析緣由,及時修改Web程序,堵住漏洞,防止 MySQL暴露在web面前。
對於Web的安全檢查,在MySQL官方文檔中這麼建議,對於web應用,至少檢查如下清單:
  試試用Web形式輸入單引號和雙引號(‘'’和‘"’)。若是獲得任何形式的MySQL錯誤,當即分析緣由。
  試試修改動態URL,能夠在其中添加%22(‘"’)、%23(‘#’)和%27(‘'’)。
  試試在動態URL中修改數據類型,使用前面示例中的字符,包括數字和字符類型。你的應用程序應足夠安全,能夠防範此類修改和相似攻擊。
  試試輸入字符、空格和特殊符號,不要輸入數值字段的數字。你的應用程序應在將它們傳遞到MySQL以前將它們刪除或生成錯誤。將未通過檢查的值傳遞給MySQL是很危險的!
  將數據傳給MySQL以前先檢查其大小。
  用管理帳戶以外的用戶名將應用程序鏈接到數據庫。不要給應用程序任何不須要的訪問權限。

1四、數據庫備份策略
通常可採用本地備份和網絡備份的形式,可採用MySQL自己自帶的mysqldump的方式和直接複製備份形式,

直接拷貝數據文件最爲直接、快速、方便,但缺點是基本上不能實現增量備份。爲了保證數據的一致性,須要在備份文件前,執行如下 SQL 語句:FLUSH TABLES WITH READ LOCK;也就是把內存中的數據都刷新到磁盤中,同時鎖定數據表,以保證拷貝過程當中不會有新的數據寫入。這種方法備份出來的數據恢復也很簡單,直接拷貝回原來的數據庫目錄下便可。

使用mysqldump能夠把整個數據庫裝載到一個單獨的文本文件中。這個文件包含有全部重建您的數據庫所須要的SQL命令。這個命令取得全部的模式(Schema,後面有解釋)而且將其轉換成DDL語法(CREATE語句,即數據庫定義語句),取得全部的數據,而且從這些數據中建立INSERT語句。這個工具將您的數據庫中全部的設計倒轉。由於全部的東西都被包含到了一個文本文件中。這個文本文件能夠用一個簡單的批處理和一個合適SQL語句導回到MySQL中。

使用 mysqldump進行備份很是簡單,若是要備份數據庫」 nagios_db_backup 」,使用命令,同時使用管道gzip命令對備份文件進行壓縮,建議使用異地備份的形式,能夠採用Rsync等方式,將備份服務器的目錄掛載到數據庫服務器,將數據庫文件備份打包在,經過crontab定時備份數據:

#!/bin/sh
time=`date +"("%F")"%R`
$/usr/local/mysql/bin/mysqldump -u nagios -pnagios nagios | gzip >/home/sszheng/nfs58/nagiosbackup/nagios_backup.$time.gz
# crontab -l
# m h dom mon dow   command
00 00 * * * /home/sszheng/shnagios/backup.sh

恢復數據使用命令:
gzip -d nagios_backup./(2008-01-24/)00/:00.gz
nagios_backup.(2008-01-24)00:00
#mysql –u root -p nagios      <  /home/sszheng/nfs58/nagiosbackup/nagios_backup./(2008-01-24/)12/:00


3、Mysqld安全相關啓動選項
下列mysqld選項影響安全:
  --allow-suspicious-udfs
該選項控制是否能夠載入主函數只有xxx符的用戶定義函數。默認狀況下,該選項被關閉,而且只能載入至少有輔助符的UDF。這樣能夠防止從未包含合法UDF的共享對象文件載入函數。
  --local-infile[={0|1}]
若是用--local-infile=0啓動服務器,則客戶端不能使用LOCAL in LOAD DATA語句。
  --old-passwords
強制服務器爲新密碼生成短(pre-4.1)密碼哈希。當服務器必須支持舊版本客戶端程序時,爲了保證兼容性這頗有用。
   (OBSOLETE) --safe-show-database
在之前版本的MySQL中,該選項使SHOW DATABASES語句只顯示用戶具備部分權限的數據庫名。在MySQL 5.1中,該選項再也不做爲如今的 默認行爲使用,有一個SHOW DATABASES權限能夠用來控制每一個帳戶對數據庫名的訪問。
  --safe-user-create
若是啓用,用戶不能用GRANT語句建立新用戶,除非用戶有mysql.user表的INSERT權限。若是你想讓用戶具備受權權限來建立新用戶,你應給用戶授予下面的權限:
mysql> GRANT INSERT(user) ON mysql.user TO 'user_name'@'host_name';
這樣確保用戶不能直接更改權限列,必須使用GRANT語句給其它用戶授予該權限。
  --secure-auth
不容許鑑定有舊(pre-4.1)密碼的帳戶。
  --skip-grant-tables
這個選項致使服務器根本不使用權限系統。這給每一個人以徹底訪問全部的數據庫的權力!(經過執行mysqladmin flush-privileges或mysqladmin eload命令,或執行FLUSH PRIVILEGES語句,你能告訴一個正在運行的服務器再次開始使用受權表。)
  --skip-name-resolve
主機名不被解析。全部在受權表的Host的列值必須是IP號或localhost。
  --skip-networking
在網絡上不容許TCP/IP鏈接。全部到mysqld的鏈接必須經由Unix套接字進行。
  -skip-show-database
使用該選項,只容許有SHOW DATABASES權限的用戶執行SHOW DATABASES語句,該語句顯示全部數據庫名。不使用該選項,容許全部用戶執行SHOW DATABASES,但只顯示用戶有SHOW DATABASES權限或部分數據庫權限的數據庫名。請注意全局權限指數據庫的權限。
相關文章
相關標籤/搜索