OpenWrt系统安全改进<五> --- Web 访问权限分级
来源:互联网 发布:淘宝护肤品店铺排行 编辑:程序博客网 时间:2024/06/05 02:14
摘要
OpenWrt系统安全改进<四>中介绍的只是在UI层面对用户进行访问控制,对于深层次非法操作并不能起到保护效果。本节介绍针对不同的用户登录请求,使用不同用户启动luci进程,从而实现不同用户进行操作级别的访问控制。
机制分析
web页面操作涉及到uhttpd和luci两个模块,uhttpd处理http报文,将cgi请求转给luci处理。从代码实现就可以看出这两个模块目前只是针对单用户:
1 uhttpd在初始化时,由root用户启动,在调用cgi请求时,使用execl调用luci
2 luci的cache内容只保留一份。
在本实践中,创建admin(归为root用户组)和user两个用户,当uhttpd接收到登陆请求包,判断用户是否发生变化,如果是就清除luci的cache(否则luci会执行出错),使用su启动luci进程。
准备工作
创建用户和用户组,相关的脚本(可执行文件)针对不同用户组分配不同的权限。
(注意:busybox中的ash和sh需要能够被所有用户可以执行,我采用了两份busybox,ash/sh link到所有用户可执行的busybox,其他link到只有同组用户可执行的busybox)
使能busybox的su
使能web ui的多用户登陆
具体操作可以参见OpenWrt系统安全改进<一>
实现不同用户身份执行luci
- --- a/uhttpd.c
- +++ b/uhttpd.c
- @@ -243,6 +243,64 @@
- return bound;
- }
- +#ifndef MULTI_USER
- +extern void MU_dbg(char *info);
- +void MU_dbg(char *info)
- +{
- + #if 0
- + int fd = open("/debug",O_RDWR|O_APPEND);
- + char buf[128] = {0};
- + int len = strlen(info);
- +
- + if (fd<0) {
- + fd = open("/debug",O_CREAT|O_RDWR);
- + }
- +
- + memcpy(buf,info,len);
- + buf[len] = '\n';
- +
- + write(fd,buf,len+1);
- + close(fd);
- + #endif
- +}
- +
- +static char CUR_USER[32] = {0};
- +
- +extern void get_cur_user(char *user);
- +void get_cur_user(char *user) {
- + if ( strlen(CUR_USER)==0 ) {
- + MU_dbg("CUR_USER empty");
- + strcpy(user,"admin");
- + } else {
- + memcpy(user,CUR_USER,strlen(CUR_USER));
- + }
- +}
- +
- +static void MU_get_user(conststruct client *cl, char *user) {
- + char *usrhead = cl->httpbuf.ptr;
- + char *pwdhead = strfind(usrhead,strlen(usrhead),"&password=",strlen("&password="));
- +
- + usrhead += strlen("username=");
- + memcpy( user, usrhead, pwdhead-usrhead );
- +
- + MU_dbg(user);
- +}
- +
- +static void MU_clear_luci_cache() {
- + int ret = 0;
- +
- + ret = system("echo clear cache > /tmp/luci_action");
- + ret = system("rm -Rf /tmp/luci-*");
- + if ( ret == -1 ) {
- + system("echo fail >> /debug");
- + } else if ( ret==0 ) {
- + system("echo ignore >> /debug");
- + } else {
- + system("echo finish >> /debug");
- + }
- +}
- +#endif
- +
- static struct http_request * uh_http_header_parse(struct client *cl,
- char *buffer, int buflen)
- {
- @@ -281,7 +339,21 @@
- if (method && !strcmp(method,"GET"))
- req->method = UH_HTTP_MSG_GET;
- else if (method && !strcmp(method, "POST"))
- - req->method = UH_HTTP_MSG_POST;
- + #ifndef MULTI_USER
- + {
- + char user[32] = {0};
- +
- + MU_get_user(cl,user);
- + if( strncmp(user,CUR_USER,4)!=0 ) {
- + MU_clear_luci_cache();
- + }
- + memcpy(CUR_USER,user,32);
- +
- + req->method = UH_HTTP_MSG_POST;
- + }
- + #else
- + req->method = UH_HTTP_MSG_POST;
- + #endif
- else if (method && !strcmp(method,"HEAD"))
- req->method = UH_HTTP_MSG_HEAD;
- else
- --- a/uhttpd-cgi.c
- +++ b/uhttpd-cgi.c
- @@ -486,12 +486,32 @@
- if (chdir(pi->root))
- perror("chdir()");
- + #ifndef MULTI_USER
- + {
- + extern void get_cur_user(char *user);
- + extern void MU_dbg(char *info);
- +
- + char user[32] = {0};
- + char info[32] = {0};
- +
- + get_cur_user(user);
- +
- + sprintf(info,"exec via %s",user);
- + MU_dbg(info);
- +
- + if (ip!=NULL) {
- + execl("/bin/su","su",user,"-c",ip->path,pi->phys,NULL);
- + } else {
- + execl("/bin/su","su",user,"-c",pi->phys,NULL);
- + }
- + }
- + #else
- if (ip != NULL)
- - execl(ip->path, ip->path, pi->phys, NULL);
- - else
- + execl(ip->path, ip->path, pi->phys, NULL);
- + else
- execl(pi->phys, pi->phys, NULL);
- -
- - /* in case it fails ... */
- + #endif
- + /* in case it fails ... */
- printf("Status: 500 Internal Server Error\r\n\r\n"
- "Unable to launch the requested CGI program:\n"
- " %s: %s\n", ip ? ip->path : pi->phys, strerror(errno));
实现admin执行UCI修改
完成上步操作后,使用不同用户登录可以根据用户执行LuCI,但是admin和user都只能查询UCI相关的一些配置,而我期望的admin能够修改配置。
经过一些尝试,发现仅仅为admin赋予uci的执行权限和相关配置文件的写权限扔不能执行UCI修改操作(uci set/commit)。
我希望修改的配置是通过UCI Map来进行修改的,修改usr/lib/lua/luci/cbi.lua文件的Map.set和Map.parse,使用su权限来执行uci set 和 commit。
后续工作
目前实现虽然支持了多用户的操作权限控制,但是对于用户切换时访问效率低,后续可以修改luci,针对每个用户创建一份cache。
- OpenWrt系统安全改进<五> --- Web 访问权限分级
- OpenWrt系统安全改进<五> --- Web 访问权限分级
- OpenWrt系统安全改进<四> --- Web UI权限分级
- OpenWrt系统安全改进<四> --- Web UI权限分级
- OpenWrt系统安全改进<一>
- OpenWrt系统安全改进<三> --- Web UI密码错误控制
- OpenWrt系统安全改进<二> --- 使能PAM
- WEB-INF访问权限
- 分级marker改进 改变分级图标
- Android系统安全与权限
- 系统安全高频访问控制程序
- openwrt 问题五 怎样用域名访问路由器网页
- Web 应用程序的访问权限
- web.config 设置访问权限
- WEB-INF 访问权限说明
- Web系统安全Tips
- 关于web系统安全
- yii 权限分级式访问控制的实现(非RBAC法)
- 第十二周项目一2
- 面试集锦
- 第十三周项目三 立体族类的纯虚函数
- WKWebView 在64位设备上的白屏问题
- 第十四周程序阅读——例六
- OpenWrt系统安全改进<五> --- Web 访问权限分级
- 第14程序阅读 例6.2
- #笔记#圣思园 JavaSE 第66讲——静态 、 动态 代理模式
- c/C++内存分配
- 不安装Oracle客户端,使用PLSQL连接Oracle服务器
- android Graphics:区域(Region)
- many-tp-one
- Javascript:谈谈JS的全局变量跟局部变量(转zyz511919766)
- 数据结构系列之循环队列