Fanr

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

6. 安全性

Mysql安装配置时要考虑安全性的影响,以下几点:

Ÿ   常规因素影响安全性

Ÿ   程序自身安全性

Ÿ   数据库内部的安全性,即,访问控制

Ÿ   网络安全性和系统安全性

Ÿ   数据文件的备份,日志文件和配置文件的安全性

6. 安全性... 1

6.1 常规安全性问题... 2

6.1.1安全性最佳实践... 2

6.1.2 保持密码安全性... 2

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 'proxied_user' TO 'proxy_user';

revoke proxy对于

REVOKE PROXY ON 'proxied_user' FROM 'proxy_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

 

posted on 2014-08-06 20:37  Fanr_Zh  阅读(973)  评论(0编辑  收藏  举报