MySQL安全配置詳解

一、MySQL安裝

MySQL可以在redhat環(huán)境下進(jìn)行RPM安裝和debian下apt安裝,但是最新的包一般都是源碼的形式,因此這里選擇源碼編譯安裝的方式。
首先登陸官方網(wǎng)站http://www.mysql.com,下載最新的released版本。

# tar zxf mysql-5.1.22-rc-linux-i686-glibc23.tar.gz
為mysql的運(yùn)行建立mysql用戶和mysql用戶組
#groupadd mysql
# useradd -g mysql mysql
# ./configure --prefix=/usr/local/mysql
#make
#make install
# cp support-files/my-medium.cnf /etc/my.cf
# bin/mysql_install_db --user=mysql //用mysql生成初始數(shù)據(jù)庫,出現(xiàn)類似thank for using mysql 證明初始化數(shù)據(jù)庫成功。
# chown -R root .  //當(dāng)前目錄給root
# chown -R mysql var //var給mysql,這個(gè)很重要,也是安全起見
# chgrp -R mysql .
# bin/mysqld_safe --user=mysql &
#bin/mysql –u root

此時(shí)安全完畢,但是最重要是對MySQL進(jìn)行安全配置,檢查你的系統(tǒng),最基本要做到以下配置。

二、MySQL安全配置

數(shù)據(jù)庫作為數(shù)據(jù)管理的平臺,它的安全性首先由系統(tǒng)的內(nèi)部安全和網(wǎng)絡(luò)安全兩部分來決定。對于系統(tǒng)管理員來說,首先要保證系統(tǒng)本身的安全,在安裝MySQL數(shù)據(jù)庫時(shí),需要對基礎(chǔ)環(huán)境進(jìn)行較好的配置。

1、修改root用戶口令,刪除空口令

缺省安裝的MySQL的root用戶是空密碼的,為了安全起見,必須修改為強(qiáng)密碼,所謂的強(qiáng)密碼,至少8位,由字母、數(shù)字和符號組成的不規(guī)律密碼。使用MySQL自帶的命令mysaladmin修改root密碼,同時(shí)也可以登陸數(shù)據(jù)庫,修改數(shù)據(jù)庫mysql下的user表的字段內(nèi)容,修改方法如下所示:

# /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; //強(qiáng)制刷新內(nèi)存授權(quán)表,否則用的還是在內(nèi)存緩沖的口令

2、刪除默認(rèn)數(shù)據(jù)庫和數(shù)據(jù)庫用戶

一般情況下,MySQL數(shù)據(jù)庫安裝在本地,并且也只需要本地的php腳本對mysql進(jìn)行讀取,所以很多用戶不需要,尤其是默認(rèn)安裝的用戶。MySQL初始化后會(huì)自動(dòng)生成空用戶和test庫,進(jìn)行安裝的測試,這會(huì)對數(shù)據(jù)庫的安全構(gòu)成威脅,有必要全部刪除,最后的狀態(tài)只保留單個(gè)root即可,當(dāng)然以后根據(jù)需要增加用戶和數(shù)據(jù)庫。

#mysql> show databases;
#mysql> drop database test; //刪除數(shù)據(jù)庫test
#use mysql;
#delete from db; //刪除存放數(shù)據(jù)庫的表信息,因?yàn)檫€沒有數(shù)據(jù)庫信息。
#mysql> delete from user where not (user='root') ; // 刪除初始非root的用戶
#mysql> delete from user where user='root' and password=''; //刪除空密碼的root,盡量重復(fù)操作
Query OK, 2 rows affected (0.00 sec)
#mysql> flush privileges; //強(qiáng)制刷新內(nèi)存授權(quán)表。

3、改變默認(rèn)mysql管理員帳號

系統(tǒng)mysql的管理員名稱是root,而一般情況下,數(shù)據(jù)庫管理員都沒進(jìn)行修改,這一定程度上對系統(tǒng)用戶窮舉的惡意行為提供了便利,此時(shí)修改為復(fù)雜的用戶名,請不要在設(shè)定為admin或者administraror的形式,因?yàn)樗鼈円苍谝撞碌挠脩糇值渲小?/p>

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

4、關(guān)于密碼的管理

密碼是數(shù)據(jù)庫安全管理的一個(gè)很重要因素,不要將純文本密碼保存到數(shù)據(jù)庫中。如果你的計(jì)算機(jī)有安全危險(xiǎn),入侵者可以獲得所有的密碼并使用它們。相反,應(yīng)使用MD5()、SHA1()或單向哈希函數(shù)。也不要從詞典中選擇密碼,有專門的程序可以破解它們,請選用至少八位,由字母、數(shù)字和符號組成的強(qiáng)密碼。在存取密碼時(shí),使用mysql的內(nèi)置函數(shù)password()的sql語句,對密碼進(jìn)行加密后存儲。例如以下方式在users表中加入新用戶。

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

5、使用獨(dú)立用戶運(yùn)行msyql

絕對不要作為使用root用戶運(yùn)行MySQL服務(wù)器。這樣做非常危險(xiǎn),因?yàn)槿魏尉哂蠪ILE權(quán)限的用戶能夠用root創(chuàng)建文件(例如,~root/.bashrc)。mysqld拒絕使用root運(yùn)行,除非使用–user=root選項(xiàng)明顯指定。應(yīng)該用普通非特權(quán)用戶運(yùn)行mysqld。正如前面的安裝過程一樣,為數(shù)據(jù)庫建立獨(dú)立的linux中的mysql賬戶,該賬戶用來只用于管理和運(yùn)行MySQL。

要想用其它Unix用戶啟動(dòng)mysqld,,增加user選項(xiàng)指定/etc/my.cnf選項(xiàng)文件或服務(wù)器數(shù)據(jù)目錄的my.cnf選項(xiàng)文件中的[mysqld]組的用戶名。

#vim /etc/my.cnf
[mysqld]
user=mysql

該命令使服務(wù)器用指定的用戶來啟動(dòng),無論你手動(dòng)啟動(dòng)或通過mysqld_safe或mysql.server啟動(dòng),都能確保使用mysql的身份。也可以在啟動(dòng)數(shù)據(jù)庫是,加上user參數(shù)。

# /usr/local/mysql/bin/mysqld_safe --user=mysql &

作為其它linux用戶而不用root運(yùn)行mysqld,你不需要更改user表中的root用戶名,因?yàn)镸ySQL賬戶的用戶名與linux賬戶的用戶名無關(guān)。確保mysqld運(yùn)行時(shí),只使用對數(shù)據(jù)庫目錄具有讀或?qū)憴?quán)限的linux用戶來運(yùn)行。

6、禁止遠(yuǎn)程連接數(shù)據(jù)庫

在命令行netstat -ant下看到,默認(rèn)的3306端口是打開的,此時(shí)打開了mysqld的網(wǎng)絡(luò)監(jiān)聽,允許用戶遠(yuǎn)程通過帳號密碼連接數(shù)本地?fù)?jù)庫,默認(rèn)情況是允許遠(yuǎn)程連接數(shù)據(jù)的。為了禁止該功能,啟動(dòng)skip-networking,不監(jiān)聽sql的任何TCP/IP的連接,切斷遠(yuǎn)程訪問的權(quán)利,保證安全性。假如需要遠(yuǎn)程管理數(shù)據(jù)庫,可通過安裝PhpMyadmin來實(shí)現(xiàn)。假如確實(shí)需要遠(yuǎn)程連接數(shù)據(jù)庫,至少修改默認(rèn)的監(jiān)聽端口,同時(shí)添加防火墻規(guī)則,只允許可信任的網(wǎng)絡(luò)的mysql監(jiān)聽端口的數(shù)據(jù)通過。

# vim /etc/my.cf
將#skip-networking注釋去掉。
# /usr/local/mysql/bin/mysqladmin -u root -p shutdown //停止數(shù)據(jù)庫
#/usr/local/mysql/bin/mysqld_safe --user=mysql & //后臺用mysql用戶啟動(dòng)mysql

7、限制連接用戶的數(shù)量

數(shù)據(jù)庫的某用戶多次遠(yuǎn)程連接,會(huì)導(dǎo)致性能的下降和影響其他用戶的操作,有必要對其進(jìn)行限制??梢酝ㄟ^限制單個(gè)賬戶允許的連接數(shù)量來實(shí)現(xiàn),設(shè)置my.cnf文件的mysqld中的max_user_connections變量來完成。GRANT語句也可以支持 資源控制選項(xiàng)來限制服務(wù)器對一個(gè)賬戶允許的使用范圍。

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

8、用戶目錄權(quán)限限制

默認(rèn)的mysql是安裝在/usr/local/mysql,而對應(yīng)的數(shù)據(jù)庫文件在/usr/local/mysql/var目錄下,因此,必須保證該目錄不能讓未經(jīng)授權(quán)的用戶訪問后把數(shù)據(jù)庫打包拷貝走了,所以要限制對該目錄的訪問。確保mysqld運(yùn)行時(shí),只使用對數(shù)據(jù)庫目錄具有讀或?qū)憴?quán)限的linux用戶來運(yùn)行。

# chown -R root  /usr/local/mysql/  //mysql主目錄給root
# chown -R mysql.mysql /usr/local/mysql/var //確保數(shù)據(jù)庫目錄權(quán)限所屬mysql用戶

9、命令歷史記錄保護(hù)

數(shù)據(jù)庫相關(guān)的shell操作命令都會(huì)分別記錄在.bash_history,如果這些文件不慎被讀取,會(huì)導(dǎo)致數(shù)據(jù)庫密碼和數(shù)據(jù)庫結(jié)構(gòu)等信息泄露,而登陸數(shù)據(jù)庫后的操作將記錄在.mysql_history文件中,如果使用update表信息來修改數(shù)據(jù)庫用戶密碼的話,也會(huì)被讀取密碼,因此需要?jiǎng)h除這兩個(gè)文件,同時(shí)在進(jìn)行登陸或備份數(shù)據(jù)庫等與密碼相關(guān)操作時(shí),應(yīng)該使用-p參數(shù)加入提示輸入密碼后,隱式輸入密碼,建議將以上文件置空。

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

10、禁止MySQL對本地文件存取

在mysql中,提供對本地文件的讀取,使用的是load data local infile命令,默認(rèn)在5.0版本中,該選項(xiàng)是默認(rèn)打開的,該操作令會(huì)利用MySQL把本地文件讀到數(shù)據(jù)庫中,然后用戶就可以非法獲取敏感信息了,假如你不需要讀取本地文件,請務(wù)必關(guān)閉。

測試:首先在測試數(shù)據(jù)庫下建立sqlfile.txt文件,用逗號隔開各個(gè)字段

# vi sqlfile.txt
1,sszng,111
2,sman,222
#mysql> load data local infile 'sqlfile.txt' into table users fields terminated by ','; //讀入數(shù)據(jù)
#mysql> select * from users;
+--------+------------+----------+
| userid  | username   | password |
+--------+------------+----------+
|      1 | sszng    | 111   |
|      2 | sman    | 222  |
+--------+------------+----------+

成功的將本地?cái)?shù)據(jù)插入數(shù)據(jù)中,此時(shí)應(yīng)該禁止MySQL中用“LOAD DATA LOCAL INFILE”命令。網(wǎng)絡(luò)上流傳的一些攻擊方法中就有用它LOAD DATA LOCAL INFILE的,同時(shí)它也是很多新發(fā)現(xiàn)的SQL Injection攻擊利用的手段!黑客還能通過使用LOAD DATALOCAL INFILE裝載“/etc/passwd”進(jìn)一個(gè)數(shù)據(jù)庫表,然后能用SELECT顯示它,這個(gè)操作對服務(wù)器的安全來說,是致命的??梢栽趍y.cnf中添加local-infile=0,或者加參數(shù)local-infile=0啟動(dòng)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選項(xiàng)啟動(dòng)mysqld從服務(wù)器端禁用所有LOAD DATA LOCAL命令,假如需要獲取本地文件,需要打開,但是建議關(guān)閉。

11、MySQL服務(wù)器權(quán)限控制

MySQL權(quán)限系統(tǒng)的主要功能是證實(shí)連接到一臺給定主機(jī)的用戶,并且賦予該用戶在數(shù)據(jù)庫上的SELECT、INSERT、UPDATE和DELETE等權(quán)限(詳見user超級用戶表)。它的附加的功能包括有匿名的用戶并對于MySQL特定的功能例如LOAD DATA INFILE進(jìn)行授權(quán)及管理操作的能力。

管理員可以對user,db,host等表進(jìn)行配置,來控制用戶的訪問權(quán)限,而user表權(quán)限是超級用戶權(quán)限。只把user表的權(quán)限授予超級用戶如服務(wù)器或數(shù)據(jù)庫主管是明智的。對其他用戶,你應(yīng)該把在user表中的權(quán)限設(shè)成’N’并且僅在特定數(shù)據(jù)庫的基礎(chǔ)上授權(quán)。你可以為特定的數(shù)據(jù)庫、表或列授權(quán),F(xiàn)ILE權(quán)限給予你用LOAD DATA INFILE和SELECT … INTO OUTFILE語句讀和寫服務(wù)器上的文件,任何被授予FILE權(quán)限的用戶都能讀或?qū)慚ySQL服務(wù)器能讀或?qū)懙娜魏挝募?說明用戶可以讀任何數(shù)據(jù)庫目錄下的文件,因?yàn)榉?wù)器可以訪問這些文件)。 FILE權(quán)限允許用戶在MySQL服務(wù)器具有寫權(quán)限的目錄下創(chuàng)建新文件,但不能覆蓋已有文件在user表的File_priv設(shè)置Y或N。,所以當(dāng)你不需要對服務(wù)器文件讀取時(shí),請關(guān)閉該權(quá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'; //禁止讀取權(quán)限
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> flush privileges; //刷新授權(quán)表
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)

為了安全起見,隨時(shí)使用SHOW GRANTS語句檢查查看誰已經(jīng)訪問了什么。然后使用REVOKE語句刪除不再需要的權(quán)限。

12、使用chroot方式來控制MySQL的運(yùn)行目錄

Chroot是linux中的一種系統(tǒng)高級保護(hù)手段,它的建立會(huì)將其與主系統(tǒng)幾乎完全隔離,也就是說,一旦遭到什么問題,也不會(huì)危及到正在運(yùn)行的主系統(tǒng)。這是一個(gè)非常有效的辦法,特別是在配置網(wǎng)絡(luò)服務(wù)程序的時(shí)候。

13、關(guān)閉對Web訪問的支持

如果不打算讓W(xué)eb訪問使用MySQL數(shù)據(jù)庫,沒有提供諸如PHP這樣的Web語言的時(shí)候,重新設(shè)置或編譯你的PHP,取消它們對MySQL的默認(rèn)支持。假如服務(wù)器中使用php等web程序,試試用Web形式非法的請求,如果得到任何形式的MySQL錯(cuò)誤,立即分析原因,及時(shí)修改Web程序,堵住漏洞,防止MySQL暴露在web面前。
對于Web的安全檢查,在MySQL官方文檔中這么建議,對于web應(yīng)用,至少檢查以下清單:
試試用Web形式輸入單引號和雙引號(‘’’和‘”’)。如果得到任何形式的MySQL錯(cuò)誤,立即分析原因。
試試修改動(dòng)態(tài)URL,可以在其中添加%22(‘”’)、%23(‘#’)和%27(‘’’)。
試試在動(dòng)態(tài)URL中修改數(shù)據(jù)類型,使用前面示例中的字符,包括數(shù)字和字符類型。你的應(yīng)用程序應(yīng)足夠安全,可以防范此類修改和類似攻擊。
試試輸入字符、空格和特殊符號,不要輸入數(shù)值字段的數(shù)字。你的應(yīng)用程序應(yīng)在將它們傳遞到MySQL之前將它們刪除或生成錯(cuò)誤。將未經(jīng)過檢查的值傳遞給MySQL是很危險(xiǎn)的!
將數(shù)據(jù)傳給MySQL之前先檢查其大小。
用管理賬戶之外的用戶名將應(yīng)用程序連接到數(shù)據(jù)庫。不要給應(yīng)用程序任何不需要的訪問權(quán)限。

14、數(shù)據(jù)庫備份策略

一般可采用本地備份和網(wǎng)絡(luò)備份的形式,可采用MySQL本身自帶的mysqldump的方式和直接復(fù)制備份形式,

直接拷貝數(shù)據(jù)文件最為直接、快速、方便,但缺點(diǎn)是基本上不能實(shí)現(xiàn)增量備份。為了保證數(shù)據(jù)的一致性,需要在備份文件前,執(zhí)行以下 SQL 語句:FLUSH TABLES WITH READ LOCK;也就是把內(nèi)存中的數(shù)據(jù)都刷新到磁盤中,同時(shí)鎖定數(shù)據(jù)表,以保證拷貝過程中不會(huì)有新的數(shù)據(jù)寫入。這種方法備份出來的數(shù)據(jù)恢復(fù)也很簡單,直接拷貝回原來的數(shù)據(jù)庫目錄下即可。

使用mysqldump可以把整個(gè)數(shù)據(jù)庫裝載到一個(gè)單獨(dú)的文本文件中。這個(gè)文件包含有所有重建您的數(shù)據(jù)庫所需要的SQL命令。這個(gè)命令取得所有的模式(Schema,后面有解釋)并且將其轉(zhuǎn)換成DDL語法(CREATE語句,即數(shù)據(jù)庫定義語句),取得所有的數(shù)據(jù),并且從這些數(shù)據(jù)中創(chuàng)建INSERT語句。這個(gè)工具將您的數(shù)據(jù)庫中所有的設(shè)計(jì)倒轉(zhuǎn)。因?yàn)樗械臇|西都被包含到了一個(gè)文本文件中。這個(gè)文本文件可以用一個(gè)簡單的批處理和一個(gè)合適SQL語句導(dǎo)回到MySQL中。

使用 mysqldump進(jìn)行備份非常簡單,如果要備份數(shù)據(jù)庫” nagios_db_backup ”,使用命令,同時(shí)使用管道gzip命令對備份文件進(jìn)行壓縮,建議使用異地備份的形式,可以采用Rsync等方式,將備份服務(wù)器的目錄掛載到數(shù)據(jù)庫服務(wù)器,將數(shù)據(jù)庫文件備份打包在,通過crontab定時(shí)備份數(shù)據(jù):

#!/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

恢復(fù)數(shù)據(jù)使用命令:

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

三、Mysqld安全相關(guān)啟動(dòng)選項(xiàng)

下列mysqld選項(xiàng)影響安全:

   --allow-suspicious-udfs
該選項(xiàng)控制是否可以載入主函數(shù)只有xxx符的用戶定義函數(shù)。默認(rèn)情況下,該選項(xiàng)被關(guān)閉,并且只能載入至少有輔助符的UDF。這樣可以防止從未包含合法UDF的共享對象文件載入函數(shù)。
    --local-infile[={0|1}]
如果用–local-infile=0啟動(dòng)服務(wù)器,則客戶端不能使用LOCAL in LOAD DATA語句。
    --old-passwords
強(qiáng)制服務(wù)器為新密碼生成短(pre-4.1)密碼哈希。當(dāng)服務(wù)器必須支持舊版本客戶端程序時(shí),為了保證兼容性這很有用。
     (OBSOLETE) --safe-show-database
在以前版本的MySQL中,該選項(xiàng)使SHOW DATABASES語句只顯示用戶具有部分權(quán)限的數(shù)據(jù)庫名。在MySQL 5.1中,該選項(xiàng)不再作為現(xiàn)在的 默認(rèn)行為使用,有一個(gè)SHOW DATABASES權(quán)限可以用來控制每個(gè)賬戶對數(shù)據(jù)庫名的訪問。
    --safe-user-create
如果啟用,用戶不能用GRANT語句創(chuàng)建新用戶,除非用戶有mysql.user表的INSERT權(quán)限。如果你想讓用戶具有授權(quán)權(quán)限來創(chuàng)建新用戶,你應(yīng)給用戶授予下面的權(quán)限:
mysql> GRANT INSERT(user) ON mysql.user TO ‘user_name’@’host_name’;
這樣確保用戶不能直接更改權(quán)限列,必須使用GRANT語句給其它用戶授予該權(quán)限。
    --secure-auth
不允許鑒定有舊(pre-4.1)密碼的賬戶。
    --skip-grant-tables
這個(gè)選項(xiàng)導(dǎo)致服務(wù)器根本不使用權(quán)限系統(tǒng)。這給每個(gè)人以完全訪問所有的數(shù)據(jù)庫的權(quán)力!(通過執(zhí)行mysqladmin flush-privileges或mysqladmin eload命令,或執(zhí)行FLUSH PRIVILEGES語句,你能告訴一個(gè)正在運(yùn)行的服務(wù)器再次開始使用授權(quán)表。)
    --skip-name-resolve
主機(jī)名不被解析。所有在授權(quán)表的Host的列值必須是IP號或localhost。
    --skip-networking
在網(wǎng)絡(luò)上不允許TCP/IP連接。所有到mysqld的連接必須經(jīng)由Unix套接字進(jìn)行。
    --skip-show-database
使用該選項(xiàng),只允許有SHOW DATABASES權(quán)限的用戶執(zhí)行SHOW DATABASES語句,該語句顯示所有數(shù)據(jù)庫名。不使用該選項(xiàng),允許所有用戶執(zhí)行SHOW DATABASES,但只顯示用戶有SHOW DATABASES權(quán)限或部分?jǐn)?shù)據(jù)庫權(quán)限的數(shù)據(jù)庫名。請注意全局權(quán)限指數(shù)據(jù)庫的權(quán)限。

原文出處

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容