美文网首页程序员专栏
从删库到跑路:漫谈MySQL权限安全

从删库到跑路:漫谈MySQL权限安全

作者: 享学课堂 | 来源:发表于2019-06-28 20:09 被阅读16次

    作者:享学课堂Deer老师
    转载请声明出处!

    从删库到跑路,我想作为程序员的你肯定听过无数次这样的话语,这话已经成为程序员搭话的一句玩笑话。

    但仅仅只是一句玩笑吗?绝不,从小deer 十多年在程序员的江湖中混搭就发现过无数次这样的情况:

    某某一天,初级程序员张某本想在测试库删除测试订单数据,结果误打开正式库,结果delete 订单表,而且数据没做备份,后果呢? 呵呵哒~

    某某一天,初级开发本想在测试库用户表删除两字段,结果也是误打开正式库,删除了正式库的字段,结果还好,部门经理被老板一顿臭骂。

    某某一天,新入职的实习生,想把数据库的数据导出一份学习,没错,他导出了正式库的数据,而且用来写论文发,导致客户的信息等隐私信息被透露。

    ……

    这事情不要发生太多。而最终的肇事者就是让人鄙夷的初级程序员,实习生,新手?

    这锅真该新手背吗? 另外这些新手背得起吗? 哪怕把这些新手开除了公司已经带了得损失谁负责呢?

    真正该对这负责的技术经理,架构师,你没有把数据库的权限控制好。

    那么来接下来的时间来谈谈mysql这个数据库的权限?把这些掌握好面试也好,以后在工作中也好,你可以少走很多弯路。

    1. 那么多数据库为什么来谈mysql

    嗯,这是个好问题,如果你公司有钱倒腾oracle,出问题能找oracle 公司的dba背锅,那就放弃mysql吧,mysql太low。

    比如你所在公司是中国电力,在10年的时间仅仅在oralce的使用上就支出就是390几个亿,平均一年30,40个亿,嗯,能有钱解决的都不是事。

    问题,绝大多数公司没钱,起码没这么有钱。

    另外还有很多公司有钱也要用mysql,还是举例来说:

    全世界访问量最大的20家公司,他们有钱吧? 仅仅两家不是使用的mysql,分别是live.com和bing,为啥? 因为它是微软,它得支持自己的MsSql。

    另外再看张图:

    他们也全都是使用mysql,所以,我也讲mysql。

    2. 最简单的MySql权限

    最简单也是最高效的,如果解决新手们删库跑路的问题其实也是很简单的,对于正式库只给一个增删改查的权限,或者只给一个查询权限(是不是就解决了删库的可能性?)

    以下内容如果看官是大牛,请稍安勿躁,我讲内容的方式是从简单到入门,从入门到进阶,从进阶到实战,从实战到。。。(包你满意)

    使用Root用户,执行:

    grant SELECT on mall.* TO 'dev'@'192.168.0.%' IDENTIFIED BY '123' WITH GRANT OPTION;
    

    很简单的一句sql,创建了一个dev的用户,密码为123,仅仅运行在网段为192.168.0.*的网段进行查询操作。

    再执行一条命令:

    show grants for 'dev'@'192.168.0.%'
    

    不错,可以链接,也可以执行select,这个时候还想删库?做梦吧~

    3. 深入研究下MySQL权限

    3.1. 用户标识是什么

    上面一句简单的SQL堪称完美的解决了程序员新手的删库跑路的问题,高兴吧,你学到了新姿势,但是如果想面试给面试管留下好映像,上面的知识好像还不够,有必要好好深入研究下MySql的权限了。

    这里有个小的知识点需要先具备,在mysql中的权限不是单纯的赋予给用户的,而是赋予给”用户+IP”的。

    比如dev用户是否能登陆,用什么密码登陆,并且能访问什么数据库等都需要加上IP,这样才算一个完整的用户标识,换句话说 'dev'@'192.168.0.168''dev'@'127.0.0.1''dev'@'localhost' 这3个是完全不同的用户标识(哪怕你本机的ip就是192.168.0.168)。

    3.2. 用户权限所涉及的表

    有了用户标识的概念接下来就可以看权限涉及的表了,这也是面试的时候加分项哦。

    有几张表你可以好好的记记的,mysql.user,mysql.db,mysql.table_priv,mysql_column_priv。

    你可以熟悉其中的user表,甚至手动的改过里面的数据(不合规范哦!)

    那这些表有什么用,和权限又有什么关系呢?

    l User的一行记录代表一个用户标识;

    l db的一行记录代表对数据库的权限;

    l table_priv的一行记录代表对表的权限;

    l column_priv的一行记录代表对某一列的权限。

    很诧异吧,mysql其实权限并不是特别low,权限的粒度甚至到了某一列上,举例来说,有个表account表:

    对于前面创建的dev用户我不想让他访问balance列,但是id和name列是可以访问的,这样的需求在工作中不是没有。

    grant select(id,name) on mysqldemo.account to 'dev'@'192.168.0.%';
    

    这时候可以在分别看下table_priv,column_priv的数据:


    这个就应该豁然开朗了吧!

    你使用dev登陆查询试试:

    你再要查询所有记录?不好意思不让查。

    而你查询id,name查询又是可以了。


    3.3. Mysql的角色

    3.3.1. 准备工作

    MySql基于”用户+IP”的这种授权模式其实还是挺好用的,但如果你使用Oracle、PostgreSQL、SqlServer你可能会发牢骚。

    这样对于每个用户都要赋权的方式是不是太麻烦了,如果我用户多呢?有没有角色或者用户组这样的功能呢?

    好吧,你搓中了mysql的软肋,很痛,在mysql5.7开始才正式支持这个功能,而且连mysql官方把它叫做“Role Like”(不是角色,长得比较像而已,额~~~)?

    好咧,那在5.7中怎么玩这个不像角色的角色呢?

    show variables like "%proxy%"
    

    你得先把check_proxy_users,mysql_native_password_proxy_users这两个变量设置成true才行。

    set GLOBAL check_proxy_users =1;
    
    set GLOBAL mysql_native_password_proxy_users = 1;
    
    

    当然,你也可以把这两个配置设置到my.cnf中。

    3.3.2. 创建一个角色

    create USER 'dev_role'
    

    可能被你发现了,我这里创建得是个user,为了稍微像角色一点点,我给这user取名叫dev_role,而且为了方便也没用使用密码了。

    3.3.3. 创建2个开发人员账号:

    create USER 'deer'
    
    create USER 'enjoy'
    
    

    这两个用户我也没设置密码。

    3.3.4. 把两个用户加到组里面

    grant proxy on 'dev_role' to  'deer'
    
    grant proxy on 'dev_role' to  'enjoy'
    
    

    可以看下其中一个用户的权限:


    这里有个小的地方需要注意:如果你是远程链接,你可能会收获一个大大的错误,你没有权限做这一步,这个时候你需要再服务器上执行一条。

     GRANT PROXY ON ''@'' TO 'root'@'%' WITH GRANT OPTION;
    

    3.3.5. 给角色dev_role应该有的权限

    有了用户了,这用户也归属到了dev_role这角色下面,那接下来要做的就很简单了,根据业务需求给这角色设置权限就好了。

    grant select(id,name) on mysqldemo.account to 'dev_role'
    

    3.3.6. 测试

    好咧,大功告成,现在使用'deer'用户登陆系统试试。

    select id ,name from mysqldemo.account
    

    学到了吧,涨到姿势了吧,你可能又会问,这种角色的权限是存哪的呢?

    给你看表:


    完美,收官!

    持续关注我,分享更多干货。

    相关文章

      网友评论

        本文标题:从删库到跑路:漫谈MySQL权限安全

        本文链接:https://www.haomeiwen.com/subject/yvcdcctx.html