How do I prevent the raw WSGI python file from being read? - python

I am using mod_wsgi with apache to serve the python application. I have a directive in the VirtualHost entry as follows WSGIScriptAlias /app /home/ubuntu/www/app.wsgi. I also have DocumentRoot /home/ubuntu/www/. Therefore, if the user attempts to read /app.wsgi it gets the raw file. If I try to block access to it via .htaccess, the application becomes unusable. How do I fix this? Is there a way to do so without moving the file out of the DocumentRoot?

This is far from the best option, but it does seem to work: I added WSGIScriptAlias /app.wsgi /home/ubuntu/www/app.wsgi to the VirtualHost as well so that it will run the app on that uri instead of returning the raw file.

You should not stick the WSGI file in the DocumentRoot directory in the first place. You have created the situation yourself. It doesn't need to be in that directory for WSGIScriptAlias to work.

Related

django deploy - ubuntu 14.04 and apache2

https://www.sitepoint.com/deploying-a-django-app-with-mod_wsgi-on-ubuntu-14-04/
and
https://www.youtube.com/watch?v=hBMVVruB9Vs
This was the first time I deploy a website.And these are the tutorials I followed.
Now I can access to the server(by typing 10.231.XX.XX) from other machine and see the Apache2 Ubuntu Default Page.
Then I tried to access my django project. I run:
python manage.py runserver 8000
Validating models...
0 errors found August 03, 2016 - 09:44:20 Django version 1.6.1, using
settings 'settings' Starting development server at
http://127.0.0.1:8000/ Quit the server with CONTROL-C.
Then I type 10.231.XX.XX:8000 to try to acess the django page. But I failed.
It said:
This site can’t be reached
10.231.XX.XX refused to connect. Search Google for 231 8000 ERR_CONNECTION_REFUSED
I have tried every thing I can but still can't figure why.
(as followed the website https://www.sitepoint.com/deploying-a-django-app-with-mod_wsgi-on-ubuntu-14-04/)
I have apache folder in mysite folder, and in override.py:
from mysite.settings import *
DEBUG = True
ALLOWED_HOSTS = ['10.231.XX.XX']
in wsgi.py:
import os, sys
# Calculate the path based on the location of the WSGI script.
apache_configuration= os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)
sys.path.append(workspace)
sys.path.append(project)
# Add the path to 3rd party django application and to django itself.
sys.path.append('/home/zhaojf1')
os.environ['DJANGO_SETTINGS_MODULE'] = '10.231.52.XX.apache.override'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
and __init__py is empty.
in /etc/apache2/sites-enabled/000-default.conf :
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
WSGIScriptAlias /msa.html /home/zhaojf1/Web-Interaction/apache/wsgi.py
<Directory "/home/zhaojf1/Web-Interaction-APP">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
I have also restart apache after I do everything.
Thanks for help
The connection refused error is likely going to come down to Apache being incorrectly configured for the VirtualHost or you accessing wrong port. You also have other basic mistakes in your wsgi.py file as well.
Starting with the wsgi.py file, the DJANGO_SETTINGS_MODULE value is wrong:
os.environ['DJANGO_SETTINGS_MODULE'] = '10.231.52.XX.apache.override'
The value is meant to be a Python module path. Having the IP address in there looks very wrong and is unlikely to yield what you need.
Next is changes to sys.path. The location of your project and activation of any Python virtual environment is better done through options for mod_wsgi in the Apache configuration file.
That you are adding a home directory into the path is also a flag to potential other issues you may encounter. Specifically, the user that Apache runs as often cannot read into home directories as the home directories are not readable/accessible to others. You may need to move the project out of your home directory.
As to the Apache configuration, your VirtualHost lacks a ServerName directive. If this was an additional VirtualHost you added and not the default (first one appearing in Apache configuration when parsed), it will be ignored, with all requests going to the first VirtualHost. You do show this as in the default site file, so may be you are okay.
Even so, that VirtualHost is set up to listed on port 80. You are trying to connect to port 8000, so there wouldn't be anything listening.
Next issue is the WSGIScriptAlias line.
WSGIScriptAlias /msa.html /home/zhaojf1/Web-Interaction/apache/wsgi.py
It is strange to have msg.html as the mount point as that makes it appear as if you are accessing a single HTML page, but you have it mapped to a whole Django project. If you were accessing the root of the host, it also wouldn't map through to the Django application as you have it mounted at a sub URL. Thus perhaps need to use:
WSGIScriptAlias / /home/zhaojf1/Web-Interaction/apache/wsgi.py
Next problem is that the directory specified in Directory directive doesn't match where you said the wsgi.py file existed in the WSGIScriptAlias. They should match. So maybe you meant:
<Directory /home/zhaojf1/Web-Interaction/apache>
Even then that doesn't look right as where is the apache directory coming from. That last directory in the path should normally be the name of the Django project.
One final thing, you may need to change ALLOWED_HOSTS as well. If you find you start getting bad request errors it probably doesn't match properly. Change it to ['*'] to see if that helps.
So lots of little things wrong.
Suggestions are:
Make sure you read the official Django documentation for setting up mod_wsgi. See https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/modwsgi/
If you are only wanting to do development at this point, use mod_wsgi-express instead. See http://blog.dscpl.com.au/2015/04/using-modwsgi-express-with-django.html and http://blog.dscpl.com.au/2015/04/integrating-modwsgi-express-as-django.html

Django project file structure

I'm new to Django and need to understand file structure. below is an example of my Django project (some files missing)
My confusing is to do with production on a real server and how my file structure relates.
I have the following questions on this issue which I think if answered will help me understand.
Where is the web root?
How do you stop users from downloading settings.py?
Its this structure ok?
project
manage.py
templates [folder]
myapp1 [folder]
models.py
views.py
projectname [folder]
urls.py
settings.py
There is no web root. Django project files can be placed anywhere for a web server to run and serve at a given URL. URL's do not correspond to file structure.
Django should never be exposed to the public. You stop users from downloading it by not exposing it to the public. Only static media should ever be accessible from the web.
Yes, your structure is okay. That's the recommended new standard.
With mod_wsgi you don't need to declare a Document Root, you just give a path to your wsgi file
a sample apache mod_wsgi configuration from the docs:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
Users cannot access settings.py apache does not serve it. Make sure debug=False though as it can expose your settings
Your structure is the default django structure from 1.4+
Just to add another perspective, your URLconf, contained in urls.py, defines the virtual filesystem, if you will, of your web root. It's up your URLconf scheme to route entire classes of URLs to your views, which generate dynamic pages. So in a sense, with a handful of URL entries, views, and templates, you can make it appear as though you have a web root with populated with countless "files", none of which are your actual Python source code.

Setting up Python in AMPPS - Internal Server Error

I'm trying to use Python with AMPPS, which is an Apache / MySQL / etc. bundle for Windows. There's just one problem though; every script I try to run returns an 'Internal Server Error', even though it's correct code.
This is probably an issue that's not worth posting it here, but I googled for three hours and I just can't find any help.
My httpd.conf is over here: http://pastebin.com/5DMU2cUU
The single line of code I use is: print "Hello World!";
Notepad++ is set to EOL Conversion->UNIX format (before you ask).
This is all I know so far. Please don't hate me for posting this (I know you love to do that), I'm new and confused :3
mod_wsgi is already configured in AMPPS. You can see it in loaded modules of apache.
httpd.exe -D DUMP_MODULES
You just need to configure your script now.
http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide
You can modify the python.conf included in httpd.conf too. i.e for using mod_wsgi directives.
This is official hello world example from mod_wsgi. Hope this helps.
Follow below steps:
Open httpd.conf
Append .py to AddHandler cgi-script .cgi .pl under tag
Now AddHandler cgi-script .cgi .pl becomes AddHandler cgi-script .cgi .pl .py
Search for block and Add ExecCGI to Options FollowSymLinks Indexes.
Now its become Options FollowSymLinks Indexes ExecCGI
Save the httpd.conf file, stop the apache server and restart again.
If the apache server restarts without any problem process you have successfully setup ampps to run python, otherwise restore the conf file from backup. In ampps there is an option to restore default configuration.
Add python exe file link line to the top of the python file to direct to the Python interpreter.It might be #!C:\Ampps\python\python.exe
Add this line print("Content-type: text/html\n")
Add this line print("Hello world!")
Now execute your python file. http://127.0.0.1/test/test.py
wsgi_module must be installed for apache to run python script via execCGI. On ampps this is installed and added to conf file by default.
link:http://www.lakshman.com.np/run-python-on-ampps-windows/

What determines the applicative log file location in Apache/Django?

(Cross posted to Server Fault some time ago)
I have a django app running on Apache/ubuntu, and I have evidently misconfigured it.
When I start apache, I'm getting this error in the apache log:
...
IOError: [Errno 2] No such file or directory: '/home/osqa/sites/log/django.osqa.log'
Now, my site is supposed to be running in 'home/osqa/sites/foobar/'. Why is django/apache looking for a log file in a folder above that folder? Where is this configured? How to resolve/analyze?
The following lines in your httpd.conf file is what is causing your problem:
CustomLog ${APACHE_LOG_DIR}/beta-meta-d3c.access.log common
ErrorLog ${APACHE_LOG_DIR}/beta-meta-d3c.error.log
This logging is set up for apache as a whole, not just your application which is set up in a subdirectory within apache.
${APACHE_LOG_DIR} should evaluate to /home/osqa/sites/log/. Fully expanded with your log names it will be:
/home/osqa/sites/log/beta-meta-d3c.access.log
Which is exactly what it is telling you. Either create that directory and make it writeable, or change your httpd conf to append the name of your application to the logging path directive. I'd probably not change the path though, as other applications might want to log also, but not to your directory.
My hunch is that it's something in your apache2 config. Go to sites-available/your-site.com.conf, and look in its file. Perhaps you'll find that it is logging things?

How deploy Flask application on Webfaction?

Anybody know how to deploy a simple Flask application on Webfaction?
I know Webfaction support mod_wsgi and I read the guide on the Flask site but still I can't make my app working. Anybody have a working configuration?
UPDATE to answer a comment by Graham Dumpleton.
I get a 500 Internal server error. Apache does not show any error in the logs. The WSGI script is executed and seems to create the application correctly, but I keep getting a 500 error.
Thanks.
I got it working with the following procedure:
create and app named 'myapp' of type mod_wsgi 3.3/Python 2.7. Webfaction will create the following folders:
myapp
|- apache2
|- htdocs
Webfaction will also automatically create a simple script index.py in your htdocs directory. Check if the sample script work visiting the root of your newly created application (to do thin on Webfaction you need to "mount" the app on a website). If it's all OK modify the script deleting the content and adding:
from myapp import app as application
In apache2/conf/httpd.conf add the follwing lines:
WSGIPythonPath /home/username/webapps/myapp/htdocs/
#If you do not specify the next directive the app *will* work but you will
#see index.py in the path of all subdir
WSGIScriptAlias / /home/username/webapps/myapp/htdocs/index.py
<Directory /home/username/webapps/myapp/htdocs>
AddHandler wsgi-script .py
RewriteEngine on
RewriteBase /
WSGIScriptReloading On
</Directory>
Restart apache2
You need to set up a "Custom app (listening on port)" application. Make a note of the port that is assigned. Then in your Flask code, you need to put hardcode the port:
if __name__ == __main__:
app.run(host='0.0.0.0' port=XXXXXXX)
Where you substitute XXXXXXX with the port that is randomly assigned to your custom app.
Hope that helps.
EDIT:
Please use Raben's Answer, this way should not to be used in Production.

Categories