需求
最近我司后台部门太忙了,以至于运营同学和测试同学都需要自学SQL自行查询数据库。
我们的大数据数据是用impala来查询的,Cloudera的Hue是一个专门用来分析Hadoop数据的Web UI。界面是这样的:
想开放这个页面供运营和测试同学去自行查询数据库,但很不幸的,后台同学和大数据同学也发现了,Hue并没有提供只能执行Select的精细的SQL权限控制,要是遇上个删库跑路的家伙就坑爹了。于是我看下有没有什么解决方式。
正确的做法
当然是从Hive和Impala上做好权限控制,目前Hadoop生态圈主流的两个集中式权限系统是sentry和ranger,但是我们没有应用过,短时间内比较难搞。于是我先想用比较dirty的方法来实现。
前端
直接修改html页面。通过查看html源码,找到了这个文件:(我们的版本,目录是/opt/cloudera/parcels/CDH-5.7.1-1.cdh5.7.1.p0.11/lib/hue
)
apps/beeswax/src/beeswax/templates/execute.mako
想法是找到输入SQL的textarea,然后在"执行"按钮点击时,检查textarea里面的字符串,然后判断是否匹配到某些危险关键字。不过比较坑爹的是,这个textarea在运行时加载了codemirror的插件生成的,好难定位,加之在前端也不如在后端做限制安全,于是放弃了。
后端
Hue是用Django写的。很好。打开Chrome开发者工具,故意输错SQL,让页面报错:
看到了一个关键的uri:
用query/execute
为关键字搜索源码,找到了apps/beeswax/src/beeswax/urls.py
里配置的路由:
url(r'^api/query/execute/(?P<design_id>\d+)?$', 'execute', name='api_execute'),
然后用关键字def execute(*request*
再找到这个文件:
apps/beeswax/src/beeswax/api.py
找到这个文件里的execute
函数,中间有这么一段:
if query_form.is_valid():
query_str = query_form.query.cleaned_data["query"]
很明显,这里的query_str
就是将我们POST过去的SQL语句处理了之后的字符串,我们在这里动下手脚:
if re.search(r'\binsert\b|\bdelete\b|\balter\b|\bdrop\b|\bupdate\b|\breplace\b|\bcreate\b|\btruncate\b|\boverwrite\b', query_str, re.I):
response['message'] = _('SQL_not_allowed.')
return JsonResponse(response)
然后重启了Hue。
效果
没有过滤的SQL语句是可以执行的:
备注
- 正常的Hue执行SQL的过程是:
impala/api/query/parameters
处理提交的参数,然后/impala/api/query/execute
提交后台任务,生成一个带有jobid的watch_url,接着执行SQL,将查询结果保存到csv文件,同时有个impala/api/watch/json/${jobid}
在异步查询结果并展示页面。 - 这实现方法太dirty了,还给自己挖了个坑,万一CDH更新了而这个文件没有及时修改的话。。。