Python exec() Permission Denied in Apache server: /cgi_bin/*.py - python

I have 2 python env in my server. One path is /usr/bin and other one is the anaconda path as shown below. I am getting Permission denied error when I try executing a basic Python script on my Apache server. The python interpreter path in my .py file is as follows
#!/home/cloudera/anaconda3/bin
When this path is used, the apache server shows the error as shown below:
(13)Permission denied: exec of '/var/www/cgi-bin/abc.py' failed, referer:
When my python interpreter path in .py is changed to i.e #!/usr/bin it works well.
The problem is I have installed all my packages in /home/cloudera/anaconda3/bin
I tried setting this path to be accessible to execute in apache server by adding the below line of code in /etc/httpd/conf/httpd.conf file as follows
<Directory "/home/cloudera/anaconda3/bin/">
AllowOverride None
Options ExecCGI
AddHandler cgi-script .py
#None
Order allow,deny
Allow from all
</Directory>
I still get Permission Denied. It still does not work. I am new to cgi, any help would be really grateful. Thanks in advance.

Admittedly I've completely missed the fact that the interpret was specified as directory and the actual binary file as pointed out by Jean-François Fabre. That would indeed cause the same error. But since the OP fixed that and still got the same error, I am undeleting the answer extended as requested.
Also come to think of it, it may be more of a Server Fault question as it would appear.
This error (13: EACCES) is raised by and propagated from the OS.
HTTPd servers usually employ privilege separation and once bound to a reserved port drop their EUID to an unprivileged user. Usually a dedicate one or nobody (on my system it would be user apache, group apache). You should be able to find these in your httpd.conf under User and Group resp.
Make sure this user has access and can execute the binary you're calling.
Give you've fixed the interpreted (and the file would execute on its own). Go find your httpd.conf file (I think different distros may package it differently, on mine it would reside here: /etc/httpd/httpd.conf). You will find User and Group entries there. You must be able to access and execute the script (incl. the interpreter) as this user, because that's how Apache will try to call it. I.e. this user (or group) must be able to access this file (along the complete path) and execute it. If for instance /home/cloudera/ us restricted to (0700: rwx------) and owned by user other then the one listed int your httpd.conf (very likely), OS would prevent your Apache user to access and execute the file resulting in EACCES error you are seeing. The easiest might be to become that user and see how far your access goes, but you'd need to temporarily tweak few bits for that as the Apache account likely is locked and has not shell set (or rather /bin/false as shell).
One more thing, but I hope it's not as obvious as that. The corresponding user must have execute permission on the script itself.

Related

Python Flask with Waitress server cannot run, when making it as a Windows service

I built a Python application with Flask and run with Waitress server.
The app use local .csv files as the input data.
It can run well when running by command line. (ie. python webserver.py), I can load csv to read data, upload (to overwrite) the csv files.
But when I add it as a window's service (with nssm, or Window Resource Kit), my app can run, but the csv files only can be loaded by JS, not by the python.
It means, in service mode, if I load csv using js, It's ok, but when loading or uploading file (using python script) It returns "Internal Server Error".
My question is, how are running by command line and adding as Window's service different? How to make python script works with csv file when making it as service?
Any help is appreciated. Thank you so much.
This is the upload code.
#app.route('/uploadss', methods = ['GET', 'POST'])
def upload():
import os
print(request.files['file'])
if request.method=='POST':
file = request.files['file']
filenames = ['temperature.csv','inlet_clean_info.csv','log_data.csv','medium-term-temperature.csv']
if file.filename in filenames:
file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
return 'file uploaded successfully'
else:
return 'filename is not acceptable'
and I have add waitress webserver as service with:
> -(nssm) nssm.exe install MyService. Then add python path and the executed python file.
> -(Window ResKit) instsrv.exe LNG c:\reskit\srvany.exe. Then add "Parameter" key in Regedit, add "Application" String to point to <python path> <executed path>
In both cases, it returns "Internal Server Error"
This is the Error message, the returned response
" 500
Internal Server Error Internal Server Error The
server encountered an internal error and was unable to complete your
request. Either the server is overloaded or there is an error in the
application. "
The primary differences when running an app as a service are around environment.
Some things specifically:
Which user the service is running as.
When you start it from the command line, it's likely running as your user account. Your user account is likely to have different permissions from the Windows system account. This tends to cause issues with accessing files more than, for example, opening a port for an HTTP server. There may be other permissions related problems.
Environment variables, including PATH.
When you're in a command shell, windows has a PATH variable that tells it where to look for executable files. So if you type python it looks for python.exe in the current folder, then it searches through the PATH variable until it finds python.exe
You also have other environment variables that can be defined such as TMP (temporary folder), etc.
When it's running as a service, it's generally running in a different user context, which will have different environment variables, both the %TMP% and PATH. So one thing that could be happening is that it's trying to run python.exe but there's no python.exe on the path for the service user.
HKCU Registry entry
If your app uses the registry, and uses the HKEY_CURRENT_USER tree, this is likely different when it's running as a service. (HKEY_CURRENT_MACHINE is likely the same).
The folder that the application starts in
When you run it from the command line, you generally start it in the current folder. This means that it's possible to use relative paths (e.g. .\images) instead of absolute paths (c:\website\images).
If you were to change to a different folder, then the .\images version may not work.
When a program runs as a service, it usually seems to start in C:\Windows\System32
So you could investigate whether using absolute paths works. Or you could investigate whether there's a way to specify the startup folder.
Another thing to check (possibly first) - look for the log file
Normally web servers write a log file on the server somewhere.
The 500 error would go to the user, but there'd be a more detailed error written to a log. So find where that log file should be and check it out. (It's possible that it's not where it should be, and that could be to do with permissions associated with the User the service is running as). If it is there, it may help track down the particular issue.

Apache2.4 is finally running python script... but why?

It took me quite a while to figure out how to make Apache2.4 run my "Hello, world!" python script. I have finally figured out what sequence of commands I have to run in the command line for the script to work. Unfortunately, I still don't understand what is happening when I run those commands. I would like to know why they make my script work. I know it's all in the documentation, but so far I find it a bit hard to comprehend what's written there.
Here goes the list of commands I used.
sudo apt-get install apache2
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork
sudo service apache2 restart
sudo a2enmod cgi
sudo service apache2 restart
Any comments on steps 2, 3 and 5 would be highly appreciated.
After that I create script.py in /usr/lib/cgi-bin:
#! /usr/bin/python
print "Content-type: text/html\n\n"
print "Hello, world!"
For some reason the first two lines of the script.py are absolutely necessary. There is no way the code is going to run without them.
And finally I run:
sudo chmod +x /usr/lib/cgi-bin/script.py #why do I need this? how come it is not executable by default?
sudo service apache2 restart
When I call http://localhost/cgi-bin/script.py I get my Hello, world!
I didn't even have to modify apache2.conf, serve-cgi-bin.conf or 000-default.conf
If there is a more obvious/better/correct way to run a python script using Apache24, I would really love to learn it.
P.S. Some people recommend adding AddHandler cgi-script .py .cgi to /etc/apache2/conf-enabled/serve-cgi-bin.conf if you encounter a problem when running a script on Apache. But for some reason it doesn't make any difference in my case. Why?
P.P.S. I use Ubuntu 14.04.
The event Multi-Processing Module (MPM) is designed to allow more
requests to be served simultaneously by passing off some processing
work to supporting threads, freeing up the main threads to work on new
requests.
http://httpd.apache.org/docs/2.2/mod/event.html
This Multi-Processing Module (MPM) implements a non-threaded,
pre-forking web server. Each server process may answer incoming
requests, and a parent process manages the size of the server pool. It
is appropriate for sites that need to avoid threading for
compatibility with non-thread-safe libraries. It is also the best MPM
for isolating each request, so that a problem with a single request
will not affect any other.
http://httpd.apache.org/docs/current/mod/prefork.html
5)
a2enmod is a script that enables the specified module within
the apache2 configuration.
http://manpages.ubuntu.com/manpages/lucid/man8/a2enmod.8.html
The name a2enmod stands for apache2 enable module.
For some reason the first two lines of the script.py are absolutely
necessary.
The first one tells apache how to execute your cgi script. After all, there are other server side languages, like php, perl, ruby, etc. How is apache supposed to know which server side language you are using?
The second line outputs an HTTP header, which is the simplest header you can use. The headers are required to be output before the body of the request--that's the way the http protocol works.
sudo chmod +x /usr/lib/cgi-bin/script.py
why do I need this? how come it is not executable by default?
A file cannot be executed unless an administrator has given permission to do so. That is for security reasons.
If there is a more obvious/better/correct way to run a python script
using Apache24, I would really love to learn it.
Most of the commands you listed are to setup the apache configuration. You shouldn't have to run those commands every time you execute a cgi script. Once apache is configured, all you should have to do is start apache, then request a web page.
P.S. Some people recommend adding:
AddHandler cgi-script .py .cgi
to /etc/apache2/conf-enabled/serve-cgi-bin.conf if you encounter a
problem when running a script on Apache. But for some reason it
doesn't make any difference in my case. Why?
See here:
AddHandler handler-name extension [extension]
Files having the name extension will be served by the specified
handler-name. This mapping is added to any already in force,
overriding any mappings that already exist for the same extension. For
example, to activate CGI scripts with the file extension .cgi, you
might use:
AddHandler cgi-script .cgi
Once that has been put into your httpd.conf file, any file containing
the .cgi extension will be treated as a CGI program.
http://httpd.apache.org/docs/2.2/mod/mod_mime.html#addhandler
So it appears that when you add the AddHandler line it is overriding a configuration setting somewhere that does the same thing.
Response to comment:
ScriptInterpreterSource Directive
This directive is used to control how Apache httpd finds the
interpreter used to run CGI scripts. The default setting is Script.
This causes Apache httpd to use the interpreter pointed to by the
shebang line (first line, starting with #!) in the script
http://httpd.apache.org/docs/current/mod/core.html
On the same page, there is this directive:
CGIMapExtension Directive
This directive is used to control how Apache httpd finds the
interpreter used to run CGI scripts. For example, setting
CGIMapExtension sys:\foo.nlm .foo will cause all CGI script files with
a .foo extension to be passed to the FOO interpreter.
The mpm stands for Multi-Processing Module; basically you replaced the event based approach with the prefork; this is used internally by Apache and often does not affect anything beyond performance (each of these have different performance characteristics), but some things are not compatible with some MPM's and then you need to change them.
The cgi module is an additional module that provides the Common Gateway Interface; it is not included in Apache by default anymore.
The first line of the script is the shebang; it tells Unix/Linux kernel what program to use as the interpreter; that is; "use /usr/bin/python to run this file please". The file extensions do not mean anything in *nix w.r.t executability.
The second line are the headers. The CGI specification says that the output shall be headers followed by an empty line, followed by the content. 1 header is mandatory: the Content-Type. Here you are telling the webserver and browser, that what follows is a document of type text/html. '\n' stands for a newline. (Technically you should write
print "Content-type: text/html\n\n",
with a comma there, otherwise you get one newline too much).
Files in *nix don't have the +x execute bit on by default - this is a security feature; a conscious decision is required to make something executable.
As for the preferred method, since you control the server, use the Apache mod_wsgi with any web framework - Pyramid, Flask, Django, etc; WSGI applications are much more efficient than the CGI.

configure apache for python in windows

I installed python27 , and also the latest version of apache.
in order to run a simple program by refering link
also edited the httpd.conf file also
but i accessed the folder localhost/cgi-bin displays the error
"Forbiden you don't have the permission to access this folder"
Changed the folder permission from properties of folder.
any other way to solve the problem.
So you have a cgi script named hello.py containing the code from the tutorial and installed in the cgi-bin directory as configured in the httpd.conf file?
If you browse to http://localhost/cgi-bin/ you will most likely see a HTTP 403 Forbidden response with text along the lines of:
You don't have permission to access /cgi-bin/ on this server.
You need to execute the actual cgi script, not the containing directory, so try browsing to http://localhost/cgi-bin/hello.py.
If that doesn't work, what changes did you make to httpd.conf? Have you installed the cgi script in the directory specified in the ScriptAlias /cgi-bin/ directive?

running subprocess.Popen under apache+mod_wsgi is always returning an error with a returncode of -6

I'm hoping someone's seen this -
I'm running django-compressor, taking advantage of the lessc setup to render/compress the less into CSS on the file. It works perfectly when invoked from the development server, but when run underneath apache+mod_wsgi it is consistently returning an error.
To debug this, I have run the exact command that the filter is invoking as the www-data user (which is defined as the wsgi user in the WSGIDaemonProcess directive) and verified that it works correctly, including permissions to read and write the files that it's manipulating.
I have also hacked on the django-compressor code in compressor/filters/base.py on that system, and it seems that ANY command attempting to get invoked is getting a returncode of -6 after the proc.communicate() invocation.
I'm hoping someone's seen this before - or that it rings some bell. It works fine on this machine outside of the apache+mod_wsgi process (i.e. running the process as a dev server) as well. I'm just not clear on what might be blocking the subprocess.Popen() invocations.
Are you using Python 2.7.2 by chance?
That version of Python introduced a bug which cause fork() in sub interpreters to fail:
http://bugs.python.org/issue13156
You will have to force WSGI application to run in main Python interpreter of the process by setting:
WSGIApplicationGroup %{GLOBAL}
If running multiple Django applications you need to ensure that only the one affected has this configuration directive applied to it else you would cause all Django applications to run in one interpreter which isn't possible due to how Django configuration works.

error in configure mod_wsgi with Apache2.2

I am follow this http://pradyumnajoshi.wordpress.com/2009/06/09/setting-up-mod_wsgi-for-apache-and-django-on-windows/
I am using python2.6, Apache2.2, Django1.3 and mod_wsgi>3 on windows xp. now I have installed Apache correctly it is running well. and I have add the following line in httpd.conf file:-
LoadModule wsgi_module modules/mod_wsgi.so
Now i restart my Apache server It's running well. But when I have add the following lines in httpd.conf:-
WSGIScriptAlias /wsgi “C:/wsgi_app/wsgi_handler.py”
<Directory “C:/wsgi_app”>
AllowOverride None
Options None
Order deny,allow
Allow from all
</Directory>
Then restart my Apache server it give error on the prompt "The request operation has failed"
please help me I am new in python.
Thank You.
Whenever debugging Apache, the first place to check is the error and access logs. I've never used apache with Windows, but if you find logs, you'll get a much more descriptive error message.
FYI, I believe it is normally recommended to make the wsgi_handler use a .wsgi extension (though I think this is probably because it is normally named django).
make sure you have wsgi_handler.py file in the directory C:/wsgi_app.
problem may be the symbol with which you are quoting.
replace “C:/wsgi_app/wsgi_handler.py” with "C:/wsgi_app/wsgi_handler.py" and “C:/wsgi_app” with "C:/wsgi_app".

Categories