[MySQL Reference Manual] 6 安全性

6. 安全性

Mysql安裝配置時要考慮安全性的影響,如下幾點:html

Ÿ   常規因素影響安全性mysql

Ÿ   程序自身安全性linux

Ÿ   數據庫內部的安全性,即,訪問控制web

Ÿ   網絡安全性和系統安全性算法

Ÿ   數據文件的備份,日誌文件和配置文件的安全性sql

6. 安全性... 1shell

6.1 常規安全性問題... 2數據庫

6.1.1安全性最佳實踐... 2編程

6.1.2 保持密碼安全性... 2windows

6.1.2.1終端用戶密碼安全性最佳實踐... 2

6.1.2.2 密碼管理方法... 3

6.1.2.3 密碼和日誌... 3

6.1.2.4 Mysql中的密碼hash. 3

6.1.2.5 mysql 4.1的應用程序的密碼hash修改實現... 4

6.1.2.6 密碼驗證插件... 4

6.1.3 防止Mysql被攻擊... 4

6.1.4 安全相關的mysqld選項和變量... 5

6.1.5 使用常規用戶啓動mysql5

6.1.6 LOAD DATA LOCAL安全問題... 5

6.1.7客戶端程序安全性... 6

6.2 mysql訪問權限系統... 6

6.2.1 mysql提供的權限... 7

6.2.2 權限系統權限表... 8

6.2.3 指定賬號(Account)... 8

6.2.4 訪問控制,階段1:鏈接驗證... 9

6.2.5 訪問控制,階段2:請求驗證... 10

6.2.6 權限修改生效時間... 10

6.2.7 訪問拒絕的例子... 11

6.3 MySQL用戶賬號管理... 11

6.3.1用戶名和密碼... 11

6.3.2 增長用戶賬號... 11

6.3.3 刪除用戶賬號... 11

6.3.4 設置賬號的資源限制... 12

6.3.5 設置密碼... 12

6.3.6 密碼過時和沙盤模式... 13

6.3.6.1 密碼過時工做原理... 13

6.3.7 插件式驗證(Pluggable Authentication... 13

6.3.7.1 驗證插件的使用方法... 14

6.3.8 MySQL中可用的驗證插件... 14

6.3.9 代理用戶(proxy user... 14

6.3.9.1授予PROXY權限... 15

6.3.9.2 默認proxy用戶... 15

6.3.9.3 代理用戶系統變量... 16

6.3.10 使用SSL加密鏈接... 16

6.3.10.1 基本SSL概念... 16

6.3.10.2 爲mysql配置SSL. 16

6.3.9.10.3 使用SSL鏈接... 17

6.3.10.4 SSL相關配置... 18

6.3.10.5 爲mysql生成證書和公鑰私鑰... 18

6.3.11  從windows使用ssh連接到mysql18

6.3.12 Mysql企業版審計日誌插件... 18

6.3.12.1 安裝審計插件... 19

6.3.12.2 審計日誌安全性考慮... 19

6.3.12.3 審計日誌... 19

6.3.12.4 審計日誌記錄控制... 19

6.3.12.5 審計日誌插件選項和變量... 19

6.3.13 SQL-Based MySQL帳號活動審計... 20

 

6.1 常規安全性問題

6.1.1安全性最佳實踐

當運行mysql,有一下一些最佳實踐:

1.靜止用戶訪問mysql數據庫上面的表

2.學習權限是如何工做的。不要授予過多的權限

       checklist:測試mysql –uroot 鏈接,使用show grant查看被賦予了什麼權限

3.不要在數據庫中存明文密碼

4.不要從字典裏面選密碼

5.安裝防火牆

6.不能信任任何應用寫入的數據,應該經過防護編程技術寫入(defensive programming techniques)

7.學會使用tcpdumpstrings工具截取tcp中的數據

6.1.2 保持密碼安全性

6.1.2.1終端用戶密碼安全性最佳實踐

1.使用mysql_config_editor工具,把認證數據寫入到加密的.mylogin.cnf文件。

2.使用-ppassword或者—password=password會暴露密碼明文

3.使用 -p--password不指定密碼,交互方式數據密碼,避免密碼明文暴露

4.若是密碼明文方式在配置文件中,記得修改linux權限不讓其餘人訪問。

5.把密碼存放在環境變量 MYSQL_PWD,不推薦的訪問,會驗證影響安全。

linux中,mysql客戶端會記錄命令在.mysql_history,create usergrantset password的時候會寫入到文件,爲了安全性最好限制訪問模式。

6.1.2.2 密碼管理方法

1.不能讓非管理員用戶訪問mysql.user表。

2.使用密碼過時強制用戶重設密碼

3.使用validate_password插件強化密碼策略

6.1.2.3 密碼和日誌

使用語句 create usergrantset password或者調用了password函數,密碼都是明文的,若是被記錄,那麼可能會被其餘任何可以訪問日誌文件的人看到。

mysql 5.6.3以後就不會如下語句,日誌文件上出現明文(mariadb 10.0也不會顯示明文):

CREATE USER ... IDENTIFIED BY ...

GRANT ... IDENTIFIED BY ...

SET PASSWORD ...

SLAVE START ... PASSWORD = ...              (as of 5.6.4)

CREATE SERVER ... OPTIONS(... PASSWORD ...) (as of 5.6.9)

ALTER SERVER ... OPTIONS(... PASSWORD ...)  (as of 5.6.9)

 

語句中的密碼不會出如今,general query logslow query logbinary loggeneral query logpassword 重寫可使用—log-raw選項來限制。(使用mariadb 10.0測試無效)

審計日誌的文本是不加密的,因此不能讓其餘用戶訪問。

爲了儘可能避免日誌內容保留,應該不能讓系統和數據庫管理員以外的用戶訪問日誌文件。

複製slavemaster info repository中保存了複製master的密碼,會存在一個文件或者一個表中。要保證repository只能被數據庫管理員讀取。

6.1.2.4 Mysql中的密碼hash

mysql的用戶存放在mysql.user下,每一個帳號都有一個密碼,密碼是以hash值存放的。

mysql,在clientserver交互的2個階段用到密碼:

1.client鏈接會把密碼的hash,而後和user表的密碼進行匹配

2.在登錄以後,能夠修改密碼。

 

原先的hash方法(4.1版本以前)會產生16字節的字符串。4.1版本以後的hash方法產生41字節的字符串而且密碼以*號開頭。

使用old_password()就是使用老的hash方法。當old_password變量爲1是,password函數產生的結果16字節長度。

6.1.2.5 mysql 4.1的應用程序的密碼hash修改實現

6.1.2.6 密碼驗證插件

validate_password5.6.6以後),用來測試密碼的安全性。這個插件有2個功能:

1.檢查密碼明文的密碼策略

2.經過長度看密碼強壯性。

若是使用密碼明文,那麼就會對密碼進行驗證,若是直接用hash值,那麼就不驗證。

 

密碼驗證插件安裝方法:

1.使用配置文件

[mysqld]

plugin-load=validate_password.so

2.使用instal plugin命令,使用後會在mysql.plugins表中加入記錄,下次啓動會自動加載。

mysql> INSTALL PLUGIN validate_password SONAME 'validate_password.so';

validate-password能夠用來控制服務啓動的時候加載插件,若是值是FORCE或者FORCE_PLUS_PERMANENT,若是插件初始化失敗,那麼服務啓動就失敗。

6.1.3 防止Mysql被攻擊

mysql在傳輸的時候密碼不是明文傳輸的,可是其餘信息都是明文,可能會被其餘人讀取,若是是和非信任網絡的交互,可使用ssl加密鏈接。

有如下幾點可讓mysql系統更加安全:

1.每一個mysql用戶都要有密碼

2.只有mysqld的啓動用戶有訪問數據庫文件夾的權限

3.不要用root用戶啓動mysql服務。這樣每一個鏈接都有服務器上的root權限,十分危險。

4.不要授予非管理員用戶FILE權限

5.不要授予非管理員用戶PROCESSSUPER權限

6.不容許使用symlink到表。

7.存儲過程和函數要在安全指導寫編寫,Section 20.6, 「Access Control for Stored Programs and Views」.

8.在權限表中,若是對DNS不信任,那麼就使用ip地址

9.若是要限制一個帳號的最大鏈接數,可使用max_user_connections變量。

6.1.4 安全相關的mysqld選項和變量

Name

Cmd-Line

Option file

System Var

Status Var

Var Scope

Dynamic

allow-suspicious-udfs

Yes

Yes

 

 

 

 

automatic_sp_privileges

 

 

Yes

 

Global

Yes

chroot

Yes

Yes

 

 

 

 

des-key-file

Yes

Yes

 

 

 

 

local_infile

 

 

Yes

 

Global

Yes

old_passwords

 

 

Yes

 

Both

Yes

safe-user-create

Yes

Yes

 

 

 

 

secure-auth

Yes

Yes

 

 

Global

Yes

- Variable: secure_auth

 

 

Yes

 

Global

Yes

secure-file-priv

Yes

Yes

 

 

Global

No

- Variable: secure_file_priv

 

 

Yes

 

Global

No

skip-grant-tables

Yes

Yes

 

 

 

 

skip-name-resolve

Yes

Yes

 

 

Global

No

- Variable: skip_name_resolve

 

 

Yes

 

Global

No

skip-networking

Yes

Yes

 

 

Global

No

- Variable: skip_networking

 

 

Yes

 

Global

No

skip-show-database

Yes

Yes

 

 

Global

No

- Variable: skip_show_database

 

 

Yes

 

Global

No

6.1.5 使用常規用戶啓動mysql

修改mysqld啓動用戶步驟:

1.關閉mysql服務

2.修改數據庫文件夾和文件總的讀寫權限,可讓啓動用戶讀寫數據庫文件和文件夾

shell> chown -R user_name /path/to/mysql/datadir

3.使用—user=user_name或者在配置文件的user=user_name來指定啓動帳號,並啓動服務。

6.1.6 LOAD DATA LOCAL安全問題

load data能夠加載服務器上的文件,load data local能夠加載client host的文件。

load data local2個潛在安全性問題:

1.client host文件傳輸到server host。那麼server host要有權限,這樣會形成server host能夠訪問任何 client user有權限能夠訪問的文件。

2.web環境,用戶鏈接到web服務,一個用戶使用load data local就能夠讀取web服務進程能夠讀取的任何文件。

爲了解決這些問題,在mysql 3.29作了處理:

1.binary版本,增長了-DENABLED_LOCAL_INFILE,默認爲1,可使用 local

2.若是經過源代碼編譯沒有加-DENABLED_LOCAL_INFILE=1那麼就不能使用除非顯示的使用了,mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0).

3.能夠經過配置—local-infile=0來限制load data local語句的使用。

4.mysql 客戶端也能夠設置—local-infile來禁用和啓用load data local

5.若是是perl腳本或者其餘程序,能夠經過配置[client]的配置文件

6.若是load data local被禁用,使用的時候會報錯:

ERROR 1148: The used command is not allowed with this MySQL version

6.1.7客戶端程序安全性

具體看:

http://dev.mysql.com/doc/refman/5.6/en/secure-client-programming.html

 

6.2 mysql訪問權限系統

mysql權限系統主要有2個功能:

1.給驗證用戶權限

2.給你匿名用戶權限

權限系統中不能作的事:

·         You cannot explicitly specify that a given user should be denied access. That is, you cannot explicitly match a user and then refuse the connection.

·         You cannot specify that a user has privileges to create or drop tables in a database but not to create or drop the database itself.

·         A password applies globally to an account. You cannot associate a password with a specific object such as a database, table, or routine.

mysql的權限信息都是存放在mysql數據庫中,當服務啓動的時候,把數據加載到內存,而後以後處理都是在內存層面。

 

mysql的權限系統保證了,全部用戶只能操做被容許的行爲。mysql是經過用戶的identity來肯定用戶權限的identity=username@host

 

mysql的訪問控制分爲2個階段:

1.驗證用戶,鏈接

2.若是鏈接,而後經過檢查用戶權限來判斷可否執行。

 

若是一個用戶在鏈接狀態,而且修改了這個用戶的權限,那麼這個用戶的修改不會再下一個語句立刻體現。

6.2.1 mysql提供的權限

mysql提供了應用在不一樣上下文和級別的權限:

1.實例級別,能夠管理mysql server的管理。

2.數據庫級別權限,應用於數據庫和數據庫裏面的對象。

3.對象級別的權限,表,索引,視圖,存儲過程,函數。

帳號的權限記錄在mysql中的userdbtables_priv,columns_priv,procs_priv

 

如下表顯示了,能夠grantrevoke語句權限:

Privilege

Column

Context

CREATE

Create_priv

databases, tables, or indexes

DROP

Drop_priv

databases, tables, or views

GRANT OPTION

Grant_priv

databases, tables, or stored routines

LOCK TABLES

Lock_tables_priv

databases

REFERENCES

References_priv

databases or tables

EVENT

Event_priv

databases

ALTER

Alter_priv

tables

DELETE

Delete_priv

tables

INDEX

Index_priv

tables

INSERT

Insert_priv

tables or columns

SELECT

Select_priv

tables or columns

UPDATE

Update_priv

tables or columns

CREATE TEMPORARY TABLES

Create_tmp_table_priv

tables

TRIGGER

Trigger_priv

tables

CREATE VIEW

Create_view_priv

views

SHOW VIEW

Show_view_priv

views

ALTER ROUTINE

Alter_routine_priv

stored routines

CREATE ROUTINE

Create_routine_priv

stored routines

EXECUTE

Execute_priv

stored routines

FILE

File_priv

file access on server host

CREATE TABLESPACE

Create_tablespace_priv

server administration

CREATE USER

Create_user_priv

server administration

PROCESS

Process_priv

server administration

PROXY

see proxies_priv table

server administration

RELOAD

Reload_priv

server administration

REPLICATION CLIENT

Repl_client_priv

server administration

REPLICATION SLAVE

Repl_slave_priv

server administration

SHOW DATABASES

Show_db_priv

server administration

SHUTDOWN

Shutdown_priv

server administration

SUPER

Super_priv

server administration

ALL [PRIVILEGES]

 

server administration

USAGE

 

server administration

6.2.2 權限系統權限表

一般操做權限表是經過,grantrevoke來間接操做的。

mysql的表中一下表包含權限信息:

user:包含了用戶帳號,全局權限和其餘權限列

db:數據庫級別權限

host:mysql5.6.7以後就不存在,mariadb10.0也不存在

tables_priv:表級權限

columns_priv:列級權限

procs_priv:存儲過程和函數權限

proxies_priv:代理用戶權限

 

每一個權限表包含適用範圍列和權限列:

1.適用範圍列決定了權限適用範圍。

2.權限列代表了被授予的權限。

服務會在如下方式使用權限表:

1.user表的範圍列決定了是拒絕或者容許鏈接。對於可鏈接的用戶,在users表的權限都是全局權限,能夠應用到全部數據庫。

2.db表範圍列肯定了用戶能夠肯定了從哪來的鏈接能夠訪問哪些數據庫

3.tables_privcolumns_priv表和db表相似,可是粒度更加小,應用在表級和列級。

4.procs_priv應用在存儲過程和函數的權限

5.proxies_priv表說明用戶能夠代理其餘用戶

具體權限表的表接口能夠看:

http://dev.mysql.com/doc/refman/5.6/en/grant-table-structure.html

6.2.3 指定賬號(Account)

賬號名規則:

1.賬號名規則是user_name@host_name

2.若指定一個用戶名,就至關於’user_name’@’%’

3.若是不用引號合法,能夠不用引號

4.用戶名可使用單引號,雙引號,或者(`

5.引號的添加方法不是’user_name@%’,是’user_name’@’%’

6.使用current_user或者current_user()獲取當前用戶名和host

 

host是賬號的一部分能夠有不少方式和通配符:

1.host能夠指定hostname或者ip地址(ipv4,ipv6)。

2.你可使用’%’或者’’替換host或者ip地址。

3.也可使用host_ip/netmask格式代替host_name

6.2.4 訪問控制,階段1:鏈接驗證

當用戶鏈接到mysql,經過了identity認證,則進入階段2

identity2部分組成:

1.客戶端host

2.mysql用戶名

identity的驗證須要用到user表的3個字段,hostuserpassword

若是user列不是空的,只能準確的匹配,若是user列是空的,能夠匹配任意用戶。若user表中的一行匹配了一個空用戶名的用戶,那麼這個用戶就被認爲是匿名用戶,不是指定用戶名的用戶。

password列若是爲空的,並不意味着通配,而是空密碼。若是plugin認證可使用密碼也能夠不使用密碼。若是password不是爲空的,那麼說明登錄的時候須要密碼驗證。

 

當鏈接的時候有多個能夠匹配,就用如下方法:

1.無論何時服務讀取user表到內存,會對行排序

2.當一個客戶端視圖鏈接,服務會經過排序的順序匹配

3.服務會使用第一個匹配的usernamehostname

排序,越準確的排在越前面。

如:

+-----------+----------+-             

| Host       | User     | ...

+-----------+----------+-

| %           | root     | ...

| %           | jeffrey  | ...

| localhost | root     | ...

| localhost |          | ...

+-----------+----------+-

排序後:

+-----------+----------+-

| Host      | User     | ...

+-----------+----------+-

| localhost | root     | ...

| localhost |          | ...

| %         | jeffrey  | ...

| %         | root     | ...

+-----------+----------+-

若是鏈接了,可是不是本身要的賬號,可使用current_user()查看匹配的用戶。

6.2.5 訪問控制,階段2:請求驗證

鏈接以後,服務進入第二階段,當客戶端請求,服務就會去檢查是否有權限來執行這個請求。權限能夠經過表,userdbtables_privcolumns_privprocs_priv檢查。

 

user表的權限是全局的適用於全部數據庫。

db表中:

1.空的用戶名錶示匿名用戶,非空的表示指定用戶

2.通配符和’’能夠用在hostdb

3.’%’或者空的host表示任意host

4.’%’或者空的db表示任意數據庫

db表經過hostdbuser排序。

 

對於tables_privcolumns_privprocs_priv

1.host列能夠有通配符

2.%‘或者空host表示任意host

3.dbtable_name,column_name,routine_name列不能包含通配符或者空。

這幾個表也是根據hostdbuser排序。

 

對於數據庫相關的請求,先看用戶全局user表,若沒有就查db表的權限。server查看db表,同難過hostdbuser列進行匹配。

 

在肯定指定數據庫的權限,服務把權限添加到全局權限中,若是知足了就執行,若是不知足服務檢查用戶表和列的權限(tables_priv,columns_priv)把這些添加到用戶權限,根據結果來肯定是否執行。

 

權限的計算相似於這樣:

global privileges

OR (database privileges AND host privileges)

OR table privileges

OR column privileges

OR routine privileges

可是若是出現一個請求須要多個權限的狀況下,就不是這樣。

6.2.6 權限修改生效時間

mysql啓動會讀取grant表到內存,這個時候才生效。

若是使用grantrevokesetpasswordrename user間接的修改權限,服務會注意到時修改權限並會立刻加載到內存。

 

若使用dml修改權限表,須要手動加載後才能生效。從新加載的方法:

1.flush privileges語句

2.mysqladmin flush-privilege

3.mysqladmin reload

權限生效以後會對每一個存在的客戶端影響:

1.表或者列權限修改,會影響客戶端下一個請求

2.數據庫權限修改會影響下一個use db_name語句

3.全局權限修改會影響下一個鏈接

若是在啓動服務的時候使用—skip-grant-tables選線,不會讀取權限表,不會對權限進行認證,能夠隨意訪問數據。

6.2.7 訪問拒絕的例子

具體能夠看:http://dev.mysql.com/doc/refman/5.6/en/access-denied.html

6.3 MySQL用戶賬號管理

6.3.1用戶名和密碼

mysql的賬號保存在user表中,賬號由用戶名和host組成。

Ÿ   用戶名,只用來作mysql驗證。

Ÿ   mysql用戶名最常不能超過16個字節

Ÿ   服務使用存儲在mysql.user的密碼來驗證客戶端使用,mysql原生認證,若是指明瞭驗證插件,那麼由插件決定是否使用密碼

Ÿ   mysql的原生驗證有本身的加密算法

Ÿ   若使用的用戶密碼有非ascii的字符,那麼就要設置字符集,mysql客戶端可使用—default-character-set來修改字符集。

6.3.2 增長用戶賬號

增長新的賬號由2種方式:

1.使用create usergrant,間接操做權限表

2.直接使用dml語句,直接操做權限表,固然須要flush privileges

mysql> CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank';

 

6.3.3 刪除用戶賬號

使用drop user語句來刪除賬號

mysql> DROP USER 'francis'@'localhost'

6.3.4 設置賬號的資源限制

說是資源限制,無非就是限制每一個帳號的鏈接數。使用max_user_connections來限制。

mysql5.6以後還能夠對每一個用戶作某些限制,mariadb 10.0也有這個功能:

1.限制每小時的查詢量

2.限制每小時的update

3.限制每小時的鏈接次數

4.限制一個賬號併發的鏈接個數

以上4個限制,是經過grant語句限制的,使用help grant查看。

mysql> CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank';
mysql> GRANT ALL ON customer.* TO 'francis'@'localhost'
    ->     WITH MAX_QUERIES_PER_HOUR 20
    ->          MAX_UPDATES_PER_HOUR 10
    ->          MAX_CONNECTIONS_PER_HOUR 5
    ->          MAX_USER_CONNECTIONS 2;

 

 

對於grant中的MAX_USER_CONNECTIONS是限制併發鏈接數,若爲0,則由max_user_connections系統變量肯定併發鏈接個數,若是系統變量也爲0則不限制。

若是要修改使用 grant usage來修改。如:

mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'

    ->     WITH MAX_QUERIES_PER_HOUR 100;

若是要刪除限制就設置爲0

mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'

    ->     WITH MAX_CONNECTIONS_PER_HOUR 0;

若是grant設置的MAX_USER_CONNECTIONS會覆蓋系統變量如:

max_user_connections=10

GRANT ... TO 'user1'@'localhost' WITH MAX_USER_CONNECTIONS 0;
GRANT ... TO 'user2'@'localhost' WITH MAX_USER_CONNECTIONS 5;
GRANT ... TO 'user3'@'localhost' WITH MAX_USER_CONNECTIONS 20;

那麼user1的最大併發鏈接數爲10user25user320

 

user表中的,max_query,max_update,max_connections,存放了每小時的限制。max_user_connections存放了併發鏈接數的限制。

 

如下2個語句會重置全部賬號的限制:

1.使用flush user_resources語句

2.使用grant usage設置修改限制

6.3.5 設置密碼

密碼設置能夠在create user中也能夠set password

mysql> CREATE USER 'jeffrey'@'localhost'
    -> IDENTIFIED BY 'mypass';
mysql> SET PASSWORD FOR
    -> 'jeffrey'@'localhost' = PASSWORD('mypass');

read_only變量能夠阻止沒有有SPUER權限的用戶使用 set password

 

還可使用grant usage on *.*來設置密碼:

mysql> GRANT USAGE ON *.* TO 'jeffrey'@'localhost'
    -> IDENTIFIED BY 'mypass';

或者使用mysqladmin

shell> mysqladmin -u user_name -h host_name password "newpwd"

 

設置密碼的時候注意點:

1.當使用create user或者grang identified by語句的時候能夠直接使用明文,服務會幫助加密

2.當使用identified by password那麼須要本身先使用password()加密

3.當使用set password 的時候,要本身調用password()加密

 

固然能夠直接修改user表,可是須要執行flush privileges

6.3.6 密碼過時和沙盤模式

6.3.6.1 密碼過時工做原理

密碼過時是mysql 5.6新加的功能。(在mariadb中也有password_expired可是完成不了,下面說的功能)。

alter user 來手動過時一個用戶:

ALTER USER 'myuser'@'localhost' PASSWORD EXPIRE;

執行了以後,mysql.user.password_expired變爲Y。下次鏈接的時候用戶要不進入沙盤模式,要不就沒法鏈接。

若是進入了沙盤模式,用戶只容許作:

1.set password修改密碼

2.set語句

其餘的操做都會被拒絕。

 

disconnect_on_expired_password用來判斷如何處理過時賬號的鏈接。若是爲yes,就沒法鏈接到客戶端,爲no鏈接到客戶端,並進入沙盤模式。

 

6.3.7 插件式驗證(Pluggable Authentication

當客戶端鏈接到mysql服務,根據指定的驗證插件來驗證:

1.若是指定了驗證插件,那麼就用驗證插件驗證

2.若是沒有指定驗證插件,根據passwordhash值,肯定使用mysql_native_password仍是使用mysql_old_password

插件式的驗證方式,帶來了2個功能:

1.可擴展驗證,就是能夠經過其餘驗證插件來驗證用戶登陸

2.代理用戶,可讓登陸用戶假裝成其餘用戶執行請求

6.3.7.1 驗證插件的使用方法

1.安裝插件的libraryserverclient

2.安裝插件,能夠以配置文件,也能夠用install plugin

[mysqld]
plugin-load=test_plugin_server=auth_test_plugin.so
mysql> INSTALL PLUGIN test_plugin_server SONAME 'auth_test_plugin.so';

install plugin只要運行一次就能夠,下次啓動會自動加載插件。

3.驗證插件是否安裝

mysql> SHOW PLUGINS\G
...
*************************** 21. row ***************************
   Name: test_plugin_server
 Status: ACTIVE
   Type: AUTHENTICATION
Library: auth_test_plugin.so
License: GPL

4.設置賬號的驗證插件

CREATE USER 'testuser'@'localhost' IDENTIFIED WITH test_plugin_server;

5.使用客戶端鏈接

 

當用戶鏈接驗證的時候,服務發現是使用auth_test_plugin插件驗證,那麼服務端和客戶端交流使用 auth_test_plugin,來驗證。

 

6.3.8 MySQL中可用的驗證插件

具體看文檔:http://dev.mysql.com/doc/refman/5.6/en/authentication-plugins-available.html

6.3.9 代理用戶(proxy user

代理用戶是a用戶登陸可是使用b用戶的權限執行請求。a用戶就是代理用戶(proxy user)b用戶就是被代理用戶(proxied user)

要使用代理用戶必須知足:

1.當鏈接客戶端被當作是代理用戶,插件必須返回一個不一樣的用戶名(proxied user)。

2.代理用戶賬號必須有插件驗證

3.代理用戶必須有代理 proxied用戶的權限。

如:

CREATE USER 'empl_external'@'localhost'
  IDENTIFIED WITH auth_plugin AS 'auth_string';
CREATE USER 'employee'@'localhost'
  IDENTIFIED BY 'employee_pass';
GRANT PROXY
  ON 'employee'@'localhost'
  TO 'empl_external'@'localhost';

當登陸empl_external@localhost,使用current_user()返回:

mysql> SELECT USER(), CURRENT_USER();
+-------------------------+--------------------+
| USER()                  | CURRENT_USER()     |
+-------------------------+--------------------+
| empl_external@localhost | employee@localhost |
+-------------------------+--------------------+

是否 要用identified with as由插件決定。

6.3.9.1授予PROXY權限

PROXY權限經過 grant proxy語句被授予

GRANT PROXY ON '' TO '';proxied_userproxy_user

revoke proxy對於

REVOKE PROXY ON '' FROM '';proxied_userproxy_user

 

6.3.9.2 默認proxy用戶

如:

CREATE USER ''@'' IDENTIFIED WITH ldap_auth AS 'O=Oracle, OU=MySQL';
CREATE USER 'developer'@'localhost' IDENTIFIED BY 'developer_pass';
CREATE USER 'manager'@'localhost' IDENTIFIED BY 'manager_pass';
GRANT PROXY ON 'manager'@'localhost' TO ''@'';
GRANT PROXY ON 'developer'@'localhost' TO ''@'';

用戶登陸:

mysql --user=myuser --password='myuser_pass' ...

服務找不到myuser這個用戶,可是能匹配上’’@’’而後服務調用ldap_auth,使用myusermyuser_pass做爲用戶名密碼驗證。

若是ldap_auth發現myuser_pass不是myuser的正確密碼,鏈接失敗。

若是鏈接成功,發現myuser是一個developer,那麼就返回developer用戶名給mysql服務,而後myuser使用developer的權限:

mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER()           | CURRENT_USER()      |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+

 

若是ldap_auth返回的是manager,則:

mysql> SELECT USER(), CURRENT_USER();
+------------------+-------------------+
| USER()           | CURRENT_USER()    |
+------------------+-------------------+
| myuser@localhost | manager@localhost |
+------------------+-------------------+

 

6.3.9.3 代理用戶系統變量

主要有2個系統變量:

1.proxy_user:若是爲null,表示沒有啓動代理,若是是以默認代理用戶驗證的

mysql> SELECT @@proxy_user;
+--------------+
| @@proxy_user |
+--------------+
| ''@''        |
+--------------+

2.external_user:在驗證過程當中被使用到,會做爲插件的設置被用戶驗證客戶端。

6.3.10 使用SSL加密鏈接

mysql的標準配置是儘可能加快傳輸,因此鏈接是不加密的。

6.3.10.1 基本SSL概念

手冊:http://dev.mysql.com/doc/refman/5.6/en/ssl-basics.html

 

6.3.10.2 mysql配置SSL

1.若是不是支持SSLbianry 版本,就下載安裝OpenSSL

2. 若是不是支持SSLbianry 版本,配置編譯選項

shell> cmake . -DWITH_SSL=bundled

若是使用yassl,配置以下:

shell> cmake . -DWITH_SSL=system

而後編譯安裝

3.檢查是否支持SSL

mysql> SHOW VARIABLES LIKE 'have_ssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_ssl      | YES   |
+---------------+-------+

6.3.9.10.3 使用SSL鏈接

使用ssl鏈接須要配置一下幾個選項:

Ÿ   --ssl-ca identifies the Certificate Authority (CA) certificate.

Ÿ   --ssl-cert identifies the server public key certificate. This can be sent to the client and authenticated against the CA certificate that it has.

Ÿ   --ssl-key identifies the server private key.

如:

shell> mysqld --ssl-ca=ca-cert.pem \
         --ssl-cert=server-cert.pem \
         --ssl-key=server-key.pem

和服務端相似,能夠端的—ssl-cert—ssl-key指示了客戶端的公鑰和私鑰

使用ssl鏈接是否要指定配置,主要依賴於賬號的設置。

若是沒有給賬號設置SSL請求或者沒有使用grant require SSL 語句,那麼服務端必須指定—ssl-cert--ssl-key,客戶端要使用—ssl-ca

shell> mysql --ssl-ca=ca-cert.pem

 

若是指定了require x509那麼客戶端必須還要指定正確的客戶端的key和證書文件

shell> mysql --ssl-ca=ca-cert.pem \
       --ssl-cert=client-cert.pem \
       --ssl-key=client-key.pem

 

不使用ssl可使用—ssl=0或者 –skip-ssl,--disable-ssl

能夠經過變量查看ssl_cipher

mysql> SHOW STATUS LIKE 'Ssl_cipher';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| Ssl_cipher    | DHE-RSA-AES256-SHA |
+---------------+--------------------+

6.3.10.4 SSL相關配置

具體看:http://dev.mysql.com/doc/refman/5.6/en/ssl-options.html

 

Name

Cmd-Line

Option file

System Var

Status Var

Var Scope

Dynamic

have_openssl

 

 

Yes

 

Global

No

have_ssl

 

 

Yes

 

Global

No

skip-ssl

Yes

Yes

 

 

 

 

ssl

Yes

Yes

 

 

 

 

ssl-ca

Yes

Yes

 

 

Global

No

- Variable: ssl_ca

 

 

Yes

 

Global

No

ssl-capath

Yes

Yes

 

 

Global

No

- Variable: ssl_capath

 

 

Yes

 

Global

No

ssl-cert

Yes

Yes

 

 

Global

No

- Variable: ssl_cert

 

 

Yes

 

Global

No

ssl-cipher

Yes

Yes

 

 

Global

No

- Variable: ssl_cipher

 

 

Yes

 

Global

No

ssl-crl

Yes

Yes

 

 

Global

No

- Variable: ssl_crl

 

 

Yes

 

Global

No

ssl-crlpath

Yes

Yes

 

 

Global

No

- Variable: ssl_crlpath

 

 

Yes

 

Global

No

ssl-key

Yes

Yes

 

 

Global

No

- Variable: ssl_key

 

 

Yes

 

Global

No

ssl-verify-server-cert

Yes

Yes

 

 

 

 

6.3.10.5 mysql生成證書和公鑰私鑰

具體看:http://dev.mysql.com/doc/refman/5.6/en/creating-ssl-certs.html

6.3.11  windows使用ssh連接到mysql

具體看:http://dev.mysql.com/doc/refman/5.6/en/windows-and-ssh.html

6.3.12 Mysql企業版審計日誌插件

審計日誌插件名叫audit_log,當安裝了插件後,MySQL服務會產生日誌文件包括服務的活動審計記錄。

安裝了插件以後會寫入到審計日誌,日誌路徑由變量audit_log_file控制,默認爲audit.log

審計日誌的格式爲XML格式,在服務啓動的時候,能夠經過audit_log_format控制系統變量,設置日誌格式。

audit_log_policy控制審計的事件,默認爲all,能夠設置爲LOGINSQUERIESNONE

 

把日誌記錄格式從老的改爲新的須要如下步驟:

1.中止服務

2.重命名審計日誌文件

3.使用新的audit_log_format重啓服務

 

注:

mariadb使用的審計插件和mysql 5.6不一樣,mariadb使用server audit

具體看:

https://mariadb.com/kb/en/mariadb/documentation/mariadb-plugins/server_audit-mariadb-audit-plugin/about-the-mariadb-audit-plugin/

 

6.3.12.1 安裝審計插件

使用配置文件,或者命令行參數plugin-load設置:

[mysqld]
plugin-load=audit_log.so

或者使用install plugin加載

mysql> INSTALL PLUGIN audit_log SONAME 'audit_log.so';

使用了install plugin以後,下次啓動會自動加載

使用audit-log配置文件,來強制插件初始化,不然服務啓動報錯。

6.3.12.2 審計日誌安全性考慮

審計日誌不加密,爲了考慮到敏感信息安全性問題,考慮放在只能管理員和mysql啓動用戶訪問。

6.3.12.3 審計日誌

主要介紹老的格式和新的格式的字段意義

具體看:http://dev.mysql.com/doc/refman/5.6/en/audit-log-file.html

6.3.12.4 審計日誌記錄控制

當審計日誌插件打開日誌文件的時候,查看是否包含<AUDIT>根標籤,如有則寫入內容,當寫入完成,寫入</AUDIT>結束。

若是啓動時已經存在日誌文件,檢查是否存在</AUDIT>,若是有則先截斷,而後寫入審計記錄。若是沒有</AUDIT>或者不能截斷,就認爲插件初始化失敗。常發生於服務crash或者被kill可是審計插件任然在運行的狀況。

[ERROR] Plugin 'audit_log' init function returned error.

解決辦法,直接刪除審計日誌而後重啓。

 

服務當審計事件發生就寫入審計日誌。

審計日誌插件提供了一些系統變量:

1.audit_log_file:審計日誌文件路徑

2.audit_log_policy:用來決定審計事件,可選值:NONE,LOGINS,QUERIES.

3.audit_log_strategy:用來控制寫入審計日誌的方式,可取值以下:

Value

Meaning

ASYNCHRONOUS

Log asynchronously, wait for space in output buffer

PERFORMANCE

Log asynchronously, drop request if insufficient space in output buffer

SEMISYNCHRONOUS

Log synchronously, permit caching by operating system

SYNCHRONOUS

Log synchronously, call sync() after each request

4.audit_log_buffer_size:用來給異步審計日誌寫入作緩存

5.audit_log_rotate_on_sizeaudit_log_flush:這2個主要控制審計日誌的迴繞和刷新,審計日誌會隨着時間推移變得愈來愈大,爲了增強磁盤空間管理,能夠自動迴繞,會在手動刷新並打開一個新的日誌文件。

 

默認audit_log_rotate_on_size=0是不會迴繞的,只有修改audit_log_flush纔會執行刷新審計日誌並從新打開。假設須要維護3個最近的審計日誌以下:

1.重命名文件

shell> mv audit.log.2 audit.log.3

shell> mv audit.log.1 audit.log.2

shell> mv audit.log audit.log.1

這個時候,插件任然往當前的審計日誌寫,已經被重命名爲了audit.log.1

2.鏈接到服務刷新日誌文件,插件會關閉當前日誌,並打開一個新的日誌

mysql> SET GLOBAL audit_log_flush = ON;

 

 

audit_log_rotate_on_size大於0audit_log_flush=1是沒有意義的,寫入後文件的大小大於audit_log_rotate_on_size,服務會重命名審計日誌,打開一個新的審計日誌。

6.3.12.5 審計日誌插件選項和變量

具體看:

http://dev.mysql.com/doc/refman/5.6/en/audit-log-plugin-options-variables.html

6.3.13 SQL-Based MySQL帳號活動審計

具體看:http://dev.mysql.com/doc/refman/5.6/en/account-activity-auditing.html

相關文章
相關標籤/搜索