Mysql安全措施
root權限一定要只允許本機登陸,并且MySQL安全目錄權限一定要只允許本地,root用戶一定要密鑰認證登陸系統(tǒng)(這涉及到系統(tǒng)安全的優(yōu)化)而且MySQL的安裝目錄權限一定要合理設置,并且mysql用戶不可登陸,只作為啟動用。MySQL的binlog要合理管理,配置好權限。
1、mysqladmin -u root password "newpass"
如果已經(jīng)配置了密碼:
mysqladmin -uroot -prenzhiyuan password '123456'
?
2、用SET PASSWORD命令
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('renzhiyuan');
Query OK, 0 rows affected (0.00 sec)
?
mysql>
?
3、UPDATE
mysql> UPDATE user SET Password = PASSWORD('123456') WHERE user = 'root';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4 ?Changed: 4 ?Warnings: 0
?
2.1.1)MySQL的歷史命令記錄:
[root@mysql ~]# cat .mysql_history?
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('renzhiyuan');
show databases;
use mysql;
select host,password,user from user;
grant all on *.* to root@'192.168.1.243' identified by 'renzhiyuan';
flush privileges;
show databases;
flush privileges;
[root@mysql ~]#
2.2.2)查看binlog可以查到明文密碼(5.6后版本進行了修復)
2.3.3)以通過授權表直接越過密碼。
2.4.4)明文登陸MySQL帶來的安全問題
[root@MySQL ~]# ll
總用量 66352
-rw-r--r-- 1 root root 67940718 12月 21 2016 2016-12-21-07-00-01.sql
[root@MySQL ~]# du -sh 2016-12-21-07-00-01.sql?
65M 2016-12-21-07-00-01.sql
[root@MySQL ~]# tar -czf - 2016-12-21-07-00-01.sql |openssl enc -e -aes256 -out MySQLbak_$(date +%F-%H-%M-%S).tar.gz
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password: ? #加密密碼
[root@MySQL ~]# ll
總用量 76536
-rw-r--r-- 1 root root 67940718 12月 21 2016 2016-12-21-07-00-01.sql
-rw-r--r-- 1 root root 10426544 1月 ?28 13:23 MySQLbak_2016-01-28-13-23-10.tar.gz
[root@MySQL ~]# du -sh *
65M 2016-12-21-07-00-01.sql
10M MySQLbak_2016-01-28-13-23-10.tar.gz
[root@MySQL ~]# mv 2016-12-21-07-00-01.sql /opt/
[root@MySQL ~]# ll
總用量 10184
-rw-r--r-- 1 root root 10426544 1月 ?28 13:23 MySQLbak_2016-01-28-13-23-10.tar.gz
[root@MySQL ~]# ll
總用量 10184
-rw-r--r-- 1 root root 10426544 1月 ?28 13:23 MySQLbak_2016-01-28-13-23-10.tar.gz
[root@MySQL ~]# openssl enc -d -aes256 -in MySQLbak_2016-01-28-13-23-10.tar.gz |tar xz -C /root/
enter aes-256-cbc decryption password: ? #錯誤密碼
?
gzip: stdin: not in gzip format
tar: Child died with signal 13
tar: Error is not recoverable: exiting now
error writing output file
[root@MySQL ~]# openssl enc -d -aes256 -in MySQLbak_2016-01-28-13-23-10.tar.gz |tar xz -C /root/
enter aes-256-cbc decryption password: ? ?#正確密碼
[root@MySQL ~]# ll
總用量 76536
-rw-r--r-- 1 root root 67940718 12月 21 2016 2016-12-21-07-00-01.sql
-rw-r--r-- 1 root root 10426544 1月 ?28 13:23 MySQLbak_2016-01-28-13-23-10.tar.gz
[root@MySQL ~]#
enc - openssl 命令使用加密進行編碼
-e – 用來加密輸入文件的 enc 命令選項,這里是指前一個 tar 命令的輸出
-aes256 – 加密用的算法
-out – 用于指定輸出文件名的 enc 命令選項,這里文件名是 secured.tar.gz
-d – 用于解密文件
-C – 提取內(nèi)容到指定目錄
一.權限表
mysql數(shù)據(jù)庫中的3個權限表:user 、db、 host
權限表的存取過程是:
1)先從user表中的host、 user、 password這3個字段中判斷連接的IP、用戶名、密碼是否存在表中,存在則通過身份驗證;
2) 通過權限驗證,進行權限分配時,按照user表db表中的tables_priv 和columns_priv的順序進行分配。即先檢查全局權限表 user,
如果user中對應的權限為Y,則此用戶對所有數(shù)據(jù)庫的權限都為Y,將不再檢查db, tables_priv,columns_priv;
如果為N,則到db表中檢查此用戶對應的具體數(shù)據(jù)庫,并得到db中為Y的權限;如果db中為N,則檢 查tables_priv中此數(shù)據(jù)庫對應的具體表,取得表中的權限Y,以此類推。
二.MySQL各種權限(共27個)
(以下操作都是以root身份登陸進行grant授權,以p1@localhost身份登陸執(zhí)行各種命令。)
1. usage
連接(登陸)權限,建立一個用戶,就會自動授予其usage權限(默認授予)。
mysql> grant usage on *.* to ‘p1′@’localhost’ identified by ‘123′;
該權限只能用于數(shù)據(jù)庫登陸,不能執(zhí)行任何操作;且usage權限不能被回收,也即REVOKE用戶并不能刪除用戶。
2. select
必須有select的權限,才可以使用select table
mysql> grant select on pyt.* to ‘p1′@’localhost’;
mysql> select * from shop;
3. create
必須有create的權限,才可以使用create table
mysql> grant create on pyt.* to ‘p1′@’localhost’;
4. create routine
必須具有create routine的權限,才可以使用{create |alter|drop} {procedure|function}
mysql> grant create routine on pyt.* to ‘p1′@’localhost’;
當授予create routine時,自動授予EXECUTE, ALTER ROUTINE權限給它的創(chuàng)建者:
mysql> show grants for ‘p1′@’localhost’;
+—————————————————————————+
Grants for p1@localhost
+————————————————————————–+
| GRANT USAGE ON *.* TO ‘p1′@’localhost’ IDENTIFIED BY PASSWORD ‘*23AE809DDACAF96AF0FD78ED04B6A265E05AA257′ |
| GRANT SELECT, CREATE, CREATE ROUTINE ON `pyt`.* TO ‘p1′@’localhost’|
| GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE `pyt`.`pro_shop1` TO ‘p1′@’localhost’ |
+————————————————————————————-+
5. create temporary tables(注意這里是tables,不是table)
必須有create temporary tables的權限,才可以使用create temporary tables.
mysql> grant create temporary tables on pyt.* to ‘p1′@’localhost’;
[mysql@mydev ~]$ mysql -h localhost -u p1 -p pyt
mysql> create temporary table tt1(id int);
6. create view
必須有create view的權限,才可以使用create view
mysql> grant create view on pyt.* to ‘p1′@’localhost’;
mysql> create view v_shop as select price from shop;
7. create user
要使用CREATE USER,必須擁有mysql數(shù)據(jù)庫的全局CREATE USER權限,或擁有INSERT權限。
mysql> grant create user on *.* to ‘p1′@’localhost’;
或:mysql> grant insert on *.* to p1@localhost;
8. insert
必須有insert的權限,才可以使用insert into ….. values….
9. alter
必須有alter的權限,才可以使用alter table
alter table shop modify dealer char(15);
10. alter routine
必須具有alter routine的權限,才可以使用{alter |drop} {procedure|function}
mysql>grant alter routine on pyt.* to ‘p1′@’ localhost ‘;
mysql> drop procedure pro_shop;
Query OK, 0 rows affected (0.00 sec)
mysql> revoke alter routine on pyt.* from ‘p1′@’localhost’;
[mysql@mydev ~]$ mysql -h localhost -u p1 -p pyt
mysql> drop procedure pro_shop;
ERROR 1370 (42000): alter routine command denied to user ‘p1′@’localhost’ for routine ‘pyt.pro_shop’
11. update
必須有update的權限,才可以使用update table
mysql> update shop set price=3.5 where article=0001 and dealer=’A’;
12. delete
必須有delete的權限,才可以使用delete from ….where….(刪除表中的記錄)
13. drop
必須有drop的權限,才可以使用drop database db_name; drop table tab_name;
drop view vi_name; drop index in_name;
14. show database
通過show database只能看到你擁有的某些權限的數(shù)據(jù)庫,除非你擁有全局SHOW DATABASES權限。
對于p1@localhost用戶來說,沒有對mysql數(shù)據(jù)庫的權限,所以以此身份登陸查詢時,無法看到mysql數(shù)據(jù)庫:
mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema|
| pyt |
| test |
+——————–+
15. show view
必須擁有show view權限,才能執(zhí)行show create view。
mysql> grant show view on pyt.* to p1@localhost;
mysql> show create view v_shop;
16. index
必須擁有index權限,才能執(zhí)行[create |drop] index
mysql> grant index on pyt.* to p1@localhost;
mysql> create index ix_shop on shop(article);
mysql> drop index ix_shop on shop;
17. excute
執(zhí)行存在的Functions,Procedures
mysql> call pro_shop1(0001,@a);
+———+
| article |
+———+
| 0001 |
| 0001 |
+———+
mysql> select @a;
+——+
| @a |
+——+
| 2 |
+——+
18. lock tables
必須擁有l(wèi)ock tables權限,才可以使用lock tables
mysql> grant lock tables on pyt.* to p1@localhost;
mysql> lock tables a1 read;
mysql> unlock tables;
19. references
有了REFERENCES權限,用戶就可以將其它表的一個字段作為某一個表的外鍵約束。
20. reload
必須擁有reload權限,才可以執(zhí)行flush [tables | logs | privileges]
mysql> grant reload on pyt.* to p1@localhost;
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
mysql> grant reload on *.* to ‘p1′@’localhost’;
Query OK, 0 rows affected (0.00 sec)
mysql> flush tables;
21. replication client
擁有此權限可以查詢master server、slave server狀態(tài)。
mysql> show master status;
ERROR 1227 (42000): Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation
mysql> grant Replication client on *.* to p1@localhost;
或:mysql> grant super on *.* to p1@localhost;
mysql> show master status;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000006 | 2111 | | |
+——————+———-+————–+——————+
mysql> show slave status;
22. replication slave
擁有此權限可以查看從服務器,從主服務器讀取二進制日志。
mysql> show slave hosts;
ERROR 1227 (42000): Access denied; you need the REPLICATION SLAVE privilege for this operation
mysql> show binlog events;
ERROR 1227 (42000): Access denied; you need the REPLICATION SLAVE privilege for this operation
mysql> grant replication slave on *.* to p1@localhost;
mysql> show slave hosts;
Empty set (0.00 sec)
mysql>show binlog events;
+—————+——-+—————-+———–+————-+————–+
| Log_name | Pos | Event_type | Server_id| End_log_pos|Info | +—————+——-+————–+———–+————-+—————+
| mysql-bin.000005 | 4 | Format_desc | 1 | 98 | Server ver: 5.0.77-log, Binlog ver: 4 | |mysql-bin.000005|98|Query|1|197|use `mysql`; create table a1(i int)engine=myisam|
……………………………………
23. Shutdown
關閉MySQL:
[mysql@mydev ~]$ mysqladmin shutdown
重新連接:
[mysql@mydev ~]$ mysql
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)
[mysql@mydev ~]$ cd /u01/mysql/bin
[mysql@mydev bin]$ ./mysqld_safe &
[mysql@mydev bin]$ mysql
24. grant option
擁有grant option,就可以將自己擁有的權限授予其他用戶(僅限于自己已經(jīng)擁有的權限)
mysql> grant Grant option on pyt.* to p1@localhost;
mysql> grant select on pyt.* to p2@localhost;
25. file
擁有file權限才可以執(zhí)行 select ..into outfile和load data infile…操作,但是不要把file, process, super權限授予管理員以外的賬號,這樣存在嚴重的安全隱患。
mysql> grant file on *.* to p1@localhost;
mysql> load data infile ‘/home/mysql/pet.txt’ into table pet;
26. super
這個權限允許用戶終止任何查詢;修改全局變量的SET語句;使用CHANGE MASTER,PURGE MASTER LOGS。
mysql> grant super on *.* to p1@localhost;
mysql> purge master logs before ‘mysql-bin.000006′;
27. process
通過這個權限,用戶可以執(zhí)行SHOW PROCESSLIST和KILL命令。默認情況下,每個用戶都可以執(zhí)行SHOW PROCESSLIST命令,但是只能查詢本用戶的進程。 mysql> show processlist;
+—-+——+———–+——+———+——+——-+——————+
| Id | User | Host | db | Command | Time | State | Info |
+—-+——+———–+——+———+——+——-+——————+
| 12 | p1 | localhost | pyt | Query | 0 | NULL | show processlist |
+—-+——+———–+——+———+——+——-+——————+
另外,
管理權限(如 super, process, file等)不能夠指定某個數(shù)據(jù)庫,on后面必須跟*.*
mysql> grant super on pyt.* to p1@localhost;
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
mysql> grant super on *.* to p1@localhost;
Query OK, 0 rows affected (0.01 sec)
數(shù)據(jù)庫安全 5.1. 保護MySQL安裝程序文件 5.2. 權限表 5.3. 建立加密連接
5.1. 保護 MySQL安裝程序文件
? ? ? 在重設置文件權限時,請先關閉數(shù)據(jù)庫服務器。
? ?
? ? ? 用以下命令把MySQL安裝程序目錄的屬主和所屬組設置為MySQL管理員帳號的用戶名和用戶組名。
? ? ? % chown -R mysql.mysql /usr/local/mysql
? ? ? 另外一種方法是把除數(shù)據(jù)目錄外的所有目錄屬主設置為root所有,如:
? ? ? % chown -R root.mysql /usr/local/mysql
? ? ? % chown -R mysql.mysql /usr/local/mysql/data
? ? ? ?設置安裝目錄及各有關子目錄的權限,允許管理員進行所有操作,只允許其他人進行讀和執(zhí)行訪問,設置命令如下:
? ? ? #設置mysql目錄
? ? ? % chmod 755 /usr/local/mysql
? ? ? or
? ? ? % chmod u=rwx,go=rx /usr/local/mysql
? ? ? #設置mysql/bin目錄
? ? ? % chmod 755 /usr/local/mysql/bin
? ? ? or
? ? ? % chmod u=rwx,go=rx /usr/local/mysql/bin
? ? ? #設置mysql/libexec目錄
? ? ? % chmod 700 /usr/local/mysql/libexec
? ? ? or
? ? ? % chmod u=rwx,go-rwx /usr/local/mysql/libexec
? ? ?把數(shù)據(jù)目錄及目錄中的所有子目錄和文件設置為只允許MySQL管理員訪問。
? ? ? % chmod -R go-rwx /usr/local/mysql/data
? ? ? 如果數(shù)據(jù)目錄下有選項文件或套接字文件,并一些客戶需訪問這些文件,則可用以下的權限設置,使客戶在沒有讀權限的前提下使用這些文件:
? ? ? % chmod go+x /usr/local/mysql/data
? ? ? mysql.sock 套接字文件一般放以/tmp目錄下,要確保該目錄設置了粘著位,使自戶只能刪除自已創(chuàng)建的文件,不能刪除其他用戶創(chuàng)建的文件。?
/etc/my.cnf中公共選項文件,是對所有用戶可讀的,所以不應把一些敏感信息保存在里面。
.my.cnf是用戶專用選項文件,要確保只有該用戶有權訪問 這樣設置以后,只有MySQL管理員才能啟動服務器。
5.2. 權限表
MySQL服務器通過權限表來控制用戶對數(shù)據(jù)庫的訪問,權限表存放在mysql數(shù)據(jù)庫里,由mysql_install_db腳本初始化。這些權限表分別user,db,table_priv,columns_priv和host。下面分別介紹一下這些表的結構和內(nèi)容:
? ??
? ? ? user權限表:記錄允許連接到服務器的用戶帳號信息,里面的權限是全局級的。
? ?
?? ? ?db權限表:記錄各個帳號在各個數(shù)據(jù)庫上的操作權限。
? ??
? ? ? table_priv權限表:記錄數(shù)據(jù)表級的操作權限。
? ?
? ? ? columns_priv權限表:記錄數(shù)據(jù)列級的操作權限。
? ??
? ? ? host權限表:配合db權限表對給定主機上數(shù)據(jù)庫級操作權限作更細致的控制。這個權限表不受GRANT和REVOKE語句的影響。
大家注意到,以上權限沒有限制到數(shù)據(jù)行級的設置。在MySQL只要實現(xiàn)數(shù)據(jù)行級控制就要通過編寫程序(使用GET-LOCK()函數(shù))來實現(xiàn)。
MySQL的版本很多,所以權限表的結構在不同版本間會有不同。如果出現(xiàn)這種情況,可用mysql_fix_privilege_tables腳本來修正。運行方式如下:
% mysql_fix_privilege_tables rootpassword ? ? ? ? ? ?#這里要給出MySQL的root用戶密碼
最好一下子升級到MySQL 4.0.4版本,因為4.0.2和4.0.3的db表沒有Create_tmp_table_priv和Lock_tables_priv權限。
MySQL的權限表定義了兩部份內(nèi)容,一個部份定義權限的范圍,即誰(帳戶)可以從哪里(客戶端主機)訪問什么(數(shù)據(jù)庫、數(shù)據(jù)表、數(shù)據(jù)列);另一部份定義權限,即控制用戶可以進行的操作。下面是一些常用的權限介紹,可直接在GRANT語句中使用。
? ? ? CREATE TEMPORARY TABLES,允許創(chuàng)建臨時表的權限。
? ??
? ? ? EXECUTE,允許執(zhí)行存儲過程的權限,存儲過程在MySQL的當前版本中還沒實現(xiàn)。
? ??
? ? ? FILE,允許你通過MySQL服務器去讀寫服務器主機上的文件。但有一定限制,只能訪問對任何用戶可讀的文件,通過服務器寫的文件必須是尚未存在的,以防止服務器寫的文件覆蓋重要的系統(tǒng)文件。盡管有這些限制,但為了安全,盡量不要把該權限授予普通用戶。并且不要以root用戶來運行MySQL服務器,因為root 用戶可在系統(tǒng)任何地方創(chuàng)建文件。
? ??
? ? ? GRANT OPTION,允許把你自已所擁有的權限再轉授給其他用戶。
? ??
? ? ? LOCK TABLES,可以使用LOCK TABLES語句來鎖定數(shù)據(jù)表
? ??
? ? ? PROCESS,允許你查看和終止任何客戶線程。SHOW PROCESSLIST語句或mysqladmin processlist命令可查看線程,KILL語句或mysqladmin kill命令可終止線程。在4.0.2版及以后的版本中,PROCESS權限只剩下查看線程的能力,終止線程的能力由SUPER權限控制。
? ??
? ? ? RELOAD,允許你進行一些數(shù)據(jù)庫管理操作,如FLUSH,RESET等。它還允許你執(zhí)行mysqladmin命令:reload,refresh,flush- hosts,flush-logs,flush-privileges,flush- status,flush-tables和flush-threads。
? ??
? ? ? REPLICATION CLIENT,允許查詢鏡像機制中主服務器和從服務器的位置。
? ??
? ? ? REPLICATION SLAVE,允許某個客戶連接到鏡像機制中的主服務器并請求發(fā)送二進制變更日志。該權限應授予從服務器用來連接主服務器的帳號。在4.0.2版這前,從服務器是用FILE權限來連接的。
? ??
? ? ? SHOW DATABASES,控制用戶執(zhí)行SHOW DATABASES語句的權限。
? ??
? ? ? SUPER,允許終止線程,使用mysqladmin debug命令,使用CHANGE MASTER,PURGE MASTER LOGS以及修改全局級變量的SET語句。SUPER還允許你根據(jù)存放在DES密鑰文件里的密鑰進行DES解密的工作。
user權限表中有一個ssl_type數(shù)據(jù)列,用來說明連接是否使用加密連接以及使用哪種類型的連接,它是一個ENUM類型的數(shù)據(jù)列,可能的取值有:
? ??
? ? ? NONE,默認值,表示不需加密連接。
? ??
? ? ? ANY,表示需要加密連接,可以是任何一種加密連接。由GRANT的REQUIRE SSL子句設置。
? ??
? ? ? X509,表示需要加密連接,并要求客戶提供一份有效的X509證書。由GRANT的REQUIRE X509子句設置。
? ??
? ? ? SPECIFIED,表示加密連接需滿足一定要求,由REQUIRE子句的ISSUER,SUBJECT或CIPHER的值進行設置。只要 ssl_type列的值為SPECIFIED,則MySQL會去檢查ssl_cipher(加密算法)、x509_issuer(證書簽發(fā)者)和 x509_subject(證書主題)列的值。這幾列的列類型是BLOB類型的。
user權限表里還有幾列是設置帳戶資源使用情況的,如果以下數(shù)據(jù)列中的數(shù)全為零,則表示沒有限制:
? ?
? ? ? max_connections,每小時可連接服務器的次數(shù)。
? ??
? ? ? max_questions,每小時可發(fā)出查詢命令數(shù)。
? ??
? ? ? max_updates,每小時可以發(fā)出的數(shù)據(jù)修改類查詢命令數(shù)。
設置權限表應注意的事項:
? ??
? ? ? 刪除所有匿名用戶。
? ??
? ? ? 查出所有沒有口令用戶,重新設置口令。可用以下命令查詢空口令用戶:
? ? ? mysql> SELECT host,user FROM user WHERE password = '';
? ? ? 盡量不要在host中使用通配符。
?
? ? ? 最好不要用user權限表進行授權,因為該表的權限都是全局級的。
??
? ? ? 不要把mysql數(shù)據(jù)庫的權限授予他人,因為該數(shù)據(jù)庫包含權限表。
? ?
? ? ? 使用GRANT OPTION權限時不要濫用。
? ??
? ? ? FILE權限可訪問文件系統(tǒng)中的文件,所以授權時也要注意。
? ? ?一個具有FILE權限的用戶執(zhí)行以下語句就可查看服務器上全體可讀的文件:
? ? ? mysql> CREATE TABLE etc_passwd(pwd_entry TEXT);
? ? ? mysql> LOAD DATA INFILE '/etc/passwd' INTO TABLE etc_passwd;
? ? ? mysql> SELECT * FROM etc_passwd;
? ? ? 如果MySQL服務器數(shù)據(jù)目錄上的訪問權限設置得不好,就會留下讓具有FILE權限的用戶進入別人數(shù)據(jù)庫的安全漏洞。所以建議把數(shù)據(jù)目錄設置成只能由MySQL服務器讀取。下面演示一個利用具有FILE權限的用戶讀取數(shù)據(jù)目錄中文件權限設置不嚴密的數(shù)據(jù)庫數(shù)據(jù)的過程:
? ? ? mysql> use test;
? ? ? mysql> create table temp(b longblob);
? ? ? mysql> show databases ? ? ?#顯示數(shù)據(jù)庫名清單,--skip-show-database可禁止該功能
? ? ? mysql> load data infile './db/xxx.frm' into table temp fields escaped by '' lines terminated by '';
? ? ? mysql> select * from temp into outfile 'xxx.frm' fields escaped by '' lines terminated by '';
? ? ? mysql> delete from temp;
? ? ? mysql> load data infile './db/xxx.MYD' into table temp fields escaped by '' lines terminated by '';
? ? ? mysql> select * from temp into outfile 'xxx.MYD' fields escaped by '' lines terminated by '';
? ? ? mysql> delete from temp;
? ? ? mysql> load data infile './db/xxx.MYI' into table temp fields escaped by '' lines terminated by '';
? ? ? mysql> select * from temp into outfile 'xxx.MYI' fields escaped by '' lines terminated by '';
? ? ? mysql> delete from temp;
? ? ? 這樣,你的數(shù)據(jù)庫就給人拷貝到本地了。如果服務器是運行在root用戶下,那危害就更大了,因為root可在服務器上做任何的操作。所以盡量不要用 root用戶來運行服務器。
? ? ? 只把PROCESS權限授予可信用戶,該用戶可查詢其他用戶的線程信息。
?
? ? ? 不要把RELOAD權限授予無關用戶,因為該權限可發(fā)出FLUSH或RESET語句,這些是數(shù)據(jù)庫管理工具,如果用戶不當使用會使數(shù)據(jù)庫管理出現(xiàn)問題。
?
? ? ? ALTER權限也不要授予一般用戶,因為該權限可更改數(shù)據(jù)表。
GRANT語句對權限表的修改過程:
? ? ? 當你發(fā)送一條GRANT語句時,服務器會在user權限表里創(chuàng)建一個記錄項并把你用戶名、主機名和口令記錄在User、Host和Password 列中。如果設置了全局權限,由把該設置記錄在相在的權限列中。
?
? ? ? 如果在GRANT里設置了數(shù)據(jù)庫級權限,你給出的用戶名和主機名就會記錄到db權限表的User和Host列中,數(shù)據(jù)庫名記錄在Db列中,權限記錄到相關的權限列中。
?
? ? ? 接著是到數(shù)據(jù)表和數(shù)據(jù)列級的權限設置,設置方法和上面的一樣。服務器會把用戶名、主機名、數(shù)據(jù)庫名以及相應的數(shù)據(jù)表名和數(shù)據(jù)列名記錄到數(shù)據(jù)表中。
刪除用戶權限其實就是把這些權限表中相應的帳號記錄全部刪除即可。
5.3. 建立加密連接
加密連接可提高數(shù)據(jù)的安全性,但會降低性能。要進行加密連接,必須滿足以下要求:
? ? ? user權限表里要有相關的SSL數(shù)據(jù)列。如果安裝的MySQL服務器是4.0.0版的,user權限表已包含相關的SSL數(shù)據(jù)列,否則,我們也可用mysql_fix_privilege_tables腳本升級權限表。
??
? ? ? 服務器和客戶程序都已經(jīng)編譯有OpenSSL支持。首先要安裝openssl,在編譯時MySQL服務器時加--with-vio和--with- openssl選項加上openssl支持。可用以下語句查詢服務器是否支持SSL:
? ? ? mysql> show variables like 'have_openssl';
? ? ? ? ?在啟動服務器時用有關選項指明證書文件和密鑰文件的位置。
在建立加密連接前,要準備三個文件,一個CA證書,是由可信賴第三方出具的證書,用來驗證客戶端和服務器端提供的證書。
CA證書可向商業(yè)機構購買,也可自行生成。
第二個文件是證書文件,用于在連接時向對方證明自已身份的文件。
第三個文件是密鑰文件,用來對在加密連接上傳輸數(shù)據(jù)的加密和解密。
MySQL服務器端的證書文件和密鑰文件必須首先安裝,在sampdb發(fā)行版本的ssl目錄里有幾個供參考的樣本文件:ca-cert.pem(CA證書),server-cert.pem(服務器證書),server-key.pem(服務器公共密鑰)。把這幾個文件拷貝到服務器的數(shù)據(jù)目錄中,再在選項文件里加上以下內(nèi)容:
? ? ? [mysqld]
? ? ? ssl-ca=/usr/local/mysql/data/ca-cert.pem
? ? ? ssl-cert=/usr/local/mysql/data/server-cert.pem
? ? ? ssl-key=/usr/local/mysql/data/server-key.pem
? ? ? 重啟服務器,使配置生效。
?
? ? ? 要想讓某個客戶程序建立加密連接,必須在調(diào)用這個客戶程序時用有關選項告訴它在哪里能找到其證書文件和密鑰文件。在sampdb發(fā)行版的ssl目錄中提供了 client-cert.pem(客戶證書文件),client-key.pem(客戶密鑰文件),CA證書與服務器使用同樣的ca- cert.pem。把他們拷貝到個人目錄下,并在.my.cnf選項文件中指出文件位置,如:
? ? ? [mysql]
? ? ? ssl-ca=/home/mysql/ca-cert.pem
? ? ? ssl-cert=/home/mysql/client-cert.pem
? ? ? ssl-key=/home/mysql/client-key.pem
? ? ? 配置完成后,調(diào)用mysql程序運行\(zhòng)s或SHOW STATUS LIKE 'SSL%'命令,如果看到SSL:的信息行就說明是加密連接了。如果把SSL相關的配置寫進選項文件,則默認是加密連接的。也可用mysql程序的 --skip-ssl選項取消加密連接。如果用命令行方式啟用加密連接可以這樣寫:
? ? ? % mysql --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem
可用GRANT語句的REQUIRE SSL選項來強制用戶使用加密連接。
使用sampdb發(fā)行版的證書可以建立一個加密連接,但由于該文件已公開,所以安全性不好,我們可以在測試成功后自行建立證書或購買商業(yè)證書,以提高安全性。如何自行建立SSL證書的文檔在sampdb發(fā)行版的ssl/README文件里有說明。
1、避免從互聯(lián)網(wǎng)訪問MySQL數(shù)據(jù)庫,確保特定主機才擁有訪問特權
?
直接通過本地網(wǎng)絡之外的計算機改變生產(chǎn)環(huán)境中的數(shù)據(jù)庫是異常危險的。有時,管理員會打開主機對數(shù)據(jù)庫的訪問:
> GRANT ALL ON *.* TO ';root'@'%'
?
這其實是完全放開了對root的訪問。所以,把重要的操作限制給特定主機非常重要:
> GRANT ALL ON *.* TO 'root'@'localhost';
?
> GRANT ALL ON *.* TO 'root'@'myip.athome'
?
> FLUSH PRIVILEGES
?
此時,你仍有完全的訪問,但只有指定的IP(不管其是否靜態(tài))可以訪問。
?
2、定期備份數(shù)據(jù)庫
?
任何系統(tǒng)都有可能發(fā)生災難。服務器、MySQL也會崩潰,也有可能遭受***,數(shù)據(jù)有可能被刪除。只有為最糟糕的情況做好了充分的準備,才能夠在事后快速地從災難中恢復。企業(yè)最好把備份過程作為服務器的一項日常工作。
?
3、禁用或限制遠程訪問
?
前面說過,如果使用了遠程訪問,要確保只有定義的主機才可以訪問服務器。這一般是通過TCP wrappers、iptables或任何其它的防火墻軟件或硬件實現(xiàn)的。
?
為限制打開網(wǎng)絡socket,管理員應當在my.cnf或my.ini的[mysqld]部分增加下面的參數(shù):
skip-networking
?
這些文件位于windows的C:\Program Files\MySQL\MySQL Server 5.1文件夾中,或在Linux中,my.cnf位于/etc/,或位于/etc/mysql/。這行命令在MySQL啟動期間,禁用了網(wǎng)絡連接的初始化。請注意,在這里仍可以建立與MySQL服務器的本地連接。
?
另一個可行的方案是,強迫MySQL僅監(jiān)聽本機,方法是在my.cnf的[mysqld]部分增加下面一行:
bind-address=127.0.0.1
?
如果企業(yè)的用戶從自己的機器連接到服務器或安裝到另一臺機器上的web服務器,你可能不太愿意禁用網(wǎng)絡訪問。此時,不妨考慮下面的有限許可訪問:
mysql> GRANT SELECT, INSERT ON mydb.* TO ';someuser'@'somehost'
?
這里,你要把someuser換成用戶名,把somehost換成相應的主機。
?
4、設置root用戶的口令并改變其登錄名
?
在linux中,root用戶擁有對所有數(shù)據(jù)庫的完全訪問權。因而,在Linux的安裝過程中,一定要設置root口令。當然,要改變默認的空口令,其方法如下:
Access MySQL控制臺:
$ mysql -u root -p
?
在MySQL控制臺中執(zhí)行:
> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
?
在實際操作中,只需將上面一行的new_password換成實際的口令即可。
?
在Linux控制臺中更改root口令的另一種方法是使用mysqladmin工具:
$ mysqladmin -u root password new_password
?
此時,也是將上面一行的new_password換成實際的口令即可。
?
當然,這是需要使用強口令來避免強力***。
?
為了更有效地改進root用戶的安全性,另一種好方法是為其改名。為此,你必須更新表用戶中的mySQL數(shù)據(jù)庫。在MySQL控制臺中進行操作:
> USE mysql;
?
> UPDATE user SET user="another_username" WHERE user="root";
?
> FLUSH PRIVILEGES;
?
然后,通過Linux訪問MySQL控制臺就要使用新用戶名了:
$ mysql -u another_username -p
?
5、移除測試(test)數(shù)據(jù)庫
?
在默認安裝的MySQL中,匿名用戶可以訪問test數(shù)據(jù)庫。我們可以移除任何無用的數(shù)據(jù)庫,以避免在不可預料的情況下訪問了數(shù)據(jù)庫。因而,在MySQL控制臺中,執(zhí)行:
> DROP DATABASE test;
?
6、禁用LOCAL INFILE
另一項改變是禁用”LOAD DATA LOCAL INFILE”命令,這有助于防止非授權用戶訪問本地文件。在PHP應用程序中發(fā)現(xiàn)有新的SQL注入漏洞時,這樣做尤其重要。
?
此外,在某些情況下,LOCAL INFILE命令可被用于訪問操作系統(tǒng)上的其它文件(如/etc/passwd),應使用下現(xiàn)的命令:
mysql> LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE table1
?
更簡單的方法是:
mysql> SELECT load_file("/etc/passwd")
?
為禁用LOCAL INFILE命令,應當在MySQL配置文件的[mysqld]部分增加下面的參數(shù):
set-variable=local-infile=0
?
7、移除匿名賬戶和廢棄的賬戶
?
有些MySQL數(shù)據(jù)庫的匿名用戶的口令為空。因而,任何人都可以連接到這些數(shù)據(jù)庫。可以用下面的命令進行檢查:
mysql> select * from mysql.user where user="";
?
在安全的系統(tǒng)中,不會返回什么信息。另一種方法是:
mysql> SHOW GRANTS FOR ''@'localhost';
?
mysql> SHOW GRANTS FOR ';'@'myhost'
?
如果grants存在,那么任何人都可以訪問數(shù)據(jù)庫,至少可以使用默認的數(shù)據(jù)庫“test”。其檢查方法如下:
shell> mysql -u blablabla
?
如果要移除賬戶,則執(zhí)行命令:
mysql> DROP USER "";
?
從MySQL的5.0版開始支持DROP USER命令。如果你使用的老版本的MySQL,你可以像下面這樣移除賬戶:
mysql> use mysql;
?
mysql> DELETE FROM user WHERE user="";
?
mysql> flush privileges;
?
8、降低系統(tǒng)特權
?
常見的數(shù)據(jù)庫安全建議都有“降低給各方的特權”這一說法。對于MySQL也是如此。一般情況下,開發(fā)人員會使用最大的許可,不像安全管理一樣考慮許可原則,而這樣做會將數(shù)據(jù)庫暴露在巨大的風險中。
?
為保護數(shù)據(jù)庫,務必保證真正存儲MySQL數(shù)據(jù)庫的文件目錄是由”mysql” 用戶和” mysql”組所擁有的。
shell>ls -l /var/lib/mysql
?
此外,還要確保僅有用戶”mysql”和root用戶可以訪問/var/lib/mysql目錄。
?
Mysql的二進制文件存在于/usr/bin/目錄中,它應當由root用戶或特定的”mysql”用戶所擁有。對這些文件,其它用戶不應當擁有“寫”的訪問權:
shell>ls -l /usr/bin/my*
?
9、降低用戶的數(shù)據(jù)庫特權
?
有些應用程序是通過一個特定數(shù)據(jù)庫表的用戶名和口令連接到MySQL的,安全人員不應當給予這個用戶完全的訪問權。
?
如果***者獲得了這個擁有完全訪問權的用戶,他也就擁有了所有的數(shù)據(jù)庫。查看一個用戶許可的方法是在MySQL控制臺中使用命令SHOW GRANT
>SHOW GRANTS FOR ';user'@'localhost'
?
為定義用戶的訪問權,使用GRANT命令。在下面的例子中,user1僅能從dianshang數(shù)據(jù)庫的billing表中選擇:
> GRANT SELECT ON billing.dianshang TO 'user1'@'localhost';
?
> FLUSH PRIVILEGES;
?
如此一來,user1用戶就無法改變數(shù)據(jù)庫中這個表和其它表的任何數(shù)據(jù)。
?
另一方面,如果你要從一個用戶移除訪問權,就應使用一個與GRANT命令類似的REVOKE命令:
> REVOKE SELECT ON billing.ecommerce FROM 'user1'@'localhost';
?
> FLUSH PRIVILEGES;
?
10、移除和禁用.mysql_history文件
?
在用戶訪問MySQL控制臺時,所有的命令歷史都被記錄在~/.mysql_history中。如果***者訪問這個文件,他就可以知道數(shù)據(jù)庫的結構。
$ cat ~/.mysql_history
?
為了移除和禁用這個文件,應將日志發(fā)送到/dev/null。
$export MYSQL_HISTFILE=/dev/null
?
上述命令使所有的日志文件都定向到/dev/null,你應當從home文件夾移除.mysql_history:$ rm ~/.mysql_history,并創(chuàng)建一個到/dev/null的符號鏈接。
?
11、安全補丁
?
務必保持數(shù)據(jù)庫為最新版本。因為***者可以利用上一個版本的已知漏洞來訪問企業(yè)的數(shù)據(jù)庫。
?
12、啟用日志
?
如果你的數(shù)據(jù)庫服務器并不執(zhí)行任何查詢,建議你啟用跟蹤記錄,你可以通過在/etc/my.cnf文件的[Mysql]部分添加:log =/var/log/mylogfile。
?
對于生產(chǎn)環(huán)境中任務繁重的MySQL數(shù)據(jù)庫,因為這會引起服務器的高昂成本。
?
此外,還要保證只有root和mysql可以訪問這些日志文件。
?
錯誤日志
?
務必確保只有root和mysql可以訪問hostname.err日志文件。該文件存放在mysql數(shù)據(jù)歷史中。該文件包含著非常敏感的信息,如口令、地址、表名、存儲過程名、代碼等,它可被用于信息收集,并且在某些情況下,還可以向***者提供利用數(shù)據(jù)庫漏洞的信息。***者還可以知道安裝數(shù)據(jù)庫的機器或內(nèi)部的數(shù)據(jù)。
?
MySQL日志
?
確保只有root和mysql可以訪問logfileXY日志文件,此文件存放在mysql的歷史目錄中。
?
13、改變root目錄
?
Unix操作系統(tǒng)中的chroot可以改變當前正在運行的進程及其子進程的root目錄。重新獲得另一個目錄root權限的程序無法訪問或命名此目錄之外的文件,此目錄被稱為“chroot監(jiān)獄”。
?
通過利用chroot環(huán)境,你可以限制MySQL進程及其子進程的寫操作,增加服務器的安全性。
?
你要保證chroot環(huán)境的一個專用目錄,如/chroot/mysql。此外,為了方便利用數(shù)據(jù)庫的管理工具,你可以在MySQL配置文件的[client]部分改變下面的參數(shù):
[client]
socket = /chroot/mysql/tmp/mysql.sock
?
14、禁用LOCAL INFILE命令
?
LOAD DATA LOCAL INFILE可以從文件系統(tǒng)中讀取文件,并顯示在屏幕中或保存在數(shù)據(jù)庫中。如果***者能夠從應用程序找到SQL注入漏洞,這個命令就相當危險了。下面的命令可以從MySQL控制臺進行操作:
> SELECT LOAD_FILE("/etc/passwd");
?
該命令列示了所有的用戶。解決此問題的最佳方法是在MySQL配置中禁用它,在CentOS中找到/etc/my.cnf或在Ubuntu中找到/etc/mysql/my.cnf,在[mysqld]部分增加下面一行:set-variable=local-infile=0。搞定。
?
1、安裝完MySQL后
修改root用戶密碼
? ? 5.5以前,rpm包安裝完MySQL后,root用戶密碼為空
? ? 5.6中,rpm包安裝完MySQL后,會隨機生成一個root密碼,保存在/root/.mysql_secret
? ? 5.7以后,使用mysqld --initialize初始化時,默認會自動生成隨機密碼,并且不創(chuàng)建除
root@localhost 外的其他賬號,也不創(chuàng)建test庫;
2、正確授權
? ? mysql庫中有4張權限表,user、db、tables_priv、columns_priv,分別對應用戶密碼、用戶對數(shù)據(jù)庫的權限、對表的權限、對列的權限。
? ? 當一個用戶向MySQL發(fā)起請求時,首先會從user表中驗證host、user、password,然后再依次驗證db、tables_priv、columns_priv,驗證過程中,如果db表中對應權限為Y,則此用戶對某個庫的權限全為Y,將不再驗證tables_priv和columns_priv。
對于MySQL中的賬戶權限相關的安全配置,總結如下:
? ? 針對每個網(wǎng)站建立一個單獨的賬戶
? ? 為每個網(wǎng)站單獨建立一個專屬數(shù)據(jù)庫
? ? 按照user->db->tables_priv->columns_pri的順序進行細粒度的權限控制
? ? 為每個用戶單獨配置一個專屬數(shù)據(jù)庫,保證當前用戶的所有操作只能發(fā)生在它自己的數(shù)據(jù)庫中,防止SQL注入發(fā)生后,***通過注入點訪問到系統(tǒng)表
? ? 如果有必要,改變MySQL的root用戶的用戶名(在user表中更改)
3、MySQL網(wǎng)絡完全配置
? ? 禁止root用戶遠程登錄
? ? 防火墻設置
? ? 更改默認端口(默認3306),可以從一定程度上防止端口掃描工具的掃描
? ? 限制單個用戶的連接數(shù)量:
? ? ? ? [mysqld]
? ? ? ? max_user_connections 20
4、文件權限及文件安全
? ? 使用非root用戶啟動MySQL服務
? ? 限制啟動MySQL的用戶的文件權限,同時確保該用戶對MySQL的數(shù)據(jù)文件等有讀寫權限
? ? 可以使用chroot更改根目錄,防止非root用戶訪問到一些敏感文件,比如:/etc/passwd
? ? 不要給非root用戶授予process和super權限,mysqladmin processlist和show processlist命令會查看到任何用戶執(zhí)行的命令,這可能看到其他用戶執(zhí)行的update user set password=...;命令,super權限可以終止會話、更改系統(tǒng)參數(shù)等
? ? 不要對表使用軟連接(--skip-symbolic-links參數(shù)用來禁用這一功能),表的軟連接只有MyISAM支持,因為開啟表軟連接后(尤其是對于使用系統(tǒng)root用戶啟動MySQL服務的),MySQL用戶就可以使用mysqld來刪除、重命名數(shù)據(jù)文件所在位置以外的文件了
? ? 如果plugin文件夾可以被MySQL server寫,那么用戶就可以使用select ... into dumpfile命令把可執(zhí)行代碼寫入到里面,可以通過把plugin_dir參數(shù)對應的路徑設為只讀以及調(diào)整--secure-file-priv參數(shù)來提高安全性
? ? 不要給非root用戶授予文件讀寫權限,防止使用load data local infile來提取本地文件(比如提取/etc/passwd里的信息,會對系統(tǒng)安全造成威脅)
? ? ? ? [mysqld]
? ? ? ? local-infile=0
5、如果有必要,可以刪除~/.bash_history文件,防止讀取歷史命令
# rm .bash_history .mysql_history
# ln -s /dev/null .bash_history
# ln -s /dev/null .mysql_history?
轉載于:https://blog.51cto.com/6226001001/1899645
總結
- 上一篇: CSS_伪元素_伪类
- 下一篇: Nginx内置变量以及日志格式变量参数详