Ok I need to run my Apache web server as root. For this I typed whoami; in terminal. It gives me output: root. But when I check my apache server running as a root user or not by executing following php-script: < ?php echo whoami; ?> It gives me output: nobody. So any suggestions to execute/login as a root user in apache??
I would suggest creating an external PHP file on your server that would handle everything related with this extension. And then, you could call this script with shell_exec in combination with sudo.
This way, you could put your webserver user in your sudoers file and let it run php-cli as root.
Then, in your script you could simply use:
$output = shell_exec("sudo /bin/php /yourscript.php");
This would be a much more secure solution than running Apache as root, which in my opinion, is a verry bad idea, even if you know what you are doing.
If you know what you are doing, look at the file /etc/apache2/envvars :
You can customize these variables
export APACHE_RUN_USER=root
export APACHE_RUN_GROUP=root
I echo the concerns running the apache process as root. Its just a bad idea.
Thats why I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('php /var/scripts/test.php');
//the return will be a string containing the return of the script
echo $return1;
Related
I'm trying to run a Python script from PHP using the following command:
exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
However, PHP simply doesn't produce any output. Error reporting is set to E_ALL and display_errors is on.
Here's what I've tried:
I used python2, /usr/bin/python2 and python2.7 instead of /usr/bin/python2.7
I also used a relative path instead of an absolute path which didn't change anything either.
I tried using the commands exec, shell_exec, system.
However, if I run
if (exec('echo TEST') == 'TEST')
{
echo 'exec works!';
}
it works perfectly fine while shutdown now doesn't do anything.
PHP has the permissions to access and execute the file.
EDIT: Thanks to Alejandro, I was able to fix the problem. If you have the same problem, don't forget that your webserver probably/hopefully doesn't run as root. Try logging in as your webserver's user or a user with similar permissions and try to run the commands yourself.
Tested on Ubuntu Server 10.04. I hope it helps you also on Arch Linux.
In PHP use shell_exec function:
Execute command via shell and return the complete output as a string.
It returns the output from the executed command or NULL if an error
occurred or the command produces no output.
<?php
$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;
?>
Into Python file test.py, verify this text in first line: (see shebang explain):
#!/usr/bin/env python
If you have several versions of Python installed, /usr/bin/env will
ensure the interpreter used is the first one on your environment's
$PATH. The alternative would be to hardcode something like
#!/usr/bin/python; that's ok, but less flexible.
In Unix, an executable file that's meant to be interpreted can indicate
what interpreter to use by having a #! at the start of the first line,
followed by the interpreter (and any flags it may need).
If you're talking about other platforms, of course, this rule does not
apply (but that "shebang line" does no harm, and will help if you ever
copy that script to a platform with a Unix base, such as Linux,
Mac, etc).
This applies when you run it in Unix by making it executable
(chmod +x myscript.py) and then running it directly: ./myscript.py,
rather than just python myscript.py
To make executable a file on unix-type platforms:
chmod +x myscript.py
Also Python file must have correct privileges (execution for user www-data / apache if PHP script runs in browser or curl)
and/or must be "executable". Also all commands into .py file must have correct privileges.
Taken from php manual:
Just a quick reminder for those trying to use shell_exec on a
unix-type platform and can't seem to get it to work. PHP executes as
the web user on the system (generally www for Apache), so you need to
make sure that the web user has rights to whatever files or
directories that you are trying to use in the shell_exec command.
Other wise, it won't appear to be doing anything.
I recommend using passthru and handling the output buffer directly:
ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean();
If you want to know the return status of the command and get the entire stdout output you can actually use exec:
$command = 'ls';
exec($command, $out, $status);
$out is an array of all lines. $status is the return status. Very useful for debugging.
If you also want to see the stderr output you can either play with proc_open or simply add 2>&1 to your $command. The latter is often sufficient to get things working and way faster to "implement".
To clarify which command to use based on the situation
exec() - Execute an external program
system() - Execute an external program and display the output
passthru() - Execute an external program and display raw output
Source: http://php.net/manual/en/function.exec.php
Alejandro nailed it, adding clarification to the exception (Ubuntu or Debian) - I don't have the rep to add to the answer itself:
sudoers file:
sudo visudo
exception added:
www-data ALL=(ALL) NOPASSWD: ALL
In my case I needed to create a new folder in the www directory called scripts. Within scripts I added a new file called test.py.
I then used sudo chown www-data:root scripts and sudo chown www-data:root test.py.
Then I went to the new scripts directory and used sudo chmod +x test.py.
My test.py file it looks like this. Note the different Python version:
#!/usr/bin/env python3.5
print("Hello World!")
From php I now do this:
$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);
And you should see: Hello World!
The above methods seem to be complex. Use my method as a reference.
I have these two files:
run.php
mkdir.py
Here, I've created an HTML page which contains a GO button. Whenever you press this button a new folder will be created in directory whose path you have mentioned.
run.php
<html>
<body>
<head>
<title>
run
</title>
</head>
<form method="post">
<input type="submit" value="GO" name="GO">
</form>
</body>
</html>
<?php
if(isset($_POST['GO']))
{
shell_exec("python /var/www/html/lab/mkdir.py");
echo"success";
}
?>
mkdir.py
#!/usr/bin/env python
import os
os.makedirs("thisfolder");
This is so trivial, but just wanted to help anyone who already followed along Alejandro's suggestion but encountered this error:
sh: blabla.py: command not found
If anyone encountered that error, then a little change needs to be made to the php file by Alejandro:
$command = escapeshellcmd('python blabla.py');
All the options above create new system process. Which is a performance nightmare.
For this purpose I stitched together PHP module with "transparent" calls to Python.
https://github.com/kirmorozov/runpy
It may be tricky to compile, but will save system processes and will let you keep Python runtime between PHP calls.
Inspired by Alejandro Quiroz:
<?php
$command = escapeshellcmd('python test.py');
$output = shell_exec($command);
echo $output;
?>
Need to add Python, and don't need the path.
I'm trying to run a Python script from PHP using the following command:
exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
However, PHP simply doesn't produce any output. Error reporting is set to E_ALL and display_errors is on.
Here's what I've tried:
I used python2, /usr/bin/python2 and python2.7 instead of /usr/bin/python2.7
I also used a relative path instead of an absolute path which didn't change anything either.
I tried using the commands exec, shell_exec, system.
However, if I run
if (exec('echo TEST') == 'TEST')
{
echo 'exec works!';
}
it works perfectly fine while shutdown now doesn't do anything.
PHP has the permissions to access and execute the file.
EDIT: Thanks to Alejandro, I was able to fix the problem. If you have the same problem, don't forget that your webserver probably/hopefully doesn't run as root. Try logging in as your webserver's user or a user with similar permissions and try to run the commands yourself.
Tested on Ubuntu Server 10.04. I hope it helps you also on Arch Linux.
In PHP use shell_exec function:
Execute command via shell and return the complete output as a string.
It returns the output from the executed command or NULL if an error
occurred or the command produces no output.
<?php
$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;
?>
Into Python file test.py, verify this text in first line: (see shebang explain):
#!/usr/bin/env python
If you have several versions of Python installed, /usr/bin/env will
ensure the interpreter used is the first one on your environment's
$PATH. The alternative would be to hardcode something like
#!/usr/bin/python; that's ok, but less flexible.
In Unix, an executable file that's meant to be interpreted can indicate
what interpreter to use by having a #! at the start of the first line,
followed by the interpreter (and any flags it may need).
If you're talking about other platforms, of course, this rule does not
apply (but that "shebang line" does no harm, and will help if you ever
copy that script to a platform with a Unix base, such as Linux,
Mac, etc).
This applies when you run it in Unix by making it executable
(chmod +x myscript.py) and then running it directly: ./myscript.py,
rather than just python myscript.py
To make executable a file on unix-type platforms:
chmod +x myscript.py
Also Python file must have correct privileges (execution for user www-data / apache if PHP script runs in browser or curl)
and/or must be "executable". Also all commands into .py file must have correct privileges.
Taken from php manual:
Just a quick reminder for those trying to use shell_exec on a
unix-type platform and can't seem to get it to work. PHP executes as
the web user on the system (generally www for Apache), so you need to
make sure that the web user has rights to whatever files or
directories that you are trying to use in the shell_exec command.
Other wise, it won't appear to be doing anything.
I recommend using passthru and handling the output buffer directly:
ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean();
If you want to know the return status of the command and get the entire stdout output you can actually use exec:
$command = 'ls';
exec($command, $out, $status);
$out is an array of all lines. $status is the return status. Very useful for debugging.
If you also want to see the stderr output you can either play with proc_open or simply add 2>&1 to your $command. The latter is often sufficient to get things working and way faster to "implement".
To clarify which command to use based on the situation
exec() - Execute an external program
system() - Execute an external program and display the output
passthru() - Execute an external program and display raw output
Source: http://php.net/manual/en/function.exec.php
Alejandro nailed it, adding clarification to the exception (Ubuntu or Debian) - I don't have the rep to add to the answer itself:
sudoers file:
sudo visudo
exception added:
www-data ALL=(ALL) NOPASSWD: ALL
In my case I needed to create a new folder in the www directory called scripts. Within scripts I added a new file called test.py.
I then used sudo chown www-data:root scripts and sudo chown www-data:root test.py.
Then I went to the new scripts directory and used sudo chmod +x test.py.
My test.py file it looks like this. Note the different Python version:
#!/usr/bin/env python3.5
print("Hello World!")
From php I now do this:
$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);
And you should see: Hello World!
The above methods seem to be complex. Use my method as a reference.
I have these two files:
run.php
mkdir.py
Here, I've created an HTML page which contains a GO button. Whenever you press this button a new folder will be created in directory whose path you have mentioned.
run.php
<html>
<body>
<head>
<title>
run
</title>
</head>
<form method="post">
<input type="submit" value="GO" name="GO">
</form>
</body>
</html>
<?php
if(isset($_POST['GO']))
{
shell_exec("python /var/www/html/lab/mkdir.py");
echo"success";
}
?>
mkdir.py
#!/usr/bin/env python
import os
os.makedirs("thisfolder");
This is so trivial, but just wanted to help anyone who already followed along Alejandro's suggestion but encountered this error:
sh: blabla.py: command not found
If anyone encountered that error, then a little change needs to be made to the php file by Alejandro:
$command = escapeshellcmd('python blabla.py');
All the options above create new system process. Which is a performance nightmare.
For this purpose I stitched together PHP module with "transparent" calls to Python.
https://github.com/kirmorozov/runpy
It may be tricky to compile, but will save system processes and will let you keep Python runtime between PHP calls.
Inspired by Alejandro Quiroz:
<?php
$command = escapeshellcmd('python test.py');
$output = shell_exec($command);
echo $output;
?>
Need to add Python, and don't need the path.
I am using Amazon ec2 obunto micro instance. I have wrote a php code which executes a python code and echo the result which is a simple string. When I execute it on obuntu terminal it shows the result perfectly, but when I access it through the browser it doesn't show anything.
And I have no idea why. Actually it cannot execute the python script.
$tmp = exec('/usr/bin/python /var/www/similarity.py employee/unemployed/ waiter');
If anyonw can help me I would really appreciate it.
PS: I am using a mac book pro and when I use the same codes in the localhost of my computer everything works perfectly
After a lot of "scratching my head", I finally figured it out.
First of all you will need to figure out current user who is executing the php. You can either check out php.info file or use
$processUser = posix_getpwuid(posix_geteuid());
print $processUser['name'];
This will give you the user who is executing the code. In my case it was apache rather than www-data (I shouldn't have assumed so in first place).
After that you will need to edit the sudoers file (etc/sudoers)
Add the lines over there.
You can use #Janith's code, if you want to be specific.
apache ALL=NOPASSWD:/var/www/similarity.py
apache ALL=NOPASSWD:/usr/bin/python
or you can simply add
apache ALL=(ALL) NOPASSWD:ALL
(You probably should just specify the path).
Then execute the script through php.
This is permission problem to access python file. When you running it through server python script access as apache user(most probably www-data). So apache user doesn't having privilege to execute the python file.
What you can do it is run this command as sudo and add all necessary access to apache user(www-data) in /etc/sudoers file as below sample.
www-data ALL=NOPASSWD:/var/www/similarity.py
www-data ALL=NOPASSWD:/usr/bin/python
This is just the sample, you should change this line as according to your environment.
This is really simple but I cannot get it to work at all. Spent many hours and I've always give up. I created php script called copy.php and it should call a python script called copy.py.
I want to execute a command line like this
<?php exec('/var/www/html/copy.py'); ?>
Really simple.
Why cannot I get the python script executed from php exec()? The function inside python script is to get a copy of error_log from a different directory (outside of Apache) into html directory.
If I run that from a terminal
> php copy.php
It did execute the function and made a copy. Why is that the web browser isn't doing it?
Let me simplify this:
why cannot exec("cp /var/log/httpd/error_log /var/www/html/path/to/php/script") work?
it works fine if I type it in terminal but not when run in a browser.
As others have alluded to, the difference is probably permissions. When you run a command from the command line, you're generally not the same users as your apache script is running as.
Put another way, if from the command line you type whoami, you'll probably get whatever name your user account is.
The echo exec('whoami'); from within php shows who the script is running as, which is Apache.
So, whatever command you're trying to run from your web server isn't available to run as the Apache user. You mentioned you've been able to have exec("python /usr/diskpurge/script.py") work, but not to have exec('/var/www/html/copy.py') doesn't. This is due to in one instance you're running python, in the other you're trying to execute your copy.py script. If copy.py doesn't have execute permissions for the Apache user, you're not going to be able to run it from the browser.
Perhaps different settings apply for the Apache environment versus the command line.
Use error_reporting(E_ALL); and ini_set('display_errors', true) to see what errosr may come up.
It is possible that the Apache environment is prohibited from using exec or the fact that Apache runs under a different user that does not have execute rights on the python script.
sounds like a permission error. Check if your server is running with sufficient rights.
echo exec('whoami');
Set your error reporting to report all:
ini_set('display_errors', true);
error_reporting(E_ALL);
and check for errors..
If your whoami returns a user which is not a member of the SU family (linux) or administration (windows) then resite your permissions..
Linux:
Assign the user returned by whoami correct permissions to run python scripts.. Do not allow the resulted username to run as root with total administration powers.. This is a big no no
The only reason its not working is because you didn't set the write permissions!
Do:
sudo nano /etc/sudoers
And then put the following:
www-data ALL=(root) NOPASSWD:ALL
I need to detect if php is running as nobody. How do I do this?
Are there any other names for "nobody"? "apache"? Any others?
<?php echo exec('whoami'); ?>
If available you can probe the current user account with posix_geteuid and then get the user name with posix_getpwuid.
$username = posix_getpwuid(posix_geteuid())['name'];
If you are running in safe mode however (which is often the case when exec is disabled), then it's unlikely that your PHP process is running under anything but the default www-data or apache account.
Kind of backward way, but without exec/system:
file_put_contents("testFile", "test");
$user = fileowner("testFile");
unlink("testFile");
If you create a file, the owner will be the PHP user.
This could also likely be run with any of the temporary file functions such as tempnam(), which creates a random file in the temporary directory and returns the name of that file. If there are issues due to something like the permissions, open_basedir or safe mode that prevent writing a file, typically, the temp directory will still be allowed.
More details would be useful, but assuming it's a linux system, and assuming php is running under apache, it will run as what ever user apache runs as.
An easy way to check ( again, assuming some unix like environment ) is to create a php file with:
<?php
print shell_exec( 'whoami' );
?>
which will give you the user.
For my AWS instance, I am getting apache as output when I run this script.
You can try using backticks like this:
echo `whoami`;
I would use:
lsof -i
lsof -i | less
lsof -i | grep :http
You can type any of these in your ssh command line and you will see which user is listening to each service.
You can also check this file:
more /etc/apache2/envvars
and look for these lines:
export APACHE_RUN_USER=user-name
export APACHE_RUN_GROUP=group-name
To filter out envvars file data, you can use grep:
more /etc/apache2/envvars | grep APACHE_RUN_
Straight from the shell you can run:
php -r "echo exec('whoami');"
exec('whoami') will do this
<?php
echo exec('whoami');
?>
In my setup I want to check if the current process has permission to create folders, subfolders and files before I begin a process and suggest a solution if it looks like I can't. I wanted to run stat(<file>) on various things to ensure the permissions match those of the running process (I'm using php-fpm so it varies depending on the pool).
The posix based solution Mario gave above, seems perfect, however it seems the posix extension is --disabled so I couldn't do the above and as I want to compare the results with the response from running stat() running whoami in a separate shell isn't helpful either (I need the uid and gid not the username).
However I found a useful hint, I could stat(/proc/self) and stat(/proc/self/attr) and see the uid and gid of the file.
Hope that helps someone else
Proposal
A tad late, but even though the following is a work-around, it solves the requirement as this works just fine:
<?
function get_sys_usr()
{
$unique_name = uniqid(); // not-so-unique id
$native_path = "./temp/$unique_name.php";
$public_path = "http://example.com/temp/$unique_name.php";
$php_content = "<? echo get_current_user(); ?>";
$process_usr = "apache"; // fall-back
if (is_readable("./temp") && is_writable("./temp"))
{
file_put_contents($native_path,$php_content);
$process_usr = trim(file_get_contents($public_path));
unlink($native_path);
}
return $process_usr;
}
echo get_sys_usr(); // www-data
?>
Description
The code-highlighting above is not accurate, please copy & paste in your favorite editor and view as PHP code, or save and test it yourself.
As you probably know, get_current_user() returns the owner of the "current running script" - so if you did not "chown" a script on the server to the web-server-user it will most probably be "nobody", or if the developer-user exists on the same OS, it will rather display that username.
To work around this, we create a file with the current running process. If you just require() this into the current running script, it will return the same as the parent-script as mentioned; so, we need to run it as a separate request to take effect.
Process-flow
In order to make this effective, consider running a design pattern that incorporates "runtime-mode", so when the server is in "development-mode or test-mode" then only it could run this function and save its output somewhere in an include, -or just plain text or database, or whichever.
Of course you can change some particulars of the code above as you wish to make it more dynamic, but the logic is as follows:
define a unique reference to limit interference with other users
define a local file-path for writing a temporary file
define a public url/path to run this file in its own process
write the temporary php file that outputs the script owner name
get the output of this script by making a request to it
delete the file as it is no longer needed - or leave it if you want
return the output of the request as return-value of the function
add the file info.php to the following directory - your default http/apache directory - normally /var/www/html
with the following contents
<?php
phpinfo();
?>
Then httpd/apache restart
the go to your default html directory
http://enter.server.here/info.php
would deliver the whole php pedigree!
You can use these commands :
<? system('whoami');?>
or
<? passthru('whoami');?>
or
<? print exec('whoami');?>
or
<? print shell_exec('whoami');?>
Be aware, the get_current_user() returns the name of the owner of the current PHP script !
I usually use
<?php echo get_current_user(); ?>
I will be glad if it helped you
$_SERVER["USER"]
$_SERVER["USERNAME"]
<?php phpinfo(); ?>
save as info.php and
open info.php in your browser
ctrl+f then type any of these:
APACHE_RUN_USER
APACHE_RUN_GROUP
user/group
you can see the user and the group apache is running as.
$user = $_SERVER['REMOTE_USER'];
http://php.net/manual/en/reserved.variables.server.php
Authenticated user