Home  >  Article  >  php教程  >  To use php to execute a shell script with root privileges, you must perform the following steps:

To use php to execute a shell script with root privileges, you must perform the following steps:

WBOY
WBOYOriginal
2016-07-09 09:10:001540browse

The things I have been working on these days involve the interaction between PHP and Linux using shell scripts. We know that using PHP to run scripts to access Linux is executed as Apach, so it can do very little on its own. Because there are not enough permissions, this involves granting root permissions when php is executed.

The method introduced next is something I have personally done and can be implemented. However, it has its shortcomings. I would like to share them with you here. I hope you can give me some good tips:

This uses C to realize the exchange of permissions. If you want to fully understand why the next program can run successfully, please fully understand the role of SUID and SGID.

[plain] view plaincopy
  1. #include
  2. #include
  3. #include
  4. #include
  5. int main()
  6. {
  7. uid_t uid , euid ;
  8. uid = getuid();
  9. euid= geteuid();
  10. // printf("my uid:%un",getuid());
  11. // printf("my euid:%un",geteuid());
  12. if(setreuid(euid,uid))
  13. perror("setreuid");
  14. // printf("after setreuid uid:%un",getuid());
  15. // printf("after setreuid euid:%un",geteuid());
  16. system("/home/houqingdong/myshell/mkdir.sh /home/ hou_test");
  17. return 0;
  18. }

The main function description:

1. The header files required by getuid() are:
#include
#include
Function prototype: uid_t getuid(void);
Function description: uid_t It is defined in sys/types.h. It is actually an unsigned int type. The function returns a true value of the calling program

The ID of the real user.
2. geteuid()
Function prototype: uid_t geteuid(void);
Function description: geteuid() is used to obtain the valid user identification code for executing the current process. Valid user ID used to determine process execution

permissions, by which the process can obtain additional permissions by changing this value. If the setID bit of the executable file has been set, when the file is executed,

The euid value of its process will be set to the uid of the owner of the file. For example, the permissions for executing the file /usr/bin/myshell.sh are: -r-s-

-x--x, its s bit is the setID (SUID) bit, and when any user executes myshell.sh, his effective user identification code will be set to

The uid of the owner of myshell.sh, that is, the uid value of root is 0.

3. setreuid(); can be understood as exchanging ID

Compile this file: gcc -o run -Wall run.c Generate executable file run

The next step is to give suid permissions to run: chmod u s run Its function is to set uid. When executed by ordinary users, it is executed with root permissions. In run.c The ID of the process will be exchanged, so that the ID of root is 0 for execution, and the permissions can be imagined.

But there is a very bad thing about using this method. In run.c, the command I executed is: system("/home/houqingdong/myshell/mkdir.sh /home/ hou_test"); mkdir.sh It is a script written by myself, and the last two parameters are hard-coded, which means that it is very inconvenient to pass parameters. Of course, if you execute some programs that do not need to pass parameters, this method is still very feasible, and I think What it does is that the user selects a directory under Linux and can create a file or directory in it. The parameters at this time are very difficult to handle.

Also tried another approach regarding this issue:

Just execute the shell script you wrote directly: chmod 777 mkdir.sh chmod u s mkdir.sh

In this way, when I call mkdir.sh, I also execute it as root, but when I run it on the web page, I still get an error. It is initially determined that Apache does not have enough permissions in the directory where I want to create the file. I Try changing the permissions to: chmod -R 777 /home/ Then you can create it successfully after running it, but this method of adding permissions to Apache is very informal. I know how to add the home directory and virtual directory to Apache. Permissions

But I don’t know about this, I can’t just change the permissions.

I know that there are definitely many shortcomings in my above method, whether it is from feasibility or safety, so if you happen to see this article and know a better way, I hope you can spend some money I would be grateful if you could give me a reminder when you have time, thank you! !

Using PHP to execute shell scripts with root permissions must carry out the following steps: (All steps are my own experiments. If there is anything wrong, please point out, thank you!)

1. Determine who is the execution user of your Apache. Note: It does not necessarily mean nobody. I installed httpd by myself, and my Apache user is daemon

2. Use visudo to grant root execution permissions to your Apache execution user, and of course set no password. Note: For security reasons, it is best to create a new user here and let him serve as the execution user of Apache (Modify the httpd.conf file, I will point out later)

3. This step is easy. Write your script and use PHP's exec, system... functions to execute it.

The following is the detailed implementation process:

1. Check who is the execution user of your Apache: lsof -i:80 The result after running is:

We can clearly see from the picture that the execution user of httpd (that is, Apache) is: exec_shell (Note: This is the user after changing it on my local machine. It is just for illustration. Yours is definitely not this one. ! )

lsof is the abbreviation of List of file, which is a tool for listing open files in the current system. For its specific usage, please refer to: http://club.topsage.com/thread-234763-1-1.html said It’s pretty good

After determining who is the executor of Apache on your Linux, for the sake of safety, create a new user and change the execution user of Apache to our newly created user.

2. Create a new execution user for Apache

useradd your_exec_user We know that when creating a user, a user group with the same user name will be created by default, which means that now we also have a user group for your_exec_user

Next we modify the Apache configuration file so that its execution user is changed to the user we just created, your_exec_user:

vi /home/houqingdong/httpd-exe/config/httpd.conf (this is the directory location where your Apache is located)

Find the place below and modify it to your new user: your_exec_user

 

Restart Apache: /home/houqingdong/httpd-exe/bin/apachect1 restart -------------> After restarting, you can use: lsof -i:80 to check.

3. Execute visudo (or vi /etc/sudoers), grant root permissions to your_exec_user, and no password is required. There is also an important modification (this is what bothers me)

visudo Find this place, add your_exec_user, and set no password

 

When I finished here, I went to execute the php script, but the creation was always unsuccessful. What’s more, I was very depressed because I switched to the user your_exec_user and executed it directly, and the execution was successful.

Later, I checked the Apache log file and found:

It is obvious here that when executing sudo, there must be a tty to run sudo. If you know where the problem lies, the problem can be solved: vi /etc/sudoers Comment out the following sentence:

This is because by default, executing sudo requires a terminal, just comment it out here. Next, write your shell script and php commands

4. Here is a very simple script I wrote, which uses the $directory and $name passed from the php side to create a directory of $name in the directory

[plain] view plaincopy
  1. #!/bin/bash
  2. #Program
  3. # This program will execute mkdir: cd $directory ; mkdir $name
  4. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  5. export PATH
  6. cd $1
  7. if [ ! -d $2 ]; then
  8. mkdir $2
  9. else
  10. echo "Already exist..."
  11. exit 1
  12. fi


The function is very simple, that is, enter $directory to determine whether the directory name to be created exists, and then create the directory.

Constructed php execution function: (part)

[php] view plaincopy
  1. if($type=="dir"){  
  2.           $make_dir_command="/usr/bin/sudo /home/houqingdong/myshell/mkdir.sh /$directory/ $name" ;  
  3.           echo $make_dir_command;  
  4.           exec($make_dir_command,$output,$return);  
  5.   
  6.               if($return == 0){  
  7.                   echo "";  
  8.               }else{  
  9.                   echo "";  
  10.               }  

这里顺带提一句:

构造的命令里面最好都使用绝对路径

5. 在网页端的执行结果:

    

提交之后,要过几秒中才会弹出执行结果的提示信息:

     执行成功,在我们的/home/目录下:

哈哈。。。大功告成!(谢谢存哥的帮助指点!)
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn