how to do a linux reboot from php file
Asked Answered
D

7

7

I have a user brftv on my linux system and I have www-data that runs the nginx.

from the terminal I can let my brftv user run

sudo /sbin/reboot

and it works fine since I added the following to my /etc/sudoers file's "#user privilege specification" section:

brftv ALL=NOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroff
www-data ALL=NOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroff

But when my php file runs the following code, nothing happens

exec('nohup sudo -u brftv /sbin/reboot');

I added the www-data line to the etc/sudoers above in case it was necessary when running the above exec() (even though I run it as -u brftv, but I'm no linux expert, just thought better be safe just in case).

The php file that runs this exec() is owned by www-data, and chmod is 777, all should thus have privilege to execute from it.

I have tried running the php-file both through browser (would be run by user www-data I assume) and from terminal $ php myFile.php.

------------------- UPDATE -----------------

I did this

sudo chmod u s /sbin/reboot

Which allows all users on my system to run the reboot cmd without password. It works, but I rather not leave it THAT open, so the other solution with /etc/sudoers would be better, if someone would have a hint at what my problem is...

I followed this tut http://linux.byexamples.com/archives/315/how-to-shutdown-and-reboot-without-sudo-password/ and the second example is pretty much what I got above that didn't work for me..

Drupe answered 7/6, 2014 at 17:53 Comment(1)
Try executing 'whoami' from the PHP script through your web server to verify the user it runs as.Improvisator
D
2

The only way I got this to work on my system was to "hack" it by changing chmod on /sbin/reboot like this guy did

http://linux.byexamples.com/archives/315/how-to-shutdown-and-reboot-without-sudo-password/

sudo chmod u+s /sbin/reboot

I realize this might not be optimal in many cases, but this mediaPlayer is very much locked down so there is no accessing a terminal for anyone else anyways.

Drupe answered 11/6, 2014 at 10:37 Comment(0)
P
14

I would use a very small C program to grant access to only the PHP group (probably www-data in your case?), use the suid bit on the executable, and exec the reboot command

phpreboot.c :

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
   setuid(0); // for uid to be 0, root
   char *command = "/sbin/reboot";
   execl(command, command, NULL);
   return 0; // just to avoid the warning (since never returns)
}

Compile it

gcc -Wall phpreboot.c -o phpreboot

Move phpreboot where you want to run it (has to be accessible by PHP!)

mv phpreboot /home/private/

As root (or via sudo) ensure owner is root and group is set to www-data, and change rights to have suid bit (in this order)

chown root:www-data phpreboot
chmod 4750 phpreboot

The result, ls -l phpreboot should be something like (note the s in rws)

-rwsr-x--- 1 root www-data 8565 Jun 12 11:42 phpreboot*

Change the PHP script to execute phpreboot instead

exec ("/home/private/phpreboot"); // change the path!

Only one tiny executable will have the suid to run the reboot program, and only the PHP group will be able to execute it (and root of course).

Personalty answered 12/6, 2014 at 9:57 Comment(2)
Why a C program instead of a shell script? The reason I'm asking is because I'm trying to do something similar with a bash shell script, the sticky bit, owner & group set exactly as you have described but when I do a whoami in the script, the result is www-data and not root. Consequently, my script doesn't work as expected because I can't get it to run as root. And why do you need to setuid(0) if the program is supposed to be running as root anyway? Thanks in advance for any light you can shed on this. I'm running Ubuntu 14.04.Powys
Ok, so I found the reason why the SetUID bit is ignored for shell scripts here.Powys
M
4

Giving reboot permission to www user is a bad idea.Create a cron and do system reboot from the cron rather than from PHP script. The Cron will run every minute and check for reboot flag. If it is set the it will do the reboot.

1)write a flag to a file from your php program so that the cron can decide whether to do reboot or not.

 $Handle = fopen("/tmp/myfile", 'w');
 fwrite($Handle, "doreboot");
 fclose($Handle);

2) Create a bash script to read that file and do reboot if the PHP script tells it to do so.

#!/bin/bash
arg=$(head -n 1 /tmp/myfile)   
if [ "$arg" == "doreboot" ]; then
  >/tmp/myfile
  echo "Rebooting"
  echo 'password' | sudo -S reboot
fi

execute this in shell chmod +x mycron.sh

3) Configure the script in crontab

crontab -e and paste this

* * * * * path/mycron.sh

4) The user who set the cron should have sudo permission. Add him to sudoers.

Marashio answered 11/6, 2014 at 14:13 Comment(0)
D
2

The only way I got this to work on my system was to "hack" it by changing chmod on /sbin/reboot like this guy did

http://linux.byexamples.com/archives/315/how-to-shutdown-and-reboot-without-sudo-password/

sudo chmod u+s /sbin/reboot

I realize this might not be optimal in many cases, but this mediaPlayer is very much locked down so there is no accessing a terminal for anyone else anyways.

Drupe answered 11/6, 2014 at 10:37 Comment(0)
L
1

Allow Reboots From PHP:

  1. vim /etc/sudoers
  2. List item paste new line "%www-data ALL=NOPASSWD: /sbin/reboot" and write changes.
  3. Reboot OS.
  4. Make sure your script is owned by www-data, chown www-data:www-data filename.php (apache user)
  5. Run script

Enjoy :)

(tested on ubuntu server 14.40 LTS with php5-7, should also work on any debian based distro.)

Lashaunda answered 1/2, 2017 at 11:6 Comment(0)
F
0

Why did you put -u brftv in there? That makes your PHP script try to run the reboot as your user, which won't work. Only root can reboot the system. Remove it.

Fluoroscope answered 7/6, 2014 at 18:28 Comment(5)
Ok, are you saying my addition to /etc/sudoers has no effect? And - if I remove it, how can I know it will be run as root, won't it be run as www-data in that case?Drupe
No, I'm saying that -u brftv doesn't belong in the command. Remove that.Fluoroscope
Ok, I removed it, and then I get presented with a password prompt. Clearly not a solution since this is supposed to run from a php-script, automated. Did I miss something in my /etc/sudoers or does your answer actually not work?Drupe
@duskwuff's answer is correct. By specifying -u brftv you are telling sudo to use the permissions of brftv which will never work. Removing it (exec('nohup sudo /sbin/reboot');) tells sudo to run with root privileges (but still "be" whichever user), with whatever extra privileges are specified in /etc/sudoers for the user that is running the command. What you're missing is a space between ALL= and NOPASSWD:.Derogate
Makes no difference, still not working, error: "must be root".Drupe
R
0

try this code exec('sudo shutdown -r now');

or "shutdown -r +5" shutdown after 5 minutes

Retired answered 16/6, 2014 at 16:6 Comment(1)
And what about the password required for sudo?Taite
A
-1

Try this code

brftv ALL=NOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroff
 www-data ALL=(brftv) NOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroff 

then from php

exec('sudo /sbin/reboot');
Adduction answered 12/6, 2014 at 9:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.