zoukankan      html  css  js  c++  java
  • [MySQL Reference Manual] 6 安全性

    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 PLUGINSG
    ...
    *************************** 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

     

  • 相关阅读:
    【Python】小练习
    【C语言】利用二维数组输出成绩
    【C语言】多维数组
    【C语言】输入一个字符串,并对字符串中的偶数位置的字符按从小到大的顺序排序,奇数位置的字符不动,输出排序后的结果
    【C语言】一堆数组中存放了10个小于100的整数,请编程对所有数据按照从小到大的顺序进行排序,若个位数相等,则按照十位从小到大的顺序排序,输出排序后的结果
    【C语言】移动指针
    Python中68个内置函数的总结
    【Python】变量命名习惯
    【Python】 基础语法
    【Python】 注释
  • 原文地址:https://www.cnblogs.com/Amaranthus/p/3895721.html
Copyright © 2011-2022 走看看