Django not recognizing ssl related os.environ - python

I have Django installed on a corporate intranet, running on Apache using mod_wsgi. The Apache server has SSL set up, and everything is working as expected when users hit CGI pages, but my django applications don't seem to be picking up any SSL related environment variables (ssl_client_s_dn, etc) whether they go to my django pages with http:// or https://.
I think the main issue is that I don't understand where django is pulling it's os.environ from, and how to change that. I've looked through the official django documentation and other posts on 'django' and 'ssl', but those seem to deal with views that need to sometimes be http, and sometimes https. I am just trying to get ssl related information to show up in os.environ at all, and I don't know where to look next.
What do you need to know? httpd.conf wsgi configuration settings? My projects settings.py, or lines in wsgi.py?
Any help is much appreciated.

If you are using mod_wsgi within Apache, and you set the environment variables in Apache (using SetEnv), then you are out of luck: mod_wsgi's environment variables are separate from these in Apache.
Many people are running into similar problems, when setting variable in Apache using SetEnv is completely invisible when trying to access os.environ in Django.
There is however some solution. It is listed here, and basically comes to these lines in your wsgi script (adjusted to your needs):
def application(environ, start_response):
os.environ['ssl_client_s_dn'] = environ['ssl_client_s_dn']
return _application(environ, start_response)
Which basically translates first argument of your WSGI application into os.environ dictionary. For details see the post linked above.

Related

Internationalization (i18n) not rendered using flask-babel and apache with mod_wsgi on Ubuntu instance

I have a web application developed using python 2.7.6, flask and deployed on a Apache Ubuntu server.
For internationalization, the app uses the flask-babel package in order to translate into Thai. However, it seems that my translations/th/LC_messages/messages.po file is ignored.
It works perfectly in my localhost but not in the server. To force the selection of the locale, I use the code below:
#babel.localeselector
def get_locale():
return 'th'
It seems there is something that might be missing in my configuration file but couldn't figure it out.
If you have any ideas please feel free. Thank you.
I encountered this exact same issue! My babel translations were working fine when I ran the app locally, but on my apache server, none of the text was translating as expected.
After attempting a number of different fixes, I figured out that (for whatever reason), my custom get_locale localeselector override function was not getting used by the app when it ran on the apache server.
I ended up explicitly importing the get_locale function into the relevant view file, which resolved the issue.

Django deployment final step

I have a Django project with 1 app that is working locally and I am trying to make it work on the server but I imagine I am still missing something...
The steps I have followed are:
1) create a virtualnev
2) Install django and the libraries I need
3) copy my local project to the server, keeping the same directory structure
4) create the file passenger_wsgi.py (python passenger_wsgi.py did not return any error)
After this do I need to do anything like python manage.py runserver? Or with this I should be already able to see the site through mydomain/my project/ my app (when I do ot just get an error 404)?
I have read the django book and followed the tutorial, but this part is not well described anywhere...
Thanks in advance for any help!
Deployment is explained in the documentation.
You need to actually serve your application with some kind of HTTP server and something to run your python code. Some of the possible combinations are:
nginx with uWSGI
Any web server as reverse proxy with gunicorn
Apache with mod_wsgi
Your hosting service may or may not give you the choice or even the possibilty to do this.
There is a list of Django friendly hosters in the Django wiki.
Well firstly you might want to go through the previously asked questions.
When you are deploying using passenger you do not need to run manage.py runserver , etc. The passenger_wsgi file should take care of it.
You might want to check this link out, in the first answer also contains link to Dreamhost which details quite extensively on how to achieve the same.
Visit Deploying Django app using passenger
From my personal experience I found Nginx and uwsgi setup to be much more easier to handle and work and debug in the logs, but this is subjective to your needs and platform you may have.

How do I determine if my mod_wsgi application is running on HTTPS?

I've just inherited a Python application which is running under Apache 2.4, mod_wsgi 3.4 and Python 2.7. The same application serves both HTTP and HTTPS requests.
In the existing code, it is trying to determine if the reqeust was HTTPS by checking the environment:
if context.environ.get('HTTPS') not in ['on', '1']:
This check is failing, even when the connection actually was HTTPS. On looking at an extended traceback showing the environment variables, I saw that HTTPS was not actually in the environment passed from Apache.
So my questions are:
Is this an Apache configuration problem?
Is this check completely wrong and should be rewritten to check something else? And if so, what?
Or should I give up and replace Apache with nginx like I really want to do?
Apache's mod_ssl can be configured to set the HTTPS environment variable, but doesn't do so by default for performance reasons.
You could explicitly enable it, but since you're using a WSGI application, it's probably a better idea to check the wsgi.url_scheme environment variable instead; the WSGI spec guarantees its presence, and it won't require any further changes to your application if you do eventually move to nginx.
When using CGI, WSGI or SSI you will need to advise Apache to send the HTTPS header otherwise it will beempty. You can do this with mod_env in the config or .htaccess
<IfModule mod_env.c>
SetEnv HTTPS on
</IfModule>

Python Shared Hosting

I would love to be able to use Python and Django for web applications at the company I work for. We currently use PHP because everyone is familiar with it and easy to deploy for a large number of clients. We can host anywhere between 10 to 100 websites on a single virtual server.
Is it possible to serve a number of websites from a single Apache and Python installation? Each website must have their own domain among other things, such as email accounts.
I wouldn't use Apache, the current best practice is an Nginx frontend proxying requests to uWSGI servers. Read about the uWSGI Emperor mode. It's very versatile. http://uwsgi-docs.readthedocs.org/en/latest/Emperor.html. Each individual app can be modified, removed added to dynamically. We use it at PythonAnywhere to serve thousands of web applications
There are other WSGI servers that you can use as well. uWSGI just seems the most scalable in my experience.
Yes, It is definitely possible. In our setup, typically we have django behind mod_wsgi, Apache and nginx
You can configure apache's Virtualhost, to point to a specific mod_wsgi which in turn points to specific code.
Quoting from here - Refer to the SO post for further information.
There are at least two methods you can try to serve from a single
instance:
Use apache + mod_wsgi and use the WSGIApplicationGroup and/or
WSGIProcessGroup directives. I've never needed these before so can't
be completely sure these will work the way you want, but regardless
you can definitely use mod_wsgi in daemon mode to greatly improve
your memory footprint.
You can play with Django middleware to deny/allow URLs based on the
request hostname (see HttpRequest.get_host() in the Django docs).
For that matter, even though it would be a slight performance hit,
you can put a decorator on all your views that checks the incoming
host.
Yes, you can easily serve up many sites using a single Apache / mod_wsgi installation. Typically you would do that with a separate virtualhost section for each website. See the virtualhost docs. You want to use a different servername directive in each virtual host config to specify what hostnames get routed to which config. See more detailed documentation in name based virtual hosts

Refresh urls.py cache in django

I'm using django on nginx with FastCGI and i have a problem with urls.py. According to this question, django caches url.py file and i'm - just like above question's author - not able to modify my URLs definitions.
My question is - is there any way to clear url cache in django/nginx/fcgi without server restart (which not helps anyway)?
This is not just a urls.py thing, it's normal workflow for running a wsgi or fastcgi app. The module is in memory, and it doesn't get reloaded from disk until you tell the server that it's changed.
As per Django's FastCGI docs:
If you change any Python code on your site, you'll need to tell FastCGI the code has changed. But there's no need to restart Apache in this case. Rather, just reupload mysite.fcgi, or edit the file, so that the timestamp on the file will change. When Apache sees the file has been updated, it will restart your Django application for you.
If you have access to a command shell on a Unix system, you can accomplish this easily by using the touch command:
touch mysite.fcgi
For development, in most cases you can use the django development server, which watches for code changes and restarts when it sees something change.
You don't need to restart the whole server, just your FastCGI app. However, I don't know why you say this doesn't help - this is the way to do it. It can't not help.

Categories

Resources