细聊MySQL的安全机制

MySQL作为系统的数据库,在安全性方面有非常高的要求。如果一个系统的数据库被非法进入或窃听,则系统的数据将受到非常严重的威胁,轻则数据、密码被盗,重则导致整个系统瘫痪。所以数据库的安全对于系统来说是非常重要的。

本文将从MySQL的服务器启动与客户端访问、操作及链路三方面来阐述MySQL的安全机制。

一、MySQL的服务器启动与客户端访问。
        1、服务器启动,启动服务器在安全方面的影响主要是启动它的用户。默认情况下,MySQL不允许使用root账号启动。我们应该建立一个只能操作MySQL安装目录与数据目录的非交互式账号来运行mysqld服务器。另外,服务器最好针对指定客户机开放,应将服务器置于iptables后,如果过让任意主机都能通过telnet的方式连线到服务器,也将是不安全的。telnet的测试方式为shell > telnet ip(服务器的ip)3306(服务器的默认端口)
        2、客户端访问,使用bin/mysql客户端工具登录时可以通过配置文件及直接在命令行添加参数两种方式。在登录时,我们需要使用密码才能进入,然而MySQL在安装后默认root账号是没有密码的。所以我们首先需要为root设置密码。如果root没有设置密码,那么可以通过以下方式设置:
        2.1 shell > bin/mysql —user=root —host=127.0.0.1,回车后应该进入到mysql客户端的交互界面。
        2.2 mysql > set password for ‘root’@‘127.0.0.1’ = password(’你设置的明文密码’)。这样127.0.0.1下的root密码就设置好了。需要注意的是,MySQL的登入账号不仅仅是用户名,而是用户名+IP或域名的方式确认唯一一个连线的。所以,如果该服务器的IP是192.168.1.5,在设置密码时我只设置了’root’@‘127.0.0.1’的密码,那么当用mysql —host=192.168.1.5 —user=root —password=’你设置的明文密码’登录时,会提示错误。所以,如果我们不在服务器本地登陆,那么我们还需要设置密码set password for ‘root’@‘192.168.1.5’=password(’你设置的明文密码’)。 另外一个需要注意的是,在设置密码时,我们使用了password()函数,password函数将明文密码转换成41个字节长的hash值。增加了密码的安全性。
        如果我们将密码放置在配置文件中,记得将配置文件的访问权限设置成600或400,你也不想其它用户能够轻易的读到它吧。

二、MySQL操作的授权管理系统安全机制
        2.1 MySQL权限管理系统的主要功能是验证客户端用户的登入以及验证该用户具体的对MySQL的操作权限,比如该用户可能只对某个数据库的其中某个表具有update权限和insert权限,那么系统将会禁止TA对其它的表进行写操作。但,以下的事情是权限系统办不到的:
        2.1.1、你不能指定具体拒绝登入的用户。
        2.1.2、你不能指定一个用户创建或删除一个数据库里的表,但又不让TA创建或删除该表所属的数据库。
        2.1.3、用户的密码是全局性的,你不能针对数据库或表来设置密码。

2.2 MySQL将权限分为全局权限与对象权限。所谓的全局权限是与数据库、表、视图等不相干的权限,如密码的设置、用户的创建等。对象权限是相对于全局权限的,也就是与数据库、表、视图、列、索引等一切对象相关的权限。
        关于权限的信息存储在mysql数据库中的user、db、tables_priv、columns_priv和prods_priv表里,在服务器启动后,程序会将权限表载入到内存里,客户端连入时会根据权限表验证用户的合法性,当客户端发出请求时,也会根据权限表验证用户操作的合法性。
        下面我们可以大致看下我们能控制的具体权限以及这些权限作用的范围和控制权限的列名。

权限 控制权限的列名 作用范围
CREATE Create_priv 数据库、表、索引
DROP Drop_priv 数据库、表、视图
LOCK TABLES Lock_tables_priv 数据库
REFERENCES References_priv 数据库、表
EVENT Event_priv 数据库
ALTER Alter_priv
DELETE Delete_priv
INDEX Index_priv
INSERT Insert_priv 表、列
SELECT Select_priv 表、列
UPDATE Update_priv 表、列
CREATE TEMPORARY TABLES Create_tmp_table_priv
TRIGGER Trigger_priv
CREATE VIEW Create_view_priv 视图
SHOW VIEW Show_view_priv 视图
CREATE TABLESPACE Create_tablespace_priv 全局
CREATE USER Create_user_priv 全局
PROCESS Process_priv 全局
PROXY see proxies_priv table 全局
RELOAD Reload_priv 全局
REPLICATION CLIENT Repl_client_priv 全局
REPLICATION SLAVE Repl_slave_priv 全局
SHOW DATABASES Show_db_priv 全局
SHUTDOWN Shutdown_priv 全局
SUPER Super_priv 全局
ALL [PRIVILEGES] 全局
USAGE 全局

我们可以根据上表进行相应的权限设置。要设置权限,首先得知道我们设置的用户的当前的权限。利用下面的命令可知:
mysql > show grants for ‘user’@‘ip’;
再次强调下,虽然使用show grants for ‘user’;也可以显示,但’user’@‘ip’才代表mysql的一个唯一用户。调用命令后将显示如下结果:
GRANT USAGE ON *.* TO ‘wangwei‘@‘%‘ IDENTIFIED BY PASSWORD ‘*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9‘ WITH MAX_QUERIES_PER_HOUR 20

USAGE是上表中的最后一行的值,是一个全局权限,只是代表能够进入到数据库。
        *.*第一个*代表数据库名,第二个*代表表名。
        IDENTIFIED BY后是密码
        WITH后是权限参数,这里是限制每小时最多查询20次

然后开始设置我们自己的权限,如想设置某个表某列的查询权限则命令如下:
        mysql > grant select(列名) on 数据库名.表名 to ‘用户名’@‘IP’;
        这样,该用户即有指定列的查询权限了。

2.3 密码过期策略。如果你想让mysql用户隔一段时间设置一次密码,可用以下方法。
        mysql > alter user ‘user’@‘ip’ password expire;    使该用户密码立即失效
        mysql > alter user ‘user’@‘ip’ password expire interval 90 day;    每隔90天密码需要重设一次
        mysql > alter user ‘user’@‘ip’ password expire never;    密码永不过期
        还可以通过配置文件设置密码的默认过期时间如:
        [mysqld]
        default_password_lifetime=180

三、链路通讯安全。客户端通过网路与服务器通讯,除传输登录验证信息外还请求具体的数据库操作。所以服务器与客户端之间数据的保密性与完整性是非常重要的。这里,我们通过SSL来保证数据的安全性。
        要使用SSL,需要MySQL服务器支持SSL协议。使用mysql > show variables like ‘have_ssl’;可以查询MySQL是否支持SSL。如果显示YES则该服务器正以SSL协议在运行。如果显示DISABLED则表示服务器支持SSL,但是没有开启SSL。如果显示其它,则表示MySQL服务器不支持SSL。需要重新下载新版本的MySQL或重新编译,启动SSL功能。本人所用的是MySQL 5.6的二进制版本,默认是支持SSL的。下面介绍下具体的配置方法。
        配置SSL只需要四个参数ssl、ssl-ca、ssl-cert、ssl-key。ssl表明启动SSL功能。ssl-ca为CA证书的位置。ssl-cert为由CA签名的服务器证书所在位置。ssl-key为服务器的私钥位置。如果对CA及X509比较熟悉的朋友应该很好理解,这几个参数的作用。对不不理解的朋友最好去学习下CA认证与SSL协议的原理。不管你是否熟悉SSL。按照以下步骤应该也可以配置好安全链路的MySQL通讯。
        下面介绍下具体的实现步骤:
        1、下载和安装openssl。下载地址为http://www.openssl.org/source/。可以下载最新版openssl-1.0.1j.tar.gz。我就是用的最新版本。
              安装方法:
                shell > tar zxvf openssl-1.0.1j.tar.gz
        shell > cd openssl-1.0.1j && ./config --prefix=/usr/local —    openssldir=/usr/local/openssl
        shell > make
        shell > make install
    安装后在/usr/local/bin下可找到openssl的命令。上面是很简单的源码编译安装方法,不用详细解释了。按照以上步骤应该可以安装好openssl。

2、建立CA证书
            shell > mkdir newcerts && cd newcerts
            shell > openssl genrsa 2048 > ca-key.pem 建立CA私钥
            shell > openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca-cert.pem    建立CA根证书
        
        3、建立CA签名的服务器证书及私钥
            shell > openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem    建立服务器证书请求文件及服务器私钥
            shell > openssl rsa -in server-key.pem -out server-key.pem    加密私钥
            shell > openssl x509 -req -in server-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem 签名服务器证书

生成的ca-cert.pem用于ssl-ca参数
        生成的server-cert.pem用于ssl-cert参数
        生成的server-key.pem用于ssl-key参数

服务器运行命令如下
        mysqld —user=mysql —ssl —ssl-ca=/path/ca-cert.pem —ssl-cert=/path/server-cert.pem —ssl-key=/path/server-key.pem
        
        客户端也可以创建SSL证书进行双向验证,也可以不做设置直接连接到服务器。运行后可用mysql > show variables like ‘have_ssl’;验证。如果结果显示YES。代表SSL设置成功。否则需要调试看看是什么问题。
        如果出现问题,首先可以用shell> openssl verify -CAfile ca-cert.pem server-cert.pem看看证书是否正确生成。如果仍然有问题需要看下mysqld运行用户是否有权限读取证书。

时间: 2024-07-30 10:14:27

细聊MySQL的安全机制的相关文章

细聊MySQL的Innodb存储引擎(二)

细聊MySQL的Innodb存储引擎(一) 上一篇主要和大家探讨了下Innodb的锁机制与隔离机制.本篇来和大家一起研究下在使用Innodb是会出现的问题以及如何解决它们. Innodb是如何解决幻读问题的 什么是幻读?听起来似乎很高端,但实际上它只是反映了事务中的一种数据不一致的情况.下面看我来描述这样一个场景,通过这个场景,大家就能很清楚的知道幻读到底是什么意思. 打开两个客户端,设为A和B A客户端 mysql> start transaction; (步骤一) Query OK, 0 r

细聊MySQL的Innodb存储引擎(完)

细聊MySQL的Innodb存储引擎(一) 细聊MySQL的Innodb存储引擎(二) 细聊MySQL的Innodb存储引擎(完) 上篇主要和大家探讨了Innodb引擎中出现幻读的处理方法与死锁的探测及避免死锁的一些注意事项.此篇,我们来研究下Innodb的索引. Innodb里涉及到的索引主要有四种,分别为聚簇索引(Clustered Index).次级索引(Secondary Index).全文索引(FULLTEXT Index).哈希索引(Hash Index). 聚簇索引与次级索引 每一

细聊MySQL之常用工具及基本操作(二)

接细聊MySQL之常用工具及基本操作(一) 四.客户端管理工具mysqlcheck的使用.mysqlcheck是客户端表维护工具,可以检查.修复.优化或分析表. 如 shell> mysqlcheck databasename tablename [options] databasename为数据库名 tablename为表名 如果你只指定databasename,通常会检查databasename下所有的表.如果你既不指定databasename,也不指定tablename,那么一定要添加参数

细聊MySQL之常用工具及基本操作(三)

细聊MySQL之常用工具及基本操作(一) 细聊MySQL之常用工具及基本操作(二) 七.使用mysqlshow工具查看数据库.表和列的信息.具体语法: shell> mysqlshow [options] [db_name [tbl_name [col_name]]] 注:如果没有数据库给定,列出数据库列表 如果没有表给定,列出所有数据库的表 如果没有列给定,列出表内所有的列 详细参数如下: 参数 描述 适用 弃用 --bind-address=ip_address 同mysql命令 --com

细聊MySQL的分区功能

此篇主要介绍下MySQL的分区功能.我们分别从分区的概念.分区对于MySQL应用的优点.分区的类别及设置来和大家一起探讨下MySQL的分区. 什么是分区? MySQL在未启用分区功能时,数据库的单个表内容是以单个文件的形式存放在文件系统上的.当启用分区功能后,MySQL将按用户指定的规则将单个表内容分割成几个文件存放在文件系统上.分区分为水平分区和垂直分区,水平分区是将表的数据按行分割成不同的数据文件,而垂直分区则是将表的数据按列分割成不同的数据文件.分片要遵循完备性原则.可重构性原则与不相交原

细聊MySQL的Innodb存储引擎(一)

从MySQL5.5开始,Innodb就成为MySQL的默认存储引擎了.可想而知,Innodb已经成为MySQL的主要生产方式.那Innodb到底有什么本事能够击败其它几位存储引擎而荣登宝座呢?下面,我就来和大家一起探讨探讨牛逼的Innodb引擎.Innodb涉及到的知识点比较多,所以我会分几篇来叙述,此篇主要介绍Innodb的基本概念和架构. 要了解Innodb,首先需要了解MySQL的ACID模型.何为ACID?ACID指的是事务的原子性(A).一致性(C).隔离性(I).持久性(D). 原子

细聊MySQL的备份与恢复

备份对于数据库来说是相当重要的工作.如果数据库在使用过程中出现了问题,比如系统崩溃.硬件故障或错误的删除了数据.这时,如果我们进行了数据备份,就能比较方便的使数据库恢复工作,并使我们的数据损失到最小.下面,我从备份类型.备份方法及一些常用的例子来和大家详细探讨下数据库的备份与恢复. 一.备份类别 1.物理备份与逻辑备份 物理备份用人话来形容就是复制数据库的数据文件.如果我们需要备份名为test的数据库,则我们可以将数据目录下的test目录复制到备份设备中.如果我们需要备份test库下名为user

细聊MySQL之基本安装与启动

由于MySQL的生产环境通常会部署在Linux上,所以这里只说下Linux上的安装与启动. 一.版本识别 MYSQL的版本说明:如mysql-5.7.1-m1 第一个数字5代表主版本号和描述文件格式.所有的MYSQL 5发布版本有一样的文件格式. 第二个数字7代表发布等级.主版本号5和发布登记合起来组成发布序列号. 第三个号码1代表发布次数.每次有新的发布,发布次数号增加1. m+数字代表一个里程碑号,MYSQL开发使用一个里程碑模型管理. rc代表一个发布候选.发布候选版本通常是稳定的.通过了

细聊MySQL之常用工具及基本操作(一)

一.对于MySQL用户来说,使用MySQL的第一步就是启动它.要启动MySQL,我们需要mysqld或mysqld_safe命令.默认情况下,直接执行mysqld或mysqld_safe即可.如 shell> mysqld & 或 shell> mysqld_safe &.当然不是所有事情都那么顺利,如果启动不了,请指定相关的参数.服务器运行的前提是你已经执行了mysql_install_db脚本.当然,如果就这样启动,将有很多功能启动不了.如没有binlog,当某一天你不小心