Mysql安全措施

餘二五發表於2017-11-15

root許可權一定要只允許本機登陸,並且MySQL安全目錄許可權一定要只允許本地,root使用者一定要金鑰認證登陸系統(這涉及到系統安全的優化)而且MySQL的安裝目錄許可權一定要合理設定,並且mysql使用者不可登陸,只作為啟動用。MySQL的binlog要合理管理,配置好許可權。


1、mysqladmin -u root password “newpass”

如果已經配置了密碼:

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 – 提取內容到指定目錄



一.許可權表

mysql資料庫中的3個許可權表:user 、db、 host


許可權表的存取過程是:


1)先從user表中的host、 user、 password這3個欄位中判斷連線的IP、使用者名稱、密碼是否存在表中,存在則通過身份驗證;


2) 通過許可權驗證,進行許可權分配時,按照user表db表中的tables_priv 和columns_priv的順序進行分配。即先檢查全域性許可權表 user


如果user中對應的許可權為Y,則此使用者對所有資料庫的許可權都為Y,將不再檢查db, tables_priv,columns_priv;

如果為N,則到db表中檢查此使用者對應的具體資料庫,並得到db中為Y的許可權;如果db中為N,則檢 查tables_priv中此資料庫對應的具體表,取得表中的許可權Y,以此類推。


二.MySQL各種許可權(共27個)


(以下操作都是以root身份登陸進行grant授權,以p1@localhost身份登陸執行各種命令。)


1. usage

連線(登陸)許可權,建立一個使用者,就會自動授予其usage許可權(預設授予)

mysql> grant usage on *.* to ‘p1′@’localhost’ identified by ‘123′;

該許可權只能用於資料庫登陸,不能執行任何操作;且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許可權給它的建立者:

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資料庫的全域性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只能看到你擁有的某些許可權的資料庫,除非你擁有全域性SHOW DATABASES許可權。

對於p1@localhost使用者來說,沒有對mysql資料庫的許可權,所以以此身份登陸查詢時,無法看到mysql資料庫:

mysql> show databases;

+——————–+

| Database |

+——————–+

| information_schema|

| pyt |

| test |

+——————–+

15. show view

必須擁有show view許可權,才能執行show create view。

mysql> grant show view on pyt.* to p1@localhost;

mysql> show create view v_shop;

16. index

必須擁有index許可權,才能執行[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

執行存在的Functions,Procedures

mysql> call pro_shop1(0001,@a);

+———+

| article |

+———+

| 0001 |

| 0001 |

+———+

mysql> select @a;

+——+

| @a |

+——+

| 2 |

+——+

18. lock tables

必須擁有lock 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許可權,才可以執行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狀態。

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,就可以將自己擁有的許可權授予其他使用者(僅限於自己已經擁有的許可權)

mysql> grant Grant option on pyt.* to p1@localhost;

mysql> grant select on pyt.* to p2@localhost;


25. file

擁有file許可權才可以執行 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

通過這個許可權,使用者可以執行SHOW PROCESSLIST和KILL命令。預設情況下,每個使用者都可以執行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等)不能夠指定某個資料庫,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)



資料庫安全 5.1. 保護MySQL安裝程式檔案 5.2. 許可權表 5.3. 建立加密連線


5.1. 保護 MySQL安裝程式檔案


      在重設定檔案許可權時,請先關閉資料庫伺服器。

   

      用以下命令把MySQL安裝程式目錄的屬主和所屬組設定為MySQL管理員帳號的使用者名稱和使用者組名。


      % chown -R mysql.mysql /usr/local/mysql


      另外一種方法是把除資料目錄外的所有目錄屬主設定為root所有,如:


      % chown -R root.mysql /usr/local/mysql

      % chown -R mysql.mysql /usr/local/mysql/data


       設定安裝目錄及各有關子目錄的許可權,允許管理員進行所有操作,只允許其他人進行讀和執行訪問,設定命令如下:


      #設定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


     把資料目錄及目錄中的所有子目錄和檔案設定為只允許MySQL管理員訪問。


      % chmod -R go-rwx /usr/local/mysql/data


      如果資料目錄下有選項檔案或套接字檔案,並一些客戶需訪問這些檔案,則可用以下的許可權設定,使客戶在沒有讀許可權的前提下使用這些檔案:


      % chmod go+x /usr/local/mysql/data


      mysql.sock 套接字檔案一般放以/tmp目錄下,要確保該目錄設定了粘著位,使自戶只能刪除自已建立的檔案,不能刪除其他使用者建立的檔案。 

/etc/my.cnf中公共選項檔案,是對所有使用者可讀的,所以不應把一些敏感資訊儲存在裡面。

.my.cnf是使用者專用選項檔案,要確保只有該使用者有權訪問 這樣設定以後,只有MySQL管理員才能啟動伺服器。




5.2. 許可權表


MySQL伺服器通過許可權表來控制使用者對資料庫的訪問,許可權表存放在mysql資料庫裡,由mysql_install_db指令碼初始化。這些許可權表分別user,db,table_priv,columns_priv和host。下面分別介紹一下這些表的結構和內容:


    


      user許可權表:記錄允許連線到伺服器的使用者帳號資訊,裡面的許可權是全域性級的

   

      db許可權表:記錄各個帳號在各個資料庫上的操作許可權。

    

      table_priv許可權表:記錄資料表級的操作許可權。

   

      columns_priv許可權表:記錄資料列級的操作許可權。

    

      host許可權表:配合db許可權表對給定主機上資料庫級操作許可權作更細緻的控制。這個許可權表不受GRANT和REVOKE語句的影響。


大家注意到,以上許可權沒有限制到資料行級的設定。在MySQL只要實現資料行級控制就要通過編寫程式(使用GET-LOCK()函式)來實現。


MySQL的版本很多,所以許可權表的結構在不同版本間會有不同。如果出現這種情況,可用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的許可權表定義了兩部份內容,一個部份定義許可權的範圍,即誰(帳戶)可以從哪裡(客戶端主機)訪問什麼(資料庫、資料表、資料列);另一部份定義許可權,即控制使用者可以進行的操作。下面是一些常用的許可權介紹,可直接在GRANT語句中使用。



      CREATE TEMPORARY TABLES,允許建立臨時表的許可權。

    

      EXECUTE,允許執行儲存過程的許可權,儲存過程在MySQL的當前版本中還沒實現。

    

      FILE,允許你通過MySQL伺服器去讀寫伺服器主機上的檔案。但有一定限制,只能訪問對任何使用者可讀的檔案,通過伺服器寫的檔案必須是尚未存在的,以防止伺服器寫的檔案覆蓋重要的系統檔案。儘管有這些限制,但為了安全,儘量不要把該許可權授予普通使用者。並且不要以root使用者來執行MySQL伺服器,因為root 使用者可在系統任何地方建立檔案。

    

      GRANT OPTION,允許把你自已所擁有的許可權再轉授給其他使用者。

    

      LOCK TABLES,可以使用LOCK TABLES語句來鎖定資料表

    

      PROCESS,允許你檢視和終止任何客戶執行緒。SHOW PROCESSLIST語句或mysqladmin processlist命令可檢視執行緒,KILL語句或mysqladmin kill命令可終止執行緒。在4.0.2版及以後的版本中,PROCESS許可權只剩下檢視執行緒的能力,終止執行緒的能力由SUPER許可權控制。

    

      RELOAD,允許你進行一些資料庫管理操作,如FLUSH,RESET等。它還允許你執行mysqladmin命令:reload,refresh,flush- hosts,flush-logs,flush-privileges,flush- status,flush-tables和flush-threads。

    

      REPLICATION CLIENT,允許查詢映象機制中主伺服器和從伺服器的位置。

    

      REPLICATION SLAVE,允許某個客戶連線到映象機制中的主伺服器並請求傳送二進位制變更日誌。該許可權應授予從伺服器用來連線主伺服器的帳號。在4.0.2版這前,從伺服器是用FILE許可權來連線的。

    

      SHOW DATABASES,控制使用者執行SHOW DATABASES語句的許可權。

    

      SUPER,允許終止執行緒,使用mysqladmin debug命令,使用CHANGE MASTER,PURGE MASTER LOGS以及修改全域性級變數的SET語句。SUPER還允許你根據存放在DES金鑰檔案裡的金鑰進行DES解密的工作。


user許可權表中有一個ssl_type資料列,用來說明連線是否使用加密連線以及使用哪種型別的連線,它是一個ENUM型別的資料列,可能的取值有:


    

      NONE,預設值,表示不需加密連線。

    

      ANY,表示需要加密連線,可以是任何一種加密連線。由GRANT的REQUIRE SSL子句設定。

    

      X509,表示需要加密連線,並要求客戶提供一份有效的X509證照。由GRANT的REQUIRE X509子句設定。

    

      SPECIFIED,表示加密連線需滿足一定要求,由REQUIRE子句的ISSUER,SUBJECT或CIPHER的值進行設定。只要 ssl_type列的值為SPECIFIED,則MySQL會去檢查ssl_cipher(加密演算法)、x509_issuer(證照籤發者)和 x509_subject(證照主題)列的值。這幾列的列型別是BLOB型別的。


user許可權表裡還有幾列是設定帳戶資源使用情況的,如果以下資料列中的數全為零,則表示沒有限制:


   

      max_connections,每小時可連線伺服器的次數。

    

      max_questions,每小時可發出查詢命令數。

    

      max_updates,每小時可以發出的資料修改類查詢命令數。


設定許可權表應注意的事項:


    

      刪除所有匿名使用者。

    

      查出所有沒有口令使用者,重新設定口令。可用以下命令查詢空口令使用者:


      mysql> SELECT host,user FROM user WHERE password = “;


      儘量不要在host中使用萬用字元。

 

      最好不要用user許可權表進行授權,因為該表的許可權都是全域性級的

  

      不要把mysql資料庫的許可權授予他人,因為該資料庫包含許可權表

   

      使用GRANT OPTION許可權時不要濫用。

    

      FILE許可權可訪問檔案系統中的檔案,所以授權時也要注意。


     一個具有FILE許可權的使用者執行以下語句就可檢視伺服器上全體可讀的檔案


      mysql> CREATE TABLE etc_passwd(pwd_entry TEXT);

      mysql> LOAD DATA INFILE `/etc/passwd` INTO TABLE etc_passwd;

      mysql> SELECT * FROM etc_passwd;


      如果MySQL伺服器資料目錄上的訪問許可權設定得不好,就會留下讓具有FILE許可權的使用者進入別人資料庫的安全漏洞。所以建議把資料目錄設定成只能由MySQL伺服器讀取。下面演示一個利用具有FILE許可權的使用者讀取資料目錄中檔案許可權設定不嚴密的資料庫資料的過程:


      mysql> use test;

      mysql> create table temp(b longblob);

      mysql> show databases      #顯示資料庫名清單,–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;


      這樣,你的資料庫就給人拷貝到本地了。如果伺服器是執行在root使用者下,那危害就更大了,因為root可在伺服器上做任何的操作。所以儘量不要用 root使用者來執行伺服器


      只把PROCESS許可權授予可信使用者,該使用者可查詢其他使用者的執行緒資訊。

 

      不要把RELOAD許可權授予無關使用者,因為該許可權可發出FLUSH或RESET語句,這些是資料庫管理工具,如果使用者不當使用會使資料庫管理出現問題。

 

      ALTER許可權也不要授予一般使用者,因為該許可權可更改資料表。


GRANT語句對許可權表的修改過程:



      當你傳送一條GRANT語句時,伺服器會在user許可權表裡建立一個記錄項並把你使用者名稱、主機名和口令記錄在User、Host和Password 列中。如果設定了全域性許可權,由把該設定記錄在相在的許可權列中。

 

      如果在GRANT裡設定了資料庫級許可權,你給出的使用者名稱和主機名就會記錄到db許可權表的User和Host列中,資料庫名記錄在Db列中,許可權記錄到相關的許可權列中。

 

      接著是到資料表和資料列級的許可權設定,設定方法和上面的一樣。伺服器會把使用者名稱、主機名、資料庫名以及相應的資料表名和資料列名記錄到資料表中。


刪除使用者許可權其實就是把這些許可權表中相應的帳號記錄全部刪除即可。

5.3. 建立加密連線


加密連線可提高資料的安全性,但會降低效能。要進行加密連線,必須滿足以下要求:


      user許可權表裡要有相關的SSL資料列。如果安裝的MySQL伺服器是4.0.0版的,user許可權表已包含相關的SSL資料列,否則,我們也可用mysql_fix_privilege_tables指令碼升級許可權表。

  

      伺服器和客戶程式都已經編譯有OpenSSL支援。首先要安裝openssl,在編譯時MySQL伺服器時加–with-vio和–with- openssl選項加上openssl支援。可用以下語句查詢伺服器是否支援SSL:


      mysql> show variables like `have_openssl`;


         在啟動伺服器時用有關選項指明證照檔案和金鑰檔案的位置。


在建立加密連線前,要準備三個檔案,一個CA證照,是由可信賴第三方出具的證照,用來驗證客戶端和伺服器端提供的證照。


CA證照可向商業機構購買,也可自行生成。


第二個檔案是證照檔案,用於在連線時向對方證明自已身份的檔案。


第三個檔案是金鑰檔案,用來對在加密連線上傳輸資料的加密和解密。


MySQL伺服器端的證照檔案和金鑰檔案必須首先安裝,在sampdb發行版本的ssl目錄裡有幾個供參考的樣本檔案:ca-cert.pem(CA證照),server-cert.pem(伺服器證照),server-key.pem(伺服器公共金鑰)。把這幾個檔案拷貝到伺服器的資料目錄中,再在選項檔案里加上以下內容:


      [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


      重啟伺服器,使配置生效。

 

      要想讓某個客戶程式建立加密連線,必須在呼叫這個客戶程式時用有關選項告訴它在哪裡能找到其證照檔案和金鑰檔案。在sampdb發行版的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


      配置完成後,呼叫mysql程式執行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發行版的證照可以建立一個加密連線,但由於該檔案已公開,所以安全性不好,我們可以在測試成功後自行建立證照或購買商業證照,以提高安全性。如何自行建立SSL證照的文件在sampdb發行版的ssl/README檔案裡有說明。


1、避免從網際網路訪問MySQL資料庫,確保特定主機才擁有訪問特權

 

直接通過本地網路之外的計算機改變生產環境中的資料庫是異常危險的。有時,管理員會開啟主機對資料庫的訪問:

> GRANT ALL ON *.* TO `;root`@`%`

 

這其實是完全放開了對root的訪問。所以,把重要的操作限制給特定主機非常重要:

> GRANT ALL ON *.* TO `root`@`localhost`;

 

> GRANT ALL ON *.* TO `root`@`myip.athome`

 

> FLUSH PRIVILEGES

 

此時,你仍有完全的訪問,但只有指定的IP(不管其是否靜態)可以訪問。

 

2、定期備份資料庫

 

任何系統都有可能發生災難。伺服器、MySQL也會崩潰,也有可能遭受入侵,資料有可能被刪除。只有為最糟糕的情況做好了充分的準備,才能夠在事後快速地從災難中恢復。企業最好把備份過程作為伺服器的一項日常工作。

 

3、禁用或限制遠端訪問

 

前面說過,如果使用了遠端訪問,要確保只有定義的主機才可以訪問伺服器。這一般是通過TCP wrappers、iptables或任何其它的防火牆軟體或硬體實現的。

 

為限制開啟網路socket,管理員應當在my.cnf或my.ini的[mysqld]部分增加下面的引數:

skip-networking

 

這些檔案位於windows的C:Program FilesMySQLMySQL Server 5.1資料夾中,或在Linux中,my.cnf位於/etc/,或位於/etc/mysql/。這行命令在MySQL啟動期間,禁用了網路連線的初始化。請注意,在這裡仍可以建立與MySQL伺服器的本地連線。

 

另一個可行的方案是,強迫MySQL僅監聽本機,方法是在my.cnf的[mysqld]部分增加下面一行:

bind-address=127.0.0.1

 

如果企業的使用者從自己的機器連線到伺服器或安裝到另一臺機器上的web伺服器,你可能不太願意禁用網路訪問。此時,不妨考慮下面的有限許可訪問:

mysql> GRANT SELECT, INSERT ON mydb.* TO `;someuser`@`somehost`

 

這裡,你要把someuser換成使用者名稱,把somehost換成相應的主機。

 

4、設定root使用者的口令並改變其登入名

 

在linux中,root使用者擁有對所有資料庫的完全訪問權。因而,在Linux的安裝過程中,一定要設定root口令。當然,要改變預設的空口令,其方法如下:

Access MySQL控制檯:

$ mysql -u root -p

 

在MySQL控制檯中執行:

> SET PASSWORD FOR `root`@`localhost` = PASSWORD(`new_password`);

 

在實際操作中,只需將上面一行的new_password換成實際的口令即可。

 

在Linux控制檯中更改root口令的另一種方法是使用mysqladmin工具:

mysqladmin -u root password new_password

 

此時,也是將上面一行的new_password換成實際的口令即可。

 

當然,這是需要使用強口令來避免強力攻擊。

 

為了更有效地改進root使用者的安全性,另一種好方法是為其改名。為此,你必須更新表使用者中的mySQL資料庫。在MySQL控制檯中進行操作:

> USE mysql;

 

> UPDATE user SET user=”another_username” WHERE user=”root”;

 

> FLUSH PRIVILEGES;

 

然後,通過Linux訪問MySQL控制檯就要使用新使用者名稱了:

$ mysql -u another_username -p

 

5、移除測試(test)資料庫

 

在預設安裝的MySQL中,匿名使用者可以訪問test資料庫。我們可以移除任何無用的資料庫,以避免在不可預料的情況下訪問了資料庫。因而,在MySQL控制檯中,執行:

> DROP DATABASE test;

 

6、禁用LOCAL INFILE

另一項改變是禁用”LOAD DATA LOCAL INFILE”命令,這有助於防止非授權使用者訪問本地檔案。在PHP應用程式中發現有新的SQL隱碼攻擊漏洞時,這樣做尤其重要。

 

此外,在某些情況下,LOCAL INFILE命令可被用於訪問作業系統上的其它檔案(如/etc/passwd),應使用下現的命令:

mysql> LOAD DATA LOCAL INFILE `/etc/passwd` INTO TABLE table1

 

更簡單的方法是:

mysql> SELECT load_file(“/etc/passwd”)

 

為禁用LOCAL INFILE命令,應當在MySQL配置檔案的[mysqld]部分增加下面的引數:

set-variable=local-infile=0

 

7、移除匿名賬戶和廢棄的賬戶

 

有些MySQL資料庫的匿名使用者的口令為空。因而,任何人都可以連線到這些資料庫。可以用下面的命令進行檢查:

mysql> select * from mysql.user where user=””;

 

在安全的系統中,不會返回什麼資訊。另一種方法是:

mysql> SHOW GRANTS FOR “@`localhost`;

 

mysql> SHOW GRANTS FOR `;`@`myhost`

 

如果grants存在,那麼任何人都可以訪問資料庫,至少可以使用預設的資料庫“test”。其檢查方法如下:

shell> mysql -u blablabla

 

如果要移除賬戶,則執行命令:

mysql> DROP USER “”;

 

從MySQL的5.0版開始支援DROP USER命令。如果你使用的老版本的MySQL,你可以像下面這樣移除賬戶:

mysql> use mysql;

 

mysql> DELETE FROM user WHERE user=””;

 

mysql> flush privileges;

 

8、降低系統特權

 

常見的資料庫安全建議都有“降低給各方的特權”這一說法。對於MySQL也是如此。一般情況下,開發人員會使用最大的許可,不像安全管理一樣考慮許可原則,而這樣做會將資料庫暴露在巨大的風險中。

 

為保護資料庫,務必保證真正儲存MySQL資料庫的檔案目錄是由”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、降低使用者的資料庫特權

 

有些應用程式是通過一個特定資料庫表的使用者名稱和口令連線到MySQL的,安全人員不應當給予這個使用者完全的訪問權。

 

如果攻擊者獲得了這個擁有完全訪問權的使用者,他也就擁有了所有的資料庫。檢視一個使用者許可的方法是在MySQL控制檯中使用命令SHOW GRANT

>SHOW GRANTS FOR `;user`@`localhost`

 

為定義使用者的訪問權,使用GRANT命令。在下面的例子中,user1僅能從dianshang資料庫的billing表中選擇:

> GRANT SELECT ON billing.dianshang TO `user1`@`localhost`;

 

> FLUSH PRIVILEGES;

 

如此一來,user1使用者就無法改變資料庫中這個表和其它表的任何資料。

 

另一方面,如果你要從一個使用者移除訪問權,就應使用一個與GRANT命令類似的REVOKE命令:

> REVOKE SELECT ON billing.ecommerce FROM `user1`@`localhost`;

 

> FLUSH PRIVILEGES;

 

10、移除和禁用.mysql_history檔案

 

在使用者訪問MySQL控制檯時,所有的命令歷史都被記錄在~/.mysql_history中。如果攻擊者訪問這個檔案,他就可以知道資料庫的結構。

$ cat ~/.mysql_history

 

為了移除和禁用這個檔案,應將日誌傳送到/dev/null。

$export MYSQL_HISTFILE=/dev/null

 

上述命令使所有的日誌檔案都定向到/dev/null,你應當從home資料夾移除.mysql_history:$ rm ~/.mysql_history,並建立一個到/dev/null的符號連結。

 

11、安全補丁

 

務必保持資料庫為最新版本。因為攻擊者可以利用上一個版本的已知漏洞來訪問企業的資料庫。

 

12、啟用日誌

 

如果你的資料庫伺服器並不執行任何查詢,建議你啟用跟蹤記錄,你可以通過在/etc/my.cnf檔案的[Mysql]部分新增:log =/var/log/mylogfile

 

對於生產環境中任務繁重的MySQL資料庫,因為這會引起伺服器的高昂成本。

 

此外,還要保證只有root和mysql可以訪問這些日誌檔案。

 

錯誤日誌

 

務必確保只有root和mysql可以訪問hostname.err日誌檔案。該檔案存放在mysql資料歷史中。該檔案包含著非常敏感的資訊,如口令、地址、表名、儲存過程名、程式碼等,它可被用於資訊收集,並且在某些情況下,還可以向攻擊者提供利用資料庫漏洞的資訊。攻擊者還可以知道安裝資料庫的機器或內部的資料。

 

MySQL日誌

 

確保只有root和mysql可以訪問logfileXY日誌檔案,此檔案存放在mysql的歷史目錄中。

 

13、改變root目錄

 

Unix作業系統中的chroot可以改變當前正在執行的程式及其子程式的root目錄。重新獲得另一個目錄root許可權的程式無法訪問或命名此目錄之外的檔案,此目錄被稱為“chroot監獄”。

 

通過利用chroot環境,你可以限制MySQL程式及其子程式的寫操作,增加伺服器的安全性。

 

你要保證chroot環境的一個專用目錄,如/chroot/mysql。此外,為了方便利用資料庫的管理工具,你可以在MySQL配置檔案的[client]部分改變下面的引數:

[client]

socket = /chroot/mysql/tmp/mysql.sock

 

14、禁用LOCAL INFILE命令

 

LOAD DATA LOCAL INFILE可以從檔案系統中讀取檔案,並顯示在螢幕中或儲存在資料庫中。如果攻擊者能夠從應用程式找到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初始化時,預設會自動生成隨機密碼,並且不建立除


root@localhost 外的其他賬號,也不建立test庫;

2、正確授權

    mysql庫中有4張許可權表,user、db、tables_priv、columns_priv,分別對應使用者密碼、使用者對資料庫的許可權、對錶的許可權、對列的許可權。

    當一個使用者向MySQL發起請求時,首先會從user表中驗證host、user、password,然後再依次驗證db、tables_priv、columns_priv,驗證過程中,如果db表中對應許可權為Y,則此使用者對某個庫的許可權全為Y,將不再驗證tables_priv和columns_priv。

對於MySQL中的賬戶許可權相關的安全配置,總結如下:

    針對每個網站建立一個單獨的賬戶

    為每個網站單獨建立一個專屬資料庫

    按照user->db->tables_priv->columns_pri的順序進行細粒度的許可權控制

    為每個使用者單獨配置一個專屬資料庫,保證當前使用者的所有操作只能發生在它自己的資料庫中,防止SQL隱碼攻擊發生後,黑客通過注入點訪問到系統表

    如果有必要,改變MySQL的root使用者的使用者名稱(在user表中更改)

3、MySQL網路完全配置

    禁止root使用者遠端登入

    防火牆設定

    更改預設埠(預設3306),可以從一定程度上防止埠掃描工具的掃描

    限制單個使用者的連線數量:

        [mysqld]

        max_user_connections 20

4、檔案許可權及檔案安全

    使用非root使用者啟動MySQL服務

    限制啟動MySQL的使用者的檔案許可權,同時確保該使用者對MySQL的資料檔案等有讀寫許可權

    可以使用chroot更改根目錄,防止非root使用者訪問到一些敏感檔案,比如:/etc/passwd

    不要給非root使用者授予process和super許可權,mysqladmin processlist和show processlist命令會檢視到任何使用者執行的命令,這可能看到其他使用者執行的update user set password=…;命令,super許可權可以終止會話、更改系統引數等

    不要對錶使用軟連線(–skip-symbolic-links引數用來禁用這一功能),表的軟連線只有MyISAM支援,因為開啟表軟連線後(尤其是對於使用系統root使用者啟動MySQL服務的),MySQL使用者就可以使用mysqld來刪除、重新命名資料檔案所在位置以外的檔案了

    如果plugin資料夾可以被MySQL server寫,那麼使用者就可以使用select … into dumpfile命令把可執行程式碼寫入到裡面,可以通過把plugin_dir引數對應的路徑設為只讀以及調整–secure-file-priv引數來提高安全性

    不要給非root使用者授予檔案讀寫許可權,防止使用load data local infile來提取本地檔案(比如提取/etc/passwd裡的資訊,會對系統安全造成威脅)

        [mysqld]

        local-infile=0

5、如果有必要,可以刪除~/.bash_history檔案,防止讀取歷史命令

# rm .bash_history .mysql_history

# ln -s /dev/null .bash_history

# ln -s /dev/null .mysql_history 

本文轉自 chengxuyonghu 51CTO部落格,原文連結:http://blog.51cto.com/6226001001/1899645,如需轉載請自行聯絡原作者


相關文章