apache + django + mod_wsgi conversion to https keeps going back to http - django

I've had a django (satchmo) site using Apache and mod_wsgi running fine for a couple of years now. Until now it has only served http, and I'm trying to convert the entire site to https. I have a signed ssl certificate which I believe is fine.
I have adapted my Apache configuration according to my understanding of the docs.
When I try to connect to the site using https, the browser connects fine on port 443, and the Apache server responds with the correct ssl certificate followed by the TLS key exchange etc (according to what I see in Wire Shark). At that point everything looks fine and there are no errors. But..
Once the ssl connection is established, the browser then initiates a "GET / HTTP/1.1" in a new TCP connection to port 80 (i.e. http). It's like it knew nothing about the https connection already in place.
Is it possible that django is at fault? I have not changed the django configuration at all, as I was under the impression that only Apache needs to know about it? (I don't use nginx - Apache handles all of the content.)
I can't "see" what is going on in the ssl conversation, but presumably django is telling the browser client to connect on port 80 somehow? Is that possible?
To make things simple, I now have a plain index.html page when you connect to http, and I've moved all of the django & mod_wsgi to port 443. If I connect straight to the http address, I get the simple index page, no problem.
When I try to connect to the https address, the browser effectively gets redirected to the index.html page. (I don't have any Redirect or Rewrite commands in Apache though.)
Here is my Apache configuration:
<VirtualHost *:80>
ServerName demo.pasta.co.za
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
DocumentRoot /var/www/http_site
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM
SSLCertificateFile /etc/ssl/private/pasta.co.za.crt
SSLCertificateKeyFile /etc/ssl/private/pasta.co.za.key
SSLCertificateChainFile /etc/ssl/private/root_bundle.crt
ServerName demo.pasta.co.za
Alias /favicon.ico /usr/local/django/pasta/static/favicon.ico
Alias /robots.txt /usr/local/django/pasta/static/robots.txt
AliasMatch ^/([^/]*\.css) /usr/local/django/pasta/store/static/$1
WSGIDaemonProcess demo.pasta.co.za processes=2 threads=25 display-name=%{GROUP}
WSGIProcessGroup demo.pasta.co.za
WSGIScriptAlias / /usr/local/django/pasta/apache/django.wsgi
<Directory /usr/local/django/pasta/apache>
Order allow,deny
Allow from all
</Directory>
Alias /static/admin/ /usr/share/pyshared/django/contrib/admin/static/admin/
Alias /static/images/ /usr/local/django/pasta/store/static/images/
Alias /static/ /usr/local/django/pasta/store/static/
Alias /media/ /usr/local/django/pasta/store/static/
<Directory /usr/local/django/pasta/store/static>
Order deny,allow
Options -Indexes
Allow from all
</Directory>
<Directory /usr/share/pyshared/django/contrib/admin/static/admin>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
And here is my mod_wsgi file:
import os, sys
sys.path.insert (0,"/usr/local/django/pasta/store")
import settings
import django.core.management
django.core.management.setup_environ(settings)
utility = django.core.management.ManagementUtility()
command = utility.fetch_command('runserver')
command.validate()
import django.conf
import django.utils
django.utils.translation.activate(django.conf.settings.LANGUAGE_CODE)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
There are dozens of examples on SO where people accomplish what I'm trying to do with more or less what I have above.
What am I missing? It feels like I've left out something really obvious.
I have Debian stable running django v1.4.5 python v2.7.3 and apache v2.2.22 with mod-wsgi v3.3-4.
Many thanks!

Accepted answer for satchmo nginx redirect to https then to http and back by mipadi ...
Satchmo includes a piece of middleware called satchmo_store.shop.SSLMiddleware.SSLRedirect, which automatically does redirecting to SSL/non-SSL portions of the site. You have to set up URLs to be served via SSL if you want them to be served via SSL, otherwise the middleware redirects to a non-SSL page. From the docs:
This middleware answers the problem of redirecting to (and from) a SSL secured path by stating what paths should be secured in urls.py file. To secure a path, add the additional view_kwarg 'SSL':True to the view_kwargs.
For example
urlpatterns = patterns('some_site.some_app.views',
(r'^test/secure/$','test_secure',{'SSL':True}),
)
All paths where 'SSL':False or where the kwarg of 'SSL' is not specified are routed to an unsecure path.
For example
urlpatterns = patterns('some_site.some_app.views',
(r'^test/unsecure1/$','test_unsecure',{'SSL':False}),
(r'^test/unsecure2/$','test_unsecure'),
)
In your case, since you're serving the entire site via SSL, you can probably just disable that middleware in your settings.py file.
(From my experiance you need to change quite a few urlpatterns in a few files.)

Related

Django Channels over apache server

I have a Django project that's working well on my VPS over apache.
after adding Django channels to my project it's working on localhost perfectly but in my vps, my browser logged an error "WebSocket connection to '...' failed: Error during WebSocket handshake: Unexpected response code: 404" and the project failed.
according to my googling, I think apache can't support web-socket. but can't find a clear answer and trip for running channels on apache
this is my apache config in 000-default.conf:
<VirtualHost *:80>
Alias /static /opt/kalameh/static
<Directory /opt/kalameh/static>
Require all granted
</Directory>
<Directory /opt/kalameh/server>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess kalameh python-path=opt/kalameh python-home=opt/kalameh/kalamehenv
WSGIProcessGroup kalameh
WSGIScriptAlias / opt/kalameh/server/wsgi.py
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
and this is my wsgi.py
import os
import sys
sys.path.append('/opt/kalameh/')
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
application = get_wsgi_application()
You need to check channels' Deploying section. Be aware the slight differences between channels v1.x and v.2x documentation. Pick up the appropriate one.
As you notice, Apache does not support websocket. So you would need to run a server that exposes websocket - a native ASGI interface server (terminology used by channel documentation). You can use Django's Daphne. Daphne also supports HTTP interface.
So you have two solutions:
Keep Apache delivering your Django's HTTP request + Daphne delivering your websocket (if you go for this solution, the keywords to use to find more documentation are reverse proxy and ProxyPass)
Using Daphne for delivering your Websocket and HTTP (no need of Apache).

How to configure apache2 on ubuntu for django restful services

I have django restful services on my ubuntu server which are running on port 84.
When the request is send, it come through the apache2 server which is running on port 80.
Now let say my server ip is "xx.xx.xx.10" and when i call with this url http://xx.xx.xx.10/user where user is the rest service running on django rest framework on port 84. Then the request should go to my django rest service through apache2 and return the desired output.
I tried by using the below configuration in the apache2 :-
<VirtualHost *:80>
WSGIScriptAlias / /myproject/myapp/test/wsgi.py
<Directory "/myproject/myapp/test/">
<Files "wsgi.py">
Require all granted
</Files>
</Directory>
</VirtualHost>
but this is giving internal error saying that test.settings does not exits.
is this the right way to configure the restful services running on different port on apache server.
Did you specify a python path? If you don't, import mysite will not work.
WSGIPythonPath /path/to/mysite.com
For more info see: Django docs modWSGI
I have solved this issued by using the below configurations :-
<VirtualHost *:80>
ServerName mydomain
ServerAlias *.mydomain
ProxyRequests off
ProxyPass / http://localhost:84/
ProxyPassReverse / http://localhost:84/
</VirtualHost>

How to enable SSL support using Apache + Fastcgi + Django?

I have written a Django App and I want to enable SSL(Https) support in my deployment. Currently my web application is properly served on port80. This is my setup
I am using Apache as my web server
FastCGI as reverse proxy to serve my web app
I launch my Django app using the following command
/usr/bin/python manage.py runfcgi daemonize=false method=threaded host=127.0.0.1 port=8080
I edited the Apache httpd.conf file accordingly
<VirtualHost _default_:80>
Alias /static /opt/tms/web3/static
#For every request that *doesn't* start with "static", send it
#to Django via fastcgi. The address and port must match the
#arguments that are later passed to Django.
<LocationMatch "^/(?!static)">
ProxyPass fcgi://127.0.0.1:8080/
</LocationMatch>
</VirtualHost>
<VirtualHost _default_:443>
Alias /static /opt/tms/web3/static
#For every request that *doesn't* start with "static", send it
#to Django via fastcgi. The address and port must match the
#arguments that are later passed to Django.
<LocationMatch "^/(?!static)">
ProxyPass fcgi://127.0.0.1:8080/
</LocationMatch>
LogLevel warn
ErrorLog /var/log/web_error_log
LogFormat combined
CustomLog /var/log/web_access_log combined
SSLEngine on
SSLCertificateFile /var/opt/tms/web/conf/webserver.cert.pem
SSLCertificateKeyFile /var/opt/tms/web/conf/webserver.priv.pem
SSLCertificateChainFile /var/opt/tms/web/conf/webserver_chain.cert.pem
SSLOptions +StdEnvVars
SSLProtocol -all +TLSv1 +TLSv1.1 +TLSv1.2
SSLCipherSuite HIGH:-aNULL:-kKRB5:-MD5
FileETag None
</VirtualHost>
and I get this error when I access with https
Unable to make a secure connection to the server. This may be a problem with
the server, or it may be requiring a client authentication certificate that you don't have.
Error code: ERR_SSL_PROTOCOL_ERROR

Django + mod_wsgi: Can someone advise me on my setup and rewrite rules

This is my first time deploying Django to a recently acquired Linode server and I'm curious if someone can look over my deployment and help me fix some nagging issues and advise me whether i'm doing things incorrectly.
Directory Structure
home\
-public\
-example.com\
-public\
-.htaccess
-index.html
-log\
-application\
-mysite\
-mysite\
-manage.py
-static\
-myapp\
-logs\
How is this for deployment structure for Django?
Incorrect URL Naming
I've hosted the Django application called 'myapp' on my domain 'example.com'. Following the instructions on the Django website I've made it so that the urls.py for the app must begin with '/myapp'. This has resulted in the domain for the app becoming 'example.com/myapp'.
How can I set it so that example.com is simply the Django app I've written?
I'd like to simply navigate to example.com and it load my app instead of example.com/myapp.
Even weirder is that I would've thought that example.com would load my index.html file however it tries to find a URL mapping for Django instead...
Django Log File Writing Permissions
Whenever I SSH onto my machine to either 'syncdb' or 'collectstatic', the logging module creates the log file I've named in my settings.py file. This causes problems for me because I am the owner of the file and apache2 (www-data) cannot write to it. It's just annoying having to manually delete the log file after every command before I restart the apache server.
Here is my /etc/apache2/sites-available/example.com file:
# domain: example.com
# public: /home/setheron/public/example.com/
WSGIPythonPath /home/setheron/public/example.com/applications/mysite:/home/setheron/env/lib/python2.7/site-packages
<VirtualHost *:80>
# Admin email, Server Name (domain name), and any aliases
ServerAdmin setheron#setheron.com
ServerName www.example.example.com
ServerAlias example.com
WSGIScriptAlias / /home/setheron/public/example.com/applications/mysite/mysite/wsgi.py
Alias /static/ /home/setheron/public/example.com/applications/mysite/static/
<Directory /home/setheron/public/example.com/applications/mysite/static/>
Order deny,allow
Allow from all
</Directory>
<Directory /home/setheron/public/example.com/applications/mysite/mysite>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
# Index file and Document Root (where the public files are located)
DirectoryIndex index.html index.php
DocumentRoot /home/setheron/public/example.com/public
# Log file locations
LogLevel warn
ErrorLog /home/setheron/public/example.com/log/error.log
CustomLog /home/setheron/public/example.com/log/access.log combined
</VirtualHost>
If you want Django serving the entire site, get rid of your public directory, indexes and whatnot. Other than /static, you should only need your WSGIScriptAlias directive. Fix the urls.py to say that your site should be coming from /, rather than /myapp.

Django website on Apache with wsgi failing

I have a website I've built in django that I'm trying to get working on our corporate Apache server (on debian) for our intranet at my workplace. Unfortunately, Apache keeps returning server errors whenever I try to navigate to my site. Although I can navigate to the statics folder. My Apache config and wsgi script look like the following...
lbirdf.wsgi
import os
import sys
sys.path.append('/home/lbi/rdfweb/web')
sys.path.append('/home/lbi/rdfweb/web/lbirdf')
os.environ['DJANGO_SETTINGS_MODULE'] = 'lbirdf.settings_production'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Apache config
Listen 8080
<VirtualHost *:8080>
ServerName server1
WSGIScriptAlias /rdfweb /home/lbi/rdfweb/web/lbirdf/apache/lbirdf.wsgi
Alias /statics /home/lbi/rdfweb/web/lbirdf/statics
Alias /admin_media /home/lbi/rdfweb/web/lbirdf/admin_media
<Directory /home/lbi/rdfweb/web/lbirdf/apache>
Order allow,deny
Allow from all
</Directory>
<Directory /home/lbi/rdfweb/web/lbirdf/admin_media>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Any ideas on where I might be going wrong?
What messages are in the Apache error log? Try setting DEBUG to true in Django settings file to get more informative error message sent back to browser in instance that it is an issue in your application.
Possible causes are, urls.py is wrong because you are erroneously including site prefix when you don't need to or a permissions issue because code running as Apache user and not you.
Not knowing the actual errors doesn't help in working out the problem.
Try:
sys.path.append('/home/lbi/rdfweb/')