phpMyAdmin权限控制 root用户也没辙

HH MySQL1 11,1173字数 2281阅读7分36秒阅读模式

前言

由于公司有些项目在使用阿里的RDS,RDS的一个弊端就是权限管控粒度太大,也不能创建用户。也和阿里那边沟通过有关权限细粒度化是遥遥无期了。那我们也需要将权限管控起来,开发人员只能使用SELECT语句,减少误操作几率。

权限管控思路

1、创建用户最有效(由于阿里原来无法实践)。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

2、自己部署phpMyadmin(不能创建用户,也没辙)。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

3、自己开发一个小工具只能使用SELECT(可行,耗费精力,而且界面不一定好看)。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

4、修改phpMyadmin源码,过滤执行语句只让SELECT执行(可行,较方便)。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

下面我们就按 "思路4" 来实践RDS上的mysql权限管控。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

软件介绍

软件 版本 备注
php 5.6
nginx 1.6.0 作web服务器
phpMyAdmin 4.5.3.1-all-languages

这边我就不介绍要如何搭建一个 LNMP 的环境了。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

已经做了修改的phpMyAdmin下载地址:https://yunpan.cn/crujxsTwcFe8C 访问密码 496c文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

修改思路

1、对执行的SQL进行过滤。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

2、只显示需要的菜单栏。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

对执行的SQL进行过滤文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

php文件路径:phpMyAdmin/libraries/parse_analyze.inc.php文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

第12行左右能看到代码文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

$GLOBALS['unparsed_sql'] = $sql_query;

其中$sql_query就是phpMyAdmin需要执行SQL的语句,我们只需要对$sql_query进行过滤,当出现DELETE、DROP等关键字的语句过滤就行。文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

在 $GLOBALS['unparsed_sql'] = $sql_query; 代码的上方加入过滤代码文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

/**
  Author: chenhao
  Date  : 2016-01-20
*/
// 定义敏感关键字如:DELETE, DROP
$filter_key_word_arr = array(
  'FLUSH', 'GRANT', 'SET', 'ANALYZE', 'BACKUP', 'OPTIMIZE', 'REPAIR',
  'RESTORE', 'ALTER', 'CREATE', 'DROP', 'RENAME', 'TRUNCATE', 'DELETE',
  'DO', 'HANDLER', 'INSERT', 'REPLACE', 'UPDATE', 'DEALLOCATE', 
  'EXECUTE', 'PREPARE'
);
// 将执行的SQL语句转化为大写
$sql_query = strtoupper($sql_query);
// 按,和空白分割SQL语句获得词的数组
$sql_query_key_arr = preg_split("/[\s,]+/", $sql_query);
// 比较如果SQL语句中含有自定义的关键字就修改变量$sql_query为不可执行的字符串
$intersect_arr = array_intersect($filter_key_word_arr, $sql_query_key_arr);
if(!empty($intersect_arr)) {
  $sql_query = 'Cannot allow ' . current($intersect_arr);
}

运行了敏感词报错效果:文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

Phpmyadmin

phpMyAdmin权限控制 - 01

只显示需要的菜单栏文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

php文件路径:phpMyAdmin/libraries/Menu.class.php文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

找到方法:_getTableTabs、_getDbTabs、_getServerTabs这三个方法中有类似以下的代码文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

// 展示表结构的menu
$tabs['structure']['link']
$tabs['structure']['text']
$tabs['structure']['icon']
// 展示查询SQL的menu
$tabs['sql']['link']
$tabs['sql']['text']
$tabs['sql']['icon']
// 导出操作的menu
$tabs['export']['text']
$tabs['export']['icon']
$tabs['export']['link']
// 表操作的menu
// $tabs['operation']['link']
// $tabs['operation']['text']
// $tabs['operation']['icon']
......

只需要将你不需要的menu相关变量给注释掉就好了文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

效果展示:文章源自运维生存时间-https://www.ttlsa.com/mysql/phpmyadmin-access-control/

隐藏前的菜单栏

Phpmyadmin

phpMyAdmin权限控制 - 02

隐藏后的菜单栏

Phpmyadmin

phpMyAdmin权限控制 - 03

以上就完成了使用phpMyAdmin只能使用 SELECT 语句的功能,当然可能还有很多bug。希望有兴趣的深入研究一下。

结束语

其实我们能那么方便的修改phpMyAdmin需要感谢phpMyAdmin的开发人员,如果不是他们代码写的好,我们不可能只修改一个地方就能做到控制权限的目的。这里向phpMyAdmin开发者致敬! ^_^

 作者信息

昵称:HH

QQ:275258836

感觉本文内容不错,读后有收获?

逛逛衣服店,鼓励作者写出更好文章。

weinxin
我的微信
微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
HH
  • 本文由 发表于 03/02/2016 01:00:08
  • 转载请务必保留本文链接:https://www.ttlsa.com/mysql/phpmyadmin-access-control/
评论  1  访客  1
    • chen_hao
      chen_hao

      找到 phpMyAdmin/import.php 第105行 也需要加上如下信息
      在代码如下代码下面加入
      $ajax_reload = array();
      // Are we just executing plain query or sql file?
      // (eg. non import, but query box/window run)
      if (! empty($sql_query)) {
      ———————————————————————
      以下是加入的代码
      ———————————————————————
      $filter_key_word_arr = array(
      ‘FLUSH’, ‘GRANT’, ‘SET’, ‘ANALYZE’, ‘BACKUP’, ‘OPTIMIZE’, ‘REPAIR’,
      ‘RESTORE’, ‘ALTER’, ‘CREATE’, ‘DROP’, ‘RENAME’, ‘TRUNCATE’, ‘DELETE’,
      ‘DO’, ‘HANDLER’, ‘INSERT’, ‘REPLACE’, ‘UPDATE’, ‘DEALLOCATE’,
      ‘EXECUTE’, ‘PREPARE’
      );
      // 将执行的SQL语句转化为大写
      $sql_query = strtoupper($sql_query);
      // 按,和空白分割SQL语句获得词的数组
      $sql_query_key_arr = preg_split(“/[s,]+/”, $sql_query);
      // 比较如果SQL语句中含有自定义的关键字就修改变量$sql_query为不可执行的字符串
      $intersect_arr = array_intersect($filter_key_word_arr, $sql_query_key_arr);
      if(!empty($intersect_arr)) {
      $sql_query = ‘Cannot allow ‘ . current($intersect_arr);
      }

    评论已关闭!