【夸QT十一】外来物品:通用脚本帮助Web运行基础Linux命令
需求分析:
需要注意的是在这里第一次,这个人是不是QT系列文章,它是关于Web的,之所以写这篇文章。这是因为碍着Web相关开发时间,而且往往涉及linux与底层指令处理。例如,创建一个文件夹,删除一个文件夹,或者是运行一个自己定义的脚本。关于PHP怎样调用、运行Linux的底层命令。曾经也研究过,基本上实现了自己须要的功能,可是有些地方一直没有弄明确。今天又偶然碰到了,趁着这个机会向大家描写叙述一下一步一步应该怎样实现,并最后附上相关C代码。
原理实现:
首先,一般搭建的Web网站都是採用Apache或Nginx。因此当使用php运行linux的命令的时候。在linux端体现出的时Apache或Nginx用户的身份来运行的。通常情况下基于安全考虑。Apache或Nginx在linux端的默认用户是不具有非常高的权限的,比方删除、创建等。因此我们必须通过一种方式。为其赋予一定的权限。
在我曾经写过的文章中,我採用了一种方法,即将Apache或Nginx的默认用户改动了,给那个用户赋予了非常高的权限。尽管达到了我的目的,可是恰恰造成了最大的隐患,即:webserver默认用户权限设置过大,非常easy受到来自外界的攻击,甚至不用外界。我自己在php端运行一个命令能将我整个网站删除掉。而在linux端对此基本没有不论什么防御能力。基于此。我们提出一种方式。在linux端不改动webserver默认用户的权限,而是当运行命令时由我们来自己控制这条命令应当具有何种用户的运行权限。或者root用户,或者普通用户全然由我们传递的參数决定。
其次,基于上面的阐述,基本实现思路为:接受php传递来的username和passwd的參数,在linux端新建一个进程。然后将该进程模拟为一个用户的身份。即设置该进程的用户实际、有效的用户ID和用户组ID。然后再运行某条命令,此时运行该命令的过程就好像username用户本身运行那条命令一样。username能运行的有效命令仅仅能在自己的职权范围之内,比方:假设username是普通用户,则它无法通过运行命令删除其它用户或root用户的文件。
这样。在一定程度上实现了安全的可控性。
最后。依据上面提出的改变某个进程的实际、有效用户ID和用户组ID须要用到setuid()和setgid(),而关于这两个函数这里还有须要注意的地方。假设运行它的是特权用户。即root。则它能够随意设置自己的uid和gid。即能够模拟随意用户;而假设运行它的时普通用户,则它仅仅能设置自己的uid和gid,而不能设置为其他用户的,即无法模拟其他用户。为了解决问题就要用到linux的一些特性,即设置文件的用户标记位:s。使文件在运行时具有文件全部者的权限。这样,Apache或Nginx默认用户运行这个文件的时候就类似于该文件的全部者在运行它,而我们利用root用户创建该文件,就相当于root用户在运行该文件。此时setuid和setgid就能够将进程模拟为不论什么用户的身份了。
实现代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pwd.h>
#include <math.h>
#include <time.h> //Usage: exefile command work_directory username password
int main(int argc, char *argv[])
{
char *username = NULL;
char *password = NULL;
char *command = NULL;
char *workdir = NULL;
struct passwd *stpasswd = NULL; if(argc == 5)
{
command = argv[1];
workdir = argv[2]; //work directory
username = argv[3];
password = argv[4];
}
else
{
return 1;
} //printf("username = %s\n",username);
//printf("password = %s\n",password);
//printf("workdir = %s\n",workdir);
//printf("command = %s\n",command); int result = 0;//auth(username,password); //Ensure the user is a legel user in the system if(result == 0) //auth successfully
{ int kidstatus, deadpid; //! fork()克隆出一个全然同样的进程出来;它会复制当前进程的全部变量,就好像一个进程克隆出来还有一个一样
//! fork()函数的返回值有三种情况:=0代表克隆出来的那个进程 >0代表“父”进程 <0 运行出错
//! 这样的情况一般就是fork出来新的进程。【可选:进行身份切换】,然后利用它来运行execlp(),运行相关的命令
pid_t kidpid = fork(); if (kidpid == -1)
{
printf("fork error");
return 1;
} if (kidpid == 0)
{
//! getpwnam():获取用户登录相关的信息
//! 头文件:#include <pwd.h> #include <sys/types.h>
stpasswd = getpwnam(username); //! setgid():设置实际用户组ID和有效用户组ID
//! setuid():设置实际用户ID和有效用户ID
//! chdir() : 改动当前文件夹
//! 注意:假设是一个非特权用户,则它运行setgid和setuid仅仅能设置为自己的gid和uid。而不能设置其他不论什么数值
//! 假设是一个特权用户(即:拥有root权限)。则能够利用setgid和setuid设置为随意数值,这也就是为什么终于
//! 编译出来的文件要通过:chmod u+s 设置特权位
setgid( (int)(stpasswd->pw_gid)); //Set current usergroup
setuid( (int)(stpasswd->pw_uid)); //Set current user
chdir(workdir); //change work directory //! int execlp(const char *file, const char *arg, ..., (char *)0);
//! execlp()会从PATH环境变量所指的文件夹中查找符合參数file的文件名称,找到后便运行该文件,然后
//! 将第二个參数以后的參数当作该文件的argv[0], argv[1] ...,最后一个參数必须用空指针(NULL)结束
//! 以下的命令就是:/bin/bash -c command运行
int rv = execlp("/bin/bash", "/bin/bash", "-c", command, NULL); fflush(stdout); return rv;
} //! we only get here if we're the parent process.
//! waitpid()堵塞等待子进程结束
//! 函数原型:
deadpid = waitpid(kidpid, &kidstatus, 0); if (deadpid == -1)
{
printf("error to fork a process!");
return 1;
}
else
{
return 0;
}
}
else
{
printf("Authenticate failed\n");
return 1;
}
}
最后。利用gcc编译该文件:gcc test_exec.c -o test_exec;编译完毕后为它赋予权限:chmod 777 test_exec。然后设置用户标记位:s, chmod u+s test_exec
运行測试:
1. 利用root用户创建一个del_test文件。然后切换到普通用户。測试是否能删除;然后用我们的命令模拟root用户看是否能删除
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG91cWQyMDEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
2. 利用root用户创建一个del_test的文件。切换到zhangsan用户。利用命令模拟lisi用户,看可以删除
通过以上,我们能够看出,利用该命令我们能够模拟不论什么用户的身份。相当于不论什么权限都是由你自己控制,在一定程度上保证了安全性。
总结:
对似懂非懂的知识点一定要明确其原理,不然始终不知道应该怎样来做。
加油!这段时间的网盘开发没有涉及太多挑战性怪东西,预期UDT科研。
版权声明:本文博主原创文章,博客,未经同意不得转载。
【夸QT十一】外来物品:通用脚本帮助Web运行基础Linux命令的更多相关文章
- 万能脚本助Web执行底层Linux命令
需求分析: 这里先要说明的是,这一篇不是QT系列的文章,而是关于Web的,之所以要写这篇,是因为以前做Web相关开发的时候,经常涉及到与linux底层命令打交道,比如说创建一个目录,删除一个目录,或者 ...
- 吻逗死(windows)系统下自动部署脚本(for java spring*)及linux命令行工具
转载请注明出处:https://www.cnblogs.com/funnyzpc/p/10051647.html (^^)(^^)自動部署腳本原本在上個公司就在使用,由於近期同事需要手動部署一個Spr ...
- 一个shell脚本,让你的linux命令行酷炫起来
可调用如下函数达到echo出来带颜色的文字.._echo_error() { echo -ne "\033[31;1m $1\033[0m\n";}_echo_ok() { ech ...
- 《Linux命令行与shell脚本编程大全》第十一章 构建基本脚本
11.1使用多个命令 $date;who // 命令列表,加入分号就可以,这样会依次执行.参见5.2.1节 注意区分$(date;who),这个是进程列表,会生成一个子shell来执行 Shel ...
- Linux上java程序的jar包启动通用脚本(稳定用过)
Linux上java程序的jar包启动通用脚本如下: #! /bin/sh export LANG="zh_CN.GBK" SERVICE_NAME=` .sh` SCRIPT_N ...
- sql server编写通用脚本自动检查两个不同服务器的新旧数据库的表结构差异
问题:工作过程中,不管是什么项目,伴随着项目不断升级版本,对应的项目数据库业务版本也不断升级,数据库出现新增表.修改表.删除表.新增字段.修改字段.删除字段等变化,如果人工检查,数据库表和字段比较多的 ...
- sql server编写通用脚本自动统计各表数据量心得
工作过程中,如果一个数据库的表比较多,手工编写统计脚本就会比较繁琐,于是摸索出自动生成各表统计数据量脚本的通用方法,直接上代码: /* 脚本来源:https://www.cnblogs.com/zha ...
- Qt容器类之三:通用算法
在<QtAlgorithm>头文件中,Qt提供了一些全局的模板函数,这些函数是可以使用在容器上的十分常用的算法.我们可以在任何提供了STL风格迭代器的容器类上用这些算法,包括QList.Q ...
- Linux下shell通用脚本启动jar(微服务)
Linux下shell通用脚本启动jar(微服务) vim app_jar.sh #!/bin/bash #source /etc/profile # Auth:Liucx # Please chan ...
随机推荐
- 《c陷阱与缺陷》笔记--注意边界值
如果要自己实现一个获取绝对值的函数,应该都没有问题,我这边也自己写了一个: void myabs(int i){ if(i>=0){ printf("%d\n",i); }e ...
- 第二章排错的工具:调试器Windbg(下)
感谢博主 http://book.51cto.com/art/200711/59874.htm 2.2 读懂机器的语言:汇编,CPU执行指令的最小单元2.2.1 需要用汇编来排错的常见情况 汇编是 ...
- 简体中文 — ANSI Common Lisp 中文版
简体中文 - ANSI Common Lisp 中文版 简体中文¶
- JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定. 1 byte checksum CRC ...
- Ubuntu下安装MySQL 5.6.23
Ubuntu下安装MySQL 5.6.23 1.下载相应Linux-generic的源代码包.解压,将解压后的文件夹重命名为mysql.移动到/usr/local文件夹下: tar –xzf mysq ...
- Android程序的目录结构
本篇文章我们将介绍Android应用程序的目录结构.本目录下有如图的目录结构: 下面我们来一 一介绍: 1. Src:该目录中存放的是该项目的源代码 2. Gen:该目录下的文件全部都 ...
- 开启程序的Visual Styles
首先看看MS对Visual Styles的解释: Windows XP and later operating systems support a feature called visual styl ...
- 44个JAVA代码质量管理工具(转)
1. CodePro AnalytixIt’s a great tool (Eclipse plugin) for improving software quality. It has the nex ...
- Palindrome Numbers(LA2889)第n个回文数是?
J - Palindrome Numbers Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu ...
- zoj3640(概率dp)
题目连接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4808 题意: 一个吸血鬼,每次可以随机的选择n个洞中的任意一个,如果 ...