1

So I have hosted a webpage on my apache server and I'm trying to run some python and bash scripts when the user presses a button via PHP and AJAX.

Now my php file executes at python script (located in /var/www/html) which in turn executes a bash file (located in root/files).

On doing this manually in terminal, everything works perfectly fine.

But when I try to this via the webpage, the bash script isn't executed.

(I can't place the bash script in /var/www/html because it has the command to clone a git repository to the server and it gives private key shouldn't be public error when placed there)

I already tried suggestions in this answer by adding www-data to sudoers but it is still not working as expected.

Any help on this would be appreciated. Thanks

PHP file :

if(isset($_POST['timestamp']))
{
$uid = $_POST['timestamp'];
echo "Please wait while the app is being generated".$uid;
exec("python /var/www/html/appgenserver.py $uid");

appgenserver.py

#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess


arg = sys.argv[1]
# Path to be created
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
os.makedirs(path)     #Gets executed
subprocess.call(['/root/Final/clone.sh', path)   #Not getting executed
Community
  • 1
  • 1
harshithdwivedi
  • 1,411
  • 16
  • 37

1 Answers1

1

Most likeley because a bash script in its self won't be executable, it's just a plain textfile.
Your bash (and perhaps even appgenserver.py?) might be located under /root and apache probably runs as a non-priviliged user such as www-data, that user won't be able to access either your python script and in turn not the bash that the python would run.

Consider instead calling bash with the script as a parameter.

#! /usr/bin/env python
import os
import json,sys
from firebase import firebase
import requests
import subprocess


arg = sys.argv[1]
path = "/root/files/"+str(arg)
print path
if not os.path.exists(path):
    os.makedirs(path)
subprocess.call(['/bin/bash', '/root/Final/clone.sh', path)

Now, this is NOT the most pretty of solutions.
But what you got before was probably a generic "Permission denied" error in the background (check your /var/log/apache/error.log).

What this does is start /bin/bash as a subprocess with the first parameter being the script you want to execute.

But you have zero error handling here and you can't interract with the process very much.

Consider doing something like this instead:

import subprocess

handle = subprocess.Popen(['/bin/bash', '/root/Final/clone.sh', 'parameter'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
while handle.poll() is None:
    print(handle.stdout.read()) # There's some optimizations here to be done as well so it's not a blocking call etc.

handle.stdout.close()
handle.stdin.close()

And one last tip is not to place stuff in /root/ at all if you're integrating it into a web front-end/backend type of thing.
You're asking for trouble : )

Another way is to make use of sudo

If you modify your exec() in PHP to run exec("sudo ...") and enable your web-user to run the scripts without a password prompt it could work.

Bare in mind, it's not recommended to give www-data sudo access, rather do something like this:

# useradd -m -G www-data -s /bin/bash wwwexec
# echo "myuser ALL=NOPASSWD: /usr/bin/python" >> /etc/sudoers

and change your PHP script to have the following:

exec("sudo -u wwwexec python /var/www/html/appgenserver.py $uid");

That way at least your entire web service isn't given root access via the default username.

The way to do it

Would be to place your appgenserver.py under /var/www/cgi-bin/ instead, and create a CGI hook for .py in your apache configuration and hand over the user to the URL prividing you access to the CGI script.

That way everything should be according to best practices even tho, in theory, you could get your original solution to work.

For instance, this guide should get you started.

Torxed
  • 22,866
  • 14
  • 82
  • 131
  • Hey, Tried it, but still the same result – harshithdwivedi Jun 10 '16 at 19:36
  • 1
    @HarshitDwivedi Humm, Ok what does your `/var/log/apache/error.log` say? – Torxed Jun 10 '16 at 19:39
  • 1
    @HarshitDwivedi Also if you do `sudo -i -u www-data` and then `python yourscript.py` will it still worK? Because I'm guessing the www-data user (or whatever your apache is running as) can't access `/root` stuff? – Torxed Jun 10 '16 at 19:40
  • The output to `sudo -i -u www-data` is `This account is currently not available.` So I guess that its some permission issue – harshithdwivedi Jun 10 '16 at 19:44
  • 1
    @HarshitDwivedi What folder was `appgenserver.py` located in when you tried? Because if you're standing in `/root` as root, trying to execute that the user won't be available in that context because it doesn't have permission to be there : ) If i'm not mistaken. – Torxed Jun 10 '16 at 19:45
  • I was in /var/www/html when I executed `sudo -i -u www-data`, the same folder as appgenserver.py – harshithdwivedi Jun 10 '16 at 19:46
  • Same output as before `This account is currently not available.` – harshithdwivedi Jun 10 '16 at 19:53
  • 1
    @HarshitDwivedi Hate debian based distros.. try this `su - www-data -c 'python yourscript.py`. The account `www-data` probably doesn't have a home folder on your system so the system doesn't let the user live in a logged in session. – Torxed Jun 10 '16 at 19:57
  • Hey, I'm getting the same output on executing this `This account is currently not available` – harshithdwivedi Jun 10 '16 at 20:09
  • 1
    @HarshitDwivedi There is one nasty thing you could do in your PHP script, `exec('sudo -u myuser python appgenserver.py ...');` and if you add your `myuser` to the sudoers file as `myuser ALL=NOPASSWD: /usr/bin/python`. There's all kinds of red flags here but might work. Don't forget to do `sudo useradd -m -G www-data -s /usr/bin/nologin myuser` also. – Torxed Jun 10 '16 at 20:10
  • 1
    @HarshitDwivedi the `/usr/bin/nologin` might not exist on your server, and herpahs you need `/bin/bash` and actually have a shell in order to execute the python executable from PHP. I'm not quite sure, was a long time since I did this. – Torxed Jun 10 '16 at 20:20
  • Hey, I think that this is more of a github issue perhaps because the apache logs are filled with ssh key not private issues. I'll try to execute a dummy bash file and test if it works or not and then post about it here. – harshithdwivedi Jun 10 '16 at 20:22
  • @HarshitDwivedi Sounds good, but please provide the exact log output you found - maybe it's a side-related issue? – Torxed Jun 10 '16 at 20:22
  • So it seems like its an issue with the php unable to execute bash scripts. I created a demo bash script which when executed normally, runs fine. BUT when invoked via php, won't run. Also no errors are logged in `/var/log/apache2` either – harshithdwivedi Jun 10 '16 at 20:51
  • 1
    @HarshitDwivedi Add the following trouble-shooting things found [here](https://stackoverflow.com/questions/12199353/how-can-i-debug-exec-problems) to your php script, so you make sure you enable debugging output. Because exec is a mess to work with. - `exec('my command', $output, $return);` this in particular is a good one to start with. – Torxed Jun 10 '16 at 20:54
  • I was wondering if I can place all my files in /home and run it from there? www-data can access /home right? – harshithdwivedi Jun 10 '16 at 21:12
  • 1
    @HarshitDwivedi yes you could, probably not fully recommended or adopted as best practice, but sure you could :) – Torxed Jun 10 '16 at 21:14
  • 1
    Finally fixed it after hours of head smashing. Turns out that I had to provide write access to www-data in visudo. Everything worked like charm after that. :) Thanks for your help once again. Please add this to your answer so that I can mark it as correct – harshithdwivedi Jun 10 '16 at 22:25
  • @harshithdwivedi have you got a guide so that I can follow? I am facing similar problems to yours mate. thanks – Ahmed.B Apr 01 '20 at 11:31
  • Hey @Ahmed.B. It's been a while since I asked the question but thankfully I did write a guide after I solved it. You can find it here: https://medium.com/@harshithdwivedi/allowing-web-user-on-apache-server-to-run-scripts-as-root-b62c4491e25f I hope it helps you out! – harshithdwivedi Apr 01 '20 at 13:57
  • Hi @harshithdwivedi it doesnt allow me to add any line on my visudo. after adding the line it gives me >>> /etc/sudoers: syntax error near line 31 <<< What now? Options are: (e)dit sudoers file again e(x)it without saving changes to sudoers file (Q)uit and save changes to sudoers file (DANGER!) – Ahmed.B Apr 01 '20 at 14:23
  • Then possibly there is a syntax error. Look to see if your syntax is correct or not. – harshithdwivedi Apr 01 '20 at 15:02
  • I have my php file in /var/www/html folder. In the php file I have got my .py file which resides in /var/www/cgi-bin folder. The problem is whenever I go to the webpage and try to execute the python file.. nothing happens. In my apache error log there is no error as such. So what am I doing wrong? – Ahmed.B Apr 04 '20 at 11:44
  • @Ahmed.B Have you [configured CGI](http://httpd.apache.org/docs/2.2/howto/cgi.html) in Apache? And have you set the scripts as executable? – Torxed Apr 05 '20 at 07:48
  • @Torxed how do I configure CGI in apache? I did read the links you post but they are a little confusing. Can you please explain if possible? I am a newbie. Also I have set my scripts as executable. – Ahmed.B Apr 05 '20 at 12:11
  • @Ahmed.B, what I linked is the official documentation on how to configure Apache to run CGI scripts. If that's to confusing, I won't be able to explain the whole concept in 600 characters on a SO comment section. I suggest you try yourself, google any errors and try to progress on your own. Failure is a part of learning, and this task is pretty straight forward and simple, you should be able to do this on your own. Any particular and unique/new errors can be asked https://serverfault.com/. But remember to google first, try on your own before posting quite standard questions. – Torxed Apr 06 '20 at 09:51
  • @Torxed right I followed the documentation and when I go to my site now i.e. 192.168.0.19:8000/cgi-bin/test.py I get **internal server error** – Ahmed.B Apr 07 '20 at 16:00
  • @Ahmed.B That's pretty common, and the apache error log should tell you why. If not, increase verbosity and ask a related question on serverfault as they are equipped to handle these types of question (sister site to this site) : ) The reason why I say this, is because this question is regarding how to execute bash via apache. It's not regarding how to set up CGI. And comments from here on should probably be related to the execution part, not the setting up part if that makes sense (two different subjects) : ) – Torxed Apr 07 '20 at 16:07
  • I get this error : `[cgid:error] [pid 1547] [client 192.168.0.33:65405] malformed header from script 'test.py': Bad header: ()`. I am little confused as there are 2 pages now. 1 is the php and the other is the cgi-bin/test.py. With the php page I dont get any errors but the python script is not executed. – Ahmed.B Apr 07 '20 at 21:36