MySQL安全設置與配置
數據庫作爲數據管理的平台,它的安全性首先由系統的内部安全和網絡安全兩(liǎng)部分來決定。對(duì)于系統管理員來說(shuō),首先要保證系統本身的安全,在安裝MySQL數據庫時(shí),需要對(duì)基礎環境進(jìn)行較好(hǎo)的配置。
1、修改root用戶口令,删除空口令
缺
省安裝的MySQL的root用戶是空密碼的,爲了安全起(qǐ)見,必須修改爲強密碼,所謂的強密碼,至少8位,由字母、數字和符号組成(chéng)的不規律密碼。使用
MySQL自帶的命令mysaladmin修改root密碼,同時(shí)也可以登陸數據庫,修改數據庫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; //強制刷新内存授權表,否則用的還(hái)是在内存緩沖的口令
2、删除默認數據庫和數據庫用戶
一
般情況下,MySQL數據庫安裝在本地,并且也隻需要本地的php腳本對(duì)mysql進(jìn)行讀取,所以很多用戶不需要,尤其是默認安裝的用戶。MySQL初始
化後(hòu)會(huì)自動生成(chéng)空用戶和test庫,進(jìn)行安裝的測試,這(zhè)會(huì)對(duì)數據庫的安全構成(chéng)威脅,有必要全部删除,最後(hòu)的狀态隻保留單個root即可,當然以後(hòu)根據需要
增加用戶和數據庫。
#mysql> show databases;
#mysql> drop database test; //删除數據庫test
#use mysql;
#delete from db; //删除存放數據庫的表信息,因爲還(hái)沒(méi)有數據庫信息。
#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; //強制刷新内存授權表。
3、改變默認mysql管理員帳号
系統mysql的管理員名稱是root,而一般情況下,數據庫管理員都(dōu)沒(méi)進(jìn)行修改,這(zhè)一定程度上對(duì)系統用戶窮舉的惡意行爲提供了便利,此時(shí)修改爲複雜的用戶名,請不要在設定爲admin或者administraror的形式,因爲它們也在易猜的用戶字典中。
mysql> update user set user="newroot" where user="root"; //改成(chéng)不易被(bèi)猜測的用戶名
mysql> flush privileges;
4、關于密碼的管理
密
碼是數據庫安全管理的一個很重要因素,不要將(jiāng)純文本密碼保存到數據庫中。如果你的計算機有安全危險,入侵者可以獲得所有的密碼并使用它們。相反,應使用
MD5()、SHA1()或單向(xiàng)哈希函數。也不要從詞典中選擇密碼,有專門的程序可以破解它們,請選用至少八位,由字母、數字和符号組成(chéng)的強密碼。在存取
密碼時(shí),使用mysql的内置函數password()的sql語句,對(duì)密碼進(jìn)行加密後(hòu)存儲。例如以下方式在users表中加入新用戶。
#mysql> insert into users values (1,password(1234),'test');
5、使用獨立用戶運行msyql
絕
對(duì)不要作爲使用root用戶運行MySQL服務器。這(zhè)樣(yàng)做非常危險,因爲任何具有FILE權限的用戶能(néng)夠用root創建文件(例
如,~root/.bashrc)。mysqld拒絕使用root運行,除非使用--user=root選項明顯指定。應該用普通非特權用戶運行
mysqld。正如前面(miàn)的安裝過(guò)程一樣(yàng),爲數據庫建立獨立的linux中的mysql賬戶,該賬戶用來隻用于管理和運行MySQL。
要想用其它Unix用戶啓動mysqld,,增加user選項指定/etc/my.cnf選項文件或服務器數據目錄的my.cnf選項文件中的 [mysqld]組的用戶名。
#vi /etc/my.cnf
[mysqld]
user=mysql
該命令使服務器用指定的用戶來啓動,無論你手動啓動或通過(guò)mysqld_safe或mysql.server啓動,都(dōu)能(néng)确保使用mysql的身份。也可以在啓動數據庫是,加上user參數。
# /usr/local/mysql/bin/mysqld_safe --user=mysql &
作爲其它linux用戶而不用root運行mysqld,你不需要更改user表中的root用戶名,因爲MySQL賬戶的用戶名與linux賬戶的用戶名無關。确保mysqld運行時(shí),隻使用對(duì)數據庫目錄具有讀或寫權限的linux用戶來運行。
6、禁止遠程連接數據庫
在
命令行netstat
-ant下看到,默認的3306端口是打開(kāi)的,此時(shí)打開(kāi)了mysqld的網絡監聽,允許用戶遠程通過(guò)帳号密碼連接數本地據庫,默認情況是允許遠程連接數據
的。爲了禁止該功能(néng),啓動skip-networking,不監聽sql的任何TCP/IP的連接,切斷遠程訪問的權利,保證安全性。假如需要遠程管理數
據庫,可通過(guò)安裝PhpMyadmin來實現。假如确實需要遠程連接數據庫,至少修改默認的監聽端口,同時(shí)添加防火牆規則,隻允許可信任的網絡的 mysql監聽端口的數據通過(guò)。
# vi /etc/my.cf
將(jiāng)#skip-networking注釋去掉。
#/usr/local/mysql/bin/mysqladmin -u root -p shutdown //停止數據庫
#/usr/local/mysql/bin/mysqld_safe --user=mysql & //後(hòu)台用mysql用戶啓動mysql
7、限制連接用戶的數量
數
據庫的某用戶多次遠程連接,會(huì)導緻性能(néng)的下降和影響其他用戶的操作,有必要對(duì)其進(jìn)行限制。可以通過(guò)限制單個賬戶允許的連接數量來實現,設置my.cnf
文件的mysqld中的max_user_connections變量來完成(chéng)。GRANT語句也可以支持
資源控制選項來限制服務器對(duì)一個賬戶允許的使用範圍。
#vi /etc/my.cnf
[mysqld]
max_user_connections 2
8、用戶目錄權限限制
默
認的mysql是安裝在/usr/local/mysql,而對(duì)應的數據庫文件在/usr/local/mysql/var目錄下,因此,必須保證該目錄
不能(néng)讓未經(jīng)授權的用戶訪問後(hòu)把數據庫打包拷貝走了,所以要限制對(duì)該目錄的訪問。确保mysqld運行時(shí),隻使用對(duì)數據庫目錄具有讀或寫權限的linux
用戶來運行。
# chown -R root /usr/local/mysql/ //mysql主目錄給root
# chown -R mysql.mysql /usr/local/mysql/var //确保數據庫目錄權限所屬mysql用戶
9、命令曆史記錄保護
數
據庫相關的shell操作命令都(dōu)會(huì)分别記錄在.bash_history,如果這(zhè)些文件不慎被(bèi)讀取,會(huì)導緻數據庫密碼和數據庫結構等信息洩露,而登陸數據
庫後(hòu)的操作將(jiāng)記錄在.mysql_history文件中,如果使用update表信息來修改數據庫用戶密碼的話,也會(huì)被(bèi)讀取密碼,因此需要删除這(zhè)兩(liǎng)個文
件,同時(shí)在進(jìn)行登陸或備份數據庫等與密碼相關操作時(shí),應該使用-p參數加入提示輸入密碼後(hòu),隐式輸入密碼,建議將(jiāng)以上文件置空。
# rm .bash_history .mysql_history //删除曆史記錄
# ln -s /dev/null .bash_history //將(jiāng)shell記錄文件置空
# ln -s /dev/null .mysql_history //將(jiāng)mysql記錄文件置空
10、禁止MySQL對(duì)本地文件存取
在mysql中,提供對(duì)本地文件的讀取,使用的是load data local infile命令,默認在5.0版本中,該選項是默認打開(kāi)的,該操作令會(huì)利用MySQL把本地文件讀到數據庫中,然後(hòu)用戶就(jiù)可以非法獲取敏感信息了,假如你不需要讀取本地文件,請務必關閉。
測試:首先在測試數據庫下建立sqlfile.txt文件,用逗号隔開(kāi)各個字段
# 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 |
+--------+------------+----------+
成(chéng)
功的將(jiāng)本地數據插入數據中,此時(shí)應該禁止MySQL中用“LOAD DATA LOCAL
INFILE”命令。網絡上流傳的一些攻擊方法中就(jiù)有用它LOAD DATA LOCAL INFILE的,同時(shí)它也是很多新發(fā)現的SQL
Injection攻擊利用的手段!黑客還(hái)能(néng)通過(guò)使用LOAD DATALOCAL
INFILE裝載“/etc/passwd”進(jìn)一個數據庫表,然後(hòu)能(néng)用SELECT顯示它,這(zhè)個操作對(duì)服務器的安全來說(shuō),是緻命的。可以在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命令,假如需要獲取本地文件,需要打開(kāi),但是建議關閉。
11、MySQL服務器權限控制
MySQL
權限系統的主要功能(néng)是證實連接到一台給定主機的用戶,并且賦予該用戶在數據庫上的SELECT、INSERT、UPDATE和DELETE等權限(詳見
user超級用戶表)。它的附加的功能(néng)包括有匿名的用戶并對(duì)于MySQL特定的功能(néng)例如LOAD DATA INFILE進(jìn)行授權及管理操作的能(néng)力。
管
理員可以對(duì)user,db,host等表進(jìn)行配置,來控制用戶的訪問權限,而user表權限是超級用戶權限。隻把user表的權限授予超級用戶如服務器或
數據庫主管是明智的。對(duì)其他用戶,你應該把在user表中的權限設成(chéng)'N'并且僅在特定數據庫的基礎上授權。你可以爲特定的數據庫、表或列授權,FILE
權限給予你用LOAD DATA INFILE和SELECT ... INTO
OUTFILE語句讀和寫服務器上的文件,任何被(bèi)授予FILE權限的用戶都(dōu)能(néng)讀或寫MySQL服務器能(néng)讀或寫的任何文件。(說(shuō)明用戶可以讀任何數據庫目錄
下的文件,因爲服務器可以訪問這(zhè)些文件)。
FILE權限允許用戶在MySQL服務器具有寫權限的目錄下創建新文件,但不能(néng)覆蓋已有文件在user表的File_priv設置Y或N。,所以當你不需
要對(duì)服務器文件讀取時(shí),請關閉該權限。
#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)
爲了安全起(qǐ)見,随時(shí)使用SHOW GRANTS語句檢查查看誰已經(jīng)訪問了什麼(me)。然後(hòu)使用REVOKE語句删除不再需要的權限。
12、使用chroot方式來控制MySQL的運行目錄
Chroot是linux中的一種(zhǒng)系統高級保護手段,它的建立會(huì)將(jiāng)其與主系統幾乎完全隔離,也就(jiù)是說(shuō),一旦遭到什麼(me)問題,也不會(huì)危及到正在運行的主系統。這(zhè)是一個非常有效的辦法,特别是在配置網絡服務程序的時(shí)候。
13、關閉對(duì)Web訪問的支持
如
果不打算讓Web訪問使用MySQL數據庫,沒(méi)有提供諸如PHP這(zhè)樣(yàng)的Web語言的時(shí)候,重新設置或編譯你的PHP,取消它們對(duì)MySQL的默認支持。假
如服務器中使用php等web程序,試試用Web形式非法的請求,如果得到任何形式的MySQL錯誤,立即分析原因,及時(shí)修改Web程序,堵住漏洞,防止
MySQL暴露在web面(miàn)前。
對(duì)于Web的安全檢查,在MySQL官方文檔中這(zhè)麼(me)建議,對(duì)于web應用,至少檢查以下清單:
試試用Web形式輸入單引号和雙引号(‘'’和‘"’)。如果得到任何形式的MySQL錯誤,立即分析原因。
試試修改動态URL,可以在其中添加%22(‘"’)、%23(‘#’)和%27(‘'’)。
試試在動态URL中修改數據類型,使用前面(miàn)示例中的字符,包括數字和字符類型。你的應用程序應足夠安全,可以防範此類修改和類似攻擊。
試試輸入字符、空格和特殊符号,不要輸入數值字段的數字。你的應用程序應在將(jiāng)它們傳遞到MySQL之前將(jiāng)它們删除或生成(chéng)錯誤。將(jiāng)未經(jīng)過(guò)檢查的值傳遞給 MySQL是很危險的!
將(jiāng)數據傳給MySQL之前先檢查其大小。
用管理賬戶之外的用戶名將(jiāng)應用程序連接到數據庫。不要給應用程序任何不需要的訪問權限。
14、數據庫備份策略
一般可采用本地備份和網絡備份的形式,可采用MySQL本身自帶的mysqldump的方式和直接複制備份形式,
直
接拷貝數據文件最爲直接、快速、方便,但缺點是基本上不能(néng)實現增量備份。爲了保證數據的一緻性,需要在備份文件前,執行以下 SQL 語句:FLUSH
TABLES WITH READ
LOCK;也就(jiù)是把内存中的數據都(dōu)刷新到磁盤中,同時(shí)鎖定數據表,以保證拷貝過(guò)程中不會(huì)有新的數據寫入。這(zhè)種(zhǒng)方法備份出來的數據恢複也很簡單,直接拷貝回
原來的數據庫目錄下即可。
使用mysqldump可以把整個數據庫裝載到一個單獨的文本文件中。這(zhè)個文件包含有所有重建您的數據庫所需要
的SQL命令。這(zhè)個命令取得所有的模式(Schema,後(hòu)面(miàn)有解釋)并且將(jiāng)其轉換成(chéng)DDL語法(CREATE語句,即數據庫定義語句),取得所有的數據,
并且從這(zhè)些數據中創建INSERT語句。這(zhè)個工具將(jiāng)您的數據庫中所有的設計倒轉。因爲所有的東西都(dōu)被(bèi)包含到了一個文本文件中。這(zhè)個文本文件可以用一個簡單
的批處理和一個合适SQL語句導回到 MySQL中。
使用 mysqldump進(jìn)行備份非常簡單,如果要備份數據庫”
nagios_db_backup
”,使用命令,同時(shí)使用管道(dào)gzip命令對(duì)備份文件進(jìn)行壓縮,建議使用異地備份的形式,可以采用Rsync等方式,將(jiāng)備份服務器的目錄挂載到數據庫服務
器,將(jiāng)數據庫文件備份打包在,通過(guò)crontab定時(shí)備份數據:
#!/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
本文由錦江區聚格樂享網絡工作室獨家撰寫,嚴禁轉載。