对mysql来讲,其访问受权相关模块主要是由两部分组成。html
(1)一个是基本的用户管理模块;另外一个是访问受权控制模块。 (2)用户管理模块相对简单,主要是负责用户登录链接相关的基本权限控制,但其在安全控制方面的做用没必要任何环节小。 (3)他就像mysql的一个“大门门卫”同样,经过校验每一位敲门者所给的进门“暗号”(登入口令),决定是非给敲门者开门。 (4)而访问控制模块则是随时随地检查已经进门的访问者,校验他们是否有访问所发出请求须要访问的数据的权限。 (5)经过校验者能够顺利拿到数据,而未经过校验的访问者,只能收到“访问越权”的相关反馈。
SQL语句相关安全因素:mysql
(1)“SQL注入攻击”指的就是攻击者根据数据库的SQL语句解析器的原理,利用程序中对客户端所提交数据的校验漏洞,从而经过程序动态提交数据接口提交非法数据,达到攻击者的入侵目的。 (2)“SQL注入攻击“的破坏性很是大,轻者形成数据被窃取,重者数据遭到破坏,甚至可能丢失所有的数据。
程序代码相关安全因素:sql
(1)程序代码若是权限校验不够仔细而存在安全漏洞,则一样可能会被入侵者利用,达到窃取数据等目的。 (2)好比一个存在安全漏洞的信息管理系统,很容易就可能窃取到其余一些系统的登入口令。以后,就能冠冕堂皇的轻松登录到其余相关系统达到窃取相关数据的目的。 (3)甚至还可能经过应用系统中保存不善的数据库系统链接登录口令,从而带来更大的损失。
Global Level:数据库
(1)Global Level的权限控制也叫全局权限控制,全部权限信息都保存在mysql.user表中。 (2)Global Level的全部权限都是针对整个mysqld的,对全部的数据库下的全部表及全部字段都有效。 (3)若是一个权限是以Global Level来授予的,则会覆盖其余全部级别的相同权限设置。 (4)好比咱们首先给abc用户受权能够update指定数据库如test的t表,而后又在全局级别REVOKE掉了abc用户对全部数据库的全部表的UPDATE权限,那么这时候的abc用户将再也不拥有对test.t表的更新权限。 (5)要授予Global Level的权限,则只须要在执行GRANT命令的时候,用“*.*”来指定适用范围是Global的便可,当有多个权限须要授予的时候,也并不须要屡次重复执行GRANT命令,只须要一次将全部须要的权限名称经过逗号(“,”)隔开便可,如:GRANT SELECT,UPDATE,DELETE,INSERT ON *.* TO 'def'@'localhost';
Database Level:安全
(1)Database Level是在Global Level之下,其余三个Level之上的权限级别,其做用域即为所指定整个数据库中的全部对象。 (2)与Global Level相比,Database Level主要少了如下几个权限:CREATE USER、FILE、PROCESS、RELOAD、REPLICATION CLIENT、REPLICATION SLAVE、SHOW DATABASES、SHUTDOWN、SUPER和USAGE这几个权限,没有增长任何权限。 (3)以前咱们说Global Level的权限会覆盖底下其余四层的相同权限,Database Level也同样,虽然他可能被Global Level的权限所覆盖,但同时他也能覆盖比他更下层的Table、Column和Routine这三层的权限。 (4)若是要授予Database Level的权限,则能够有两种实现方式: 【1】在执行GRANT命令的时候,经过“database.*”来限定权限做用域为database整个数据库:GRANT ALTER ON test.* TO 'def'@'localhost'; 【2】先经过USE命令选定须要受权的数据库,而后经过“*”来限定做用域,这样受权的做用域实际上就是当前选定的数据库 (5)在授予权限的时候,若是有相同的权限须要授予多个用户,咱们也能够在受权语句中一次写上多个用户信息,用逗号分隔开就能够了,如:grant create on perf.* to 'abc'@'localhost','def'@'localhost';
Table Level:网络
(1)Database Level之下就是Table Level的权限了,Table Level的权限能够被Global Level 和Database Level的权限所覆盖,同时也能覆盖Column Level 和Routine Level 的权限。 (2)Table Level 的权限做用范围是受权语句中所指定数据库的指定表。如能够经过以下语句给test数据库的t1表受权:GRANT INDEX ON test.t1 TO 'abc'@'%.jianzhaoyang.com'; (3)Table Level的权限因为其做用域仅限于某个特定的表,因此权限种类也比较少,仅有ALTER、CREATE、DELETE、DROP、INDEX、INSERT、SELECT、UPDATE这八种权限。
Column Level:函数
(1)Column Level的权限做用范围就更小了,仅仅是某个表的指定的某个列。 (2)因为权限覆盖的原则,Column Level的权限一样能够被Global、Database、Table这三个级别的权限中的相同级别所覆盖,并且因为Column Level所针对的权限和Routine Level的权限做用域没有重合部分,因此不会有覆盖与被覆盖的关系。 (3)Column Level的权限只有INSERT、SELECT和UPDATE这三种。 (4)Column Level的权限受权语句语法基本和Table Level差很少,只是须要在权限名称后面将须要受权的列名列表经过括号括起来:GRANT SELECT(id,value) ON test.t2 TO 'abc'@'%.jianzhaoyang.com'; (5)当某个用户在向某个表插入数据的时候,若是该用户在该表中某列上面没有INSERT权限,则该列的数据将以默认值填充。这一点和不少其余的数据库有一些区别,是mysql本身在SQL上面的扩展。
Routine Level:工具
(1)Routine Level的权限主要只有EXECUTE和ALTER ROUTINE两种,主要的针对的对象是procedure 和function这两种对象。 (2)在授予Routine Level权限的时候,须要指定数据库和相关对象,如:GRANT EXECUTE ON test.p1 to 'abc'@'localhost';
GRANT权限:性能
(1)除了上述几类权限外,还有一个很是特殊的权限GRANT,拥有GRANT权限的用户能够将自身所拥有的任何权限所有授予其余任何用户,因此GRANT权限是一个很是特殊也很是重要的权限。 (2)GRANT权限的授予方式也和其余任何权限都不太同样。 (3)一般是经过在执行GRANT受权语句的时候在最后添加WITH GRANT OPTION子句达到授予GRANT权限的目的。 (4)另外,咱们还能够经过GRANT ALL语句授予某个Level的全部可用权限给某个用户,如: grant all on test.t5 to 'abc';
用户管理:加密
(1)在mysql中,用户访问控制部分的实现比较简单,全部受权用户都存放在一个系统表中:mysql.user,固然这个表不只存放了受权用户的基本信息,还存放有部分细化的权限信息。 (2)用户管理模块须要使用的信息不多,主要就是Host、User、Password这三项,都在mysql.user表中 (3)一个用户想要访问mysql,至少须要提供上面列出的三项数据,mysql才能判断是否该让它进门。 (4)这三项实际是由两部分组成:来访者来源的主机名(或主机IP地址信息)和访问者的来访“暗号”(登录用户名和登录密码),这两部分中的任何一个没有可以匹配上都没法让看守大门的用户管理模块乖乖开门。 (5)其中Host信息存放的是mysql容许所对应的User的信任主机,能够是某个具体的主机名或域名,也能够是用“%”来充当通配符的某个域名集合,也能够是一个具体的IP地址,一样也能够是存在通配符的域名集合,还能够用“%”来表明任何主机,就是不对访问者的主机作任何限制。
访问控制:
(1)当客户端链接经过用户管理模块的验证,可链接上mysql server以后,就会发送各类Query和Command给mysql server,以实现客户端应用的各类功能。 (2)当mysql接收到客户端的请求以后,访问控制模块是须要校验该用户是否知足提交的请求所须要的权限。 (3)权限校验过程是从最大范围往最小范围的权限开始依次校验所涉及到的每一个对象的每一个权限。 (4)在验证所需权限的时候,mysql首先会查找存储在内存结构中的权限数据,首先查找Global Level权限,若是所需权限在Global Level都有定义(GRANT或REVOKE),则完成权限校验(经过或者拒绝); (5)若是没有找到全部权限的定义,则会继续查找Database Level的权限,进行Global Level未定义的所需权限的校验,若是仍然没有找到全部所需权限的定义,则会继续往更小范围的权限定义域查找,也就是Table Level、Column Level或者Routine Level。 (6)在前面咱们了解到mysql的grant tables有mysql.user、mysql.db、mysql.host、mysql.table_priv和mysql.column_priv这五个。 (7)我想除了mysql.host以外的四个都很是容易理解,每个表都针对mysql的一种逻辑对象,存放某一特定Leve的权限,惟独mysql.host稍有区别。 (8)咱们来看看mysql.host权限表在mysql访问控制中充当了什么样的角色? 【1】mysql.host在mysql访问控制模块中所实现的功能比较特殊,和其余几个grant tables不太同样。 【2】首先mysql.host中的权限数据不是经过GRANT或REVOKE来授予或者去除,而是必须手工经过INSESRT、UPDATE和DELETE命令来修改其中的数据。 【3】其次是其中的权限数据没法单独生效,必须经过和mysql.db权限表的数据一块儿才能生效。 【4】并且仅当mysql.db总存在不完整的时候,才会促使访问控制模块再结合mysql.host中查找是否有相应的补充权限数据实现以达到权限校验的目的。 【5】在mysql.db中没法找到知足权限校验的全部条件的数据,则说明在mysql.db中没法完成权限校验,因此也不会直接校验db.select_priv的值是不是Y。 (9)mysql的权限授予至少须要用户名和主机名两者才能肯定一个访问者的权限。 (10)mysql如何肯定权限信息?实际上,mysql永远优先考虑更精确范围的权限。 (11)在mysql内部会按照username和hostname作一个排序,对于相同username的权限,其host信息越接近访问者的来源host,则排序位置越靠前,则越早被校验使用到。 (12)并且mysql在权限校验过程当中,只要找到匹配的权限以后,就不会再继续日后查找是否还有匹配的权限信息,而直接完成校验过程。
首先须要了解来访主机:
(1)因为mysql数据库登录验证用户的时候是除了用户名和密码以外,还要验证来源主机,因此咱们还须要了解每一个用户可能从哪些主机发起链接。 (2)固然,咱们也能够经过受权的时候直接经过“%”通配符来给全部主机授予都有访问的权限,可是这样就违背了咱们安全策略的原则,带来了潜在风险,因此并不可取。 (3)尤为是在没有局域网防火墙保护的状况下,更是不能轻易容许能够从任何主机登录的用户存在。 (4)能经过具体主机名和IP地址指定的尽可能经过使用具体的主机名和IP地址来限定来访主机,不能用具体的主机名和IP地址限定的也须要用尽量小的通配范围来限定。
其次,了解用户需求:
(1)既然要作到仅授予必要的权限,那么咱们必须了解每一个用户所担当的角色,也就是说,咱们充分了解每一个用户须要链接到数据库上完成什么工做。 (2)了解用户是一个只读应用的用户,仍是一个读写都有的用户,是一个备份做业的用户仍是一个平常管理的用户,是只须要访问特定的数据库,仍是须要访问全部的数据库。 (3)只有了解了须要作什么,才能准确的了解须要授予什么样的权限。 (4)由于若是权限太低,会形成工做没法正常完成,而权限太高,则存在潜在的安全风险。
再次,要为工做分类:
(1)为了作到各司其职,咱们须要将须要作的工做分门别类,不一样类别的工做使用不一样的用户,作好用户分离。 (2)虽然这样可能会带来管理成本方面的部分工做量增长,可是基于安全方面的考虑,这部分管理工做量的增长是很是值得的。 (3)并且咱们所要作的分离也只是适度的分离。好比将执行备份工做、复制工做、常规应用访问、只读应用访问和平常管理工做分别分理出单独的特定帐户来授予各自所需权限。 (4)这样,既可让安全风险尽可能下降,也可让同类同级别的类似权限合并在一块儿,不互相交织在一块儿。 (5)对于PROCESS、FILE和SUPER这样的特殊权限,仅仅只有管理类帐号才须要,不该该授予其余非管理帐号。
最后,确保只有绝对必要者拥有GRANT OPTION权限:
(1)以前在权限系统介绍的时候咱们已经了解到GRANT OPTION权限的特殊性,和拥有该权限以后的潜在风险,因此在这里就不赘述了。 (2)总之,为了安全考虑,拥有GRANT OTPION权限的用户越少越好,尽量只让拥有超级权限的用户才拥有GRANT OPTION权限。