【夸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 ...
随机推荐
- 利用SQL语句实现分页
1.概述 在网页中如果显示的数据太多就会占据过多的页面,而且显示速度也会很慢.为了控制每次在页面上显示数据的数量,就可以利用分页来显示数据. 2.技术要点 在SQL Server中要实现SQL分页,需 ...
- Delphi面向对象设计的经验原则(61条)
(1)所有数据都应该隐藏在所在的类的内部. (2)类的使用者必须依赖类的共有接口,但类不能依赖它的使用者. (3)尽量减少类的协议中的消息. (4)实现所有类都理解的最基本公有接口[例如,拷贝操作(深 ...
- Kali Linux 装好系统后安装经常使用软件
1.配置软件源 leafpad /etc/apt/source.list or(recommand): #官方源 deb http://http.kali.org/kali kali main no ...
- [Android学习笔记]SeekBar的使用
一.SeekBar滑动条的使用 xml声明: <SeekBar android:id="@+id/seekbar" android:layout_width="20 ...
- What is tradebit?
The Tradebit Fact Sheet What is tradebit?
- Tiny server:小型Web服务器
一.背景 csapp的网络编程粗略的介绍了关于网络编程的一些知识,在最后的一节主要就实现了一个小型的Webserver.这个server名叫Tiny,它是一个小型的可是功能齐全的Webserver.在 ...
- TI推出SimpleLink低能耗蓝牙CC2541
TI推出SimpleLink低能耗蓝牙CC2541 日前,德州仪器 (TI) 宣布推出 SimpleLink™ 低能耗蓝牙 (Bluetooth®Low Energy) CC2541-Q1, 这是一款 ...
- 使用U盘进行Linux系统的安装
由于目前很多服务器已经本身不配光驱了,最近测试了下使用U盘进行Linux系统的安装,过程比较简单,需要注意的地方如下: 1.找一台linux主机,插入U盘,执行fdisk -l,识别到U盘. 2.将需 ...
- Thrift反序列化导致OOM(转)
概述 最近线上的日志处理服务偶尔会出现Out Of Memory的问题,从Exception的call stack中顺藤摸瓜,最终定位到是thrift反序列化的问题. 发现问题 先交代一下问题现场: ...
- Wix打包系列(五) 部署数据库
原文:Wix打包系列(五) 部署数据库 很多人在使用vs进行打包的时候,经常会为数据库部署的问题犯愁,即便是重写Installer类的方法,也不是很可靠方便,下面我们来看看在wix中如何部署数据库. ...