Django Channels wss not connecting received 404 Error - django

I am attempting to move my server off my local subnet and to a domain. The main webpages are working and I have them behind an SSL. Apache does a rewrite of the url from any HTTP connection to an HTTPS. However when I attempt to connect with javascript from in browser with:
new WebSocket("wss://" + window.location.host);
I receive the following error:
WebSocket connection to 'wss://{MY_WEBSITE}.com/message_route/' failed: Error during WebSocket handshake: Unexpected response code: 404
My config for the settings.py is as follows:
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"ROUTING": "my_app.routing.channel_routing",
"Config": {
"hosts": [os.environ.get('REDIS_URL', 'redis://127.0.0.0:6379')],
}
},
EDIT (ADDED IN APACHE CONFIG DATA):
My Apache default.conf is the following (simple re-write to HTTPS):
<VirtualHost *:80>
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
</VirtualHost>
Apache secure.conf:
<VirtualHost *:443>
ServerName my_domain.com
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/ssl/my_domain/my_domain.crt
SSLCertificateKeyFile /etc/ssl/my_domain/myserver.key
SSLCACertificateFile /etc/ssl/my_domain/my_domain.ca-bundle
Alias /static /home/user/my_app/myApp/static_files
<Directory /home/user/my_app/myApp/static_files>
Require all granted
</Directory>
<Directory /home/user/my_app/myApp/MyApp>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess MyApp python-path=/home/user/my_app/myApp/MyApp
WSGIProcessGroup MyApp
WSGIScriptAlias / /home/user/my_app/myApp/MyApp/MyApp/wsgi.py
</VirtualHost>
EDIT Found out apache is receiving request but not doing anything
I tailed other_vhosts.access.log and found that when I created a new websocket in chromes console, apache logs that a GET request, but does not seem to forward it to my django app.
I also have a worker running, a redis server set up, and daphne running as well. Please let me know if you can think of any possible solutions to this problem

Related

Posting http request after enabeling TLS/SSL

I have a website using Angular for the frontend, Django for the backend and they are being served using Apache.
It was working properly until I enabled TLS/SSL using letsencrypt.
Since then I was still able to access the website using https, but all my http request to the backend give errors.
The error message is:
Http failure response for http://backend.IP:8080/api/load_data/: 0 Unknown Error
If I call the API function from the browser like this:
http://backend.IP:8080/api/load_data/
It works well and returns the expected data from the backend, but when posting http request from the code it gives the previous error.
Here is apache configurations for the frontend.conf:
<VirtualHost *:80>
DocumentRoot "/home/ubuntu/myproject/static/"
# Other directives here
DirectoryIndex index.php index.htm index.html
<Directory "/home/ubuntu/myproject/static">
AllowOverride All
Require all granted
</Directory>
# Logs
ErrorLog /var/log/apache2/frontend_error.log
CustomLog /var/log/apache2/frontend_access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =test.myproject.org
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Here is the frontend-le-ssl.conf:
<IfModule mod_ssl.c>
SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)
<VirtualHost *:443>
DocumentRoot "/home/ubuntu/myproject/static/"
# Other directives here
DirectoryIndex index.php index.htm index.html
<Directory "/home/ubuntu/myproject/static">
AllowOverride All
Require all granted
</Directory>
# Logs
ErrorLog /var/log/apache2/frontend_error.log
CustomLog /var/log/apache2/frontend_access.log combined
ServerName test.myproject.org
SSLCertificateFile /etc/letsencrypt/live/test.myproject.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/test.myproject.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
Header always set Strict-Transport-Security "max-age=31536000"
SSLUseStapling on
Header always set Content-Security-Policy upgrade-insecure-requests
</VirtualHost>
</IfModule>
Here is the 000-default.conf:
<VirtualHost *:8080>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /static /home/ubuntu/myproject/static
<Directory /home/ubuntu/myproject/static>
Require all granted
</Directory>
<Directory /home/ubuntu/myproject/myproject >
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess myproject python-home=/home/ubuntu/myproject/venv python-path=/home/ubuntu/myproject
WSGIProcessGroup myproject
WSGIScriptAlias / /home/ubuntu/myproject/myproject/wsgi.py
</VirtualHost>
Angular environment.prod.ts:
export const environment = {
appVersion: require('../../package.json').version,
production: true,
apiURL: 'http://backend.IP:8080/api/',
mediaURL: 'http://backend.IP:8080',
};
Angular proxy.conf.json:
{
"/api": {
"target": "http://backend.IP:80",
"secure": false
},
"/media": {
"target": "http://backend.IP:80",
"secure": false
}
}
Backend settings.py:
SESSION_COOKIE_SECURE=True
SESSION_COOKIE_HTTPONLY=True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
ALLOWED_HOSTS = ['backend.IP',
'http://backend.IP',
'http://backend.IP:8080',
'https://backend.IP',
'https://backend.IP:8080',
'127.0.0.1',
'http://www.mproject.org/',
'https://www.mproject.org/',
'mproject.org/']
CORS_ORIGIN_WHITELIST = (
'https://localhost:4200',
'https://localhost:8000',
'https://localhost:8080',
'https://backend.IP:8080',
'http://backend.IP:8080',
'https://backend.IP:80',
'http://backend.IP:80',
)
CORS_ALLOW_CREDENTIALS = True
In the wsgi.py:
os.environ['HTTPS'] = "on"
I am completely new to these stuffs, and I followed several tutorials to reach this point but I am still missing something to allow the http requests after the setting the STL/SSL up.

How to deploy django channels with Apache and Daphne?

I am trying to deploy this django app which uses channels. I use Apache for regular HTTP requests and want to forward the web socket requests to Daphne.
Here are some of my important files:
apache config:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]
Alias /static /home/anna/tchan/static
<Directory /home/anna/tchan/static>
Require all granted
</Directory>
Alias /media /home/anna/tchan/media
<Directory /home/anna/tchan/media>
Require all granted
</Directory>
<Directory /home/anna/tchan/tchan>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/anna/tchan/tchan/wsgi.py
WSGIDaemonProcess django_app python-path=/home/anna/tchan python-home=/home/anna/tchan/venv
WSGIProcessGroup django_app
</VirtualHost>
Last few lines of settings.py:
ASGI_APPLICATION = 'tchan.routing.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 8001)],
},
},
}
asgi.py
import os
import django
from channels.routing import get_default_application
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tchan.settings')
django.setup()
application = get_default_application()
With these in place, I run daphne -p 8001 tchan.asgi:application and then sudo service apache2 reload.
Finally, when testing the websocket in my page here's what happens:
websocket.js:4 WebSocket connection to 'ws://192.168.0.57/ws/chat/8/' failed: Error during WebSocket handshake: Unexpected response code: 403
This error 403 happens whether or not I'm running daphne.
What am I doing wrong here?
Note: the app works as expected when using Django's development server and docker for the channel layer, the problem is with my Apache config, I think.
I figured it out. To enable apache to redirect, we need to:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
One of these was not enabled which caused the 403 Forbidden.

Django showing 500 Internal Server Error on HTTPS

I am getting the following error in error.log in apache2 directory : Segmentation fault (11), possible coredump in /etc/apache2.
I have the following configuration in my example-instance.conf :
ErrorDocument 404 "/error-pages/404.html"
ErrorDocument 500 "/error-pages/500.html"
ErrorDocument 403 "/error-pages/403.html"
# Change the following three lines for your server
ServerName example.app
SetEnv HTTP_HOST "example.app"
ServerAdmin admin#example.app
SetEnv LC_TIME "en_GB.UTF-8"
SetEnv LANG "en_US.UTF-8"
SSLEngine on
SSLCertificateFile "path/to/certificate"
SSLCertificateChainFile "path/to/certificate"
SSLCertificateKeyFile "path/to/private_key"
WSGIScriptAlias /app "path/to/wsgi_prod.py"
# Comment next 2 lines if using older Apache than v2.4
WSGIApplicationGroup %{GLOBAL}
WSGIDaemonProcess instance1_wsgi python-path="__PATH_TO_ENV_SITE-PACKAGES_FOLDER__"
WSGIProcessGroup instance1_wsgi
# Comment 'Require all granted' for older Apache than v2.4
<Location "/">
Require all granted
Options FollowSymLinks
</Location>
Alias /static/ "path/to/static/"
Alias /app/static/ "path/to/static/"
<Directory "path/to/static/">
Require all granted
Options -Indexes
</Directory>
Alias /data/ "path/to/data/"
<Directory "path/to/data/">
Require all granted
Options -Indexes
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example-instance-error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/example-instance-access.log combined
The site worked perfectly fine on http however on configuring it for https, I am getting 500 Internal Server Error on '/app' subdirectory where my Django app lies. The landing page of the site is perfectly fine, which indicates that https is working.
I have this same problem :/ Only option for now was to turn off mod_ssl and get back to port 80 in config file.
Strange is that i have Debug = True in settings.py but when app crashes i receive only error 500 page from apache.
Turns out pip install psycopg2-binary did the trick!

Deploy django-channels with Apache2 and Daphne

I'm trying to learn to use django-channels and have worked through both the tutorial and this multichat example. I am now trying to deploy it on a Digital Ocean droplet using Apache and Daphne. I would happily use Daphne by itself but I do not understand how to.
So this is my Apache conf file:
<VirtualHost *:80>
ServerAdmin webmaster#mysite.co.uk
ServerName multichat.mysite.co.uk
ServerAlias www.multichat.mysite.co.uk
DocumentRoot /var/www/multichat
WSGIDaemonProcess multichat python-path=/var/www/multichat python-home=/var/www/multichat/env
WSGIProcessGroup multichat
WSGIScriptAlias / /var/www/multichat/multichat/wsgi.py
Alias /robots.txt /var/www/multichat/static/robots.txt
Alias /favicon.ico /var/www/multichat/static/favicon.ico
Alias /media/ /var/www/multichat/media/
Alias /static/ /var/www/multichat/static/
<Directory /var/www/multichat/static>
Require all granted
</Directory>
<Directory /var/www/multichat/media>
Require all granted
</Directory>
WSGIScriptAlias / /var/www/multichat/multichat/wsgi.py
<Directory /var/www/multichat/multichat>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
I've installed Redis and have it up and running.
I've included this file in /etc/systemd/system/daphne.service
[Unit]
Description=daphne daemon for multichat
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/var/www/multichat/multichat
ExecStart=/var/www/multichat/env/bin/daphne -b 0.0.0.0 -p 8001 multichat.asgi:application
# Not sure if should use 'on-failure' or 'always'.
Restart=on-failure
[Install]
WantedBy=multi-user.target
Although the webpage comes up and I can login etc, when it comes to a chatroom I have the following error in console:
WebSocket connection to 'ws://multichat.mysite.co.uk/chat/stream/'
failed: Error during WebSocket handshake: Unexpected response code:
404
I'm clearly not setting up something correctly but I don't know where to turn. I would happily scrape Apache if I can get a pointer on how to use just Daphne, but I've tried and got nowhere with that either
You've configured Apache to serve Django content using WSGI protocol, but WSGI doesn't support web sockets. That is why Daphne is here. It doesn't use WSGI to serve Django content, so you can use it with web sockets.
To use Daphne instead, you should remove WSGI settings from apache file and put ProxyPass instead, which should point to your daphne server. The proper line should look like this:
<Location />
ProxyPass http://127.0.0.1:8001/
</Location>
As your daphne server is running on the same server, but on port 8001.
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]
<Location />
ProxyPass http://127.0.0.1:8001/
</Location>
#And load the next modules in the main file config:
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_module modules/mod_proxy.so
#remove WSGI settings

Django Based framework virtual host setup https on Apache

I am using a django based framework and have successfully figured Apache settings for http mode. Basically I have done the setting correctly on <VirtualHost *:80> ... </VirtualHost> and when I do, http://mysite.domain.com I get routed correctly to my site and the site pages and the skins get render correctly.
I have setup https://mysite.domain.com to work with shibboleth, shibboleth is working and when use the https I get routed to login credential page via shibboleth server, and after successful login I get redirect to https://mysite.domain.com but site doesn't get rendered correctly and skins don't show up as same as http://mysite.domain.com.
Here is my Apache settings, I am trying to understand what I am doing wrong here
<VirtualHost *:443>
ServerAdmin myname#mydomain.com
DocumentRoot /code/vEnviornment/mysite
ServerName mydomain.com
#<LocationMatch "^(?!/admin)">
#<LocationMatch "^(?!/m)">
# RewriteEngine on
# RewriteRule django.wsgi(.*)$ https://mydomain.com:443$1 [L,R=301]
#</LocationMatch>
SSLEngine on
#your SSL keys
#I have removed this wasn't comfortable putting SSL key info
#Alias /admin/media/ /usr/local/lib/python2.6/site-packages/django/contrib/admin/media/
Alias /admin/media/ /usr/local/lib/python2.7/dist-packages/django/contrib/admin/media/
WSGIScriptAlias /m/ /code/vEnviornment/mysite/django.wsgi
<Directory "/">
AuthType shibboleth
ShibRequestSetting requireSession 1
Require valid-user
</Directory>
Alias /Shibboleth.sso /tmp
# CustomLog /var/log/httpd/mysite/access_log common
# ErrorLog /var/log/httpd/mysite/error_log
CustomLog /var/log/apache2/mysite/access_log common
ErrorLog /var/log/apache2/mysite/error_log
</VirtualHost>
And here is how I have hetup http:
<VirtualHost *:80>
ServerAdmin myname#mydomain.com
DocumentRoot /code/vEnviornment/mysite
ServerName mysite.mydomain.com
#aliases to serve static media directly
#will probably need adjustment
Alias /m/ /code/vEnviornment/mysite/static/
Alias /upfiles/ /code/vEnviornment/mysite/myframework/upfiles/
<DirectoryMatch "/code/vEnviornment/mysite/myframework/skins/([^/]+)/media">
Order deny,allow
Allow from all
</DirectoryMatch>
<Directory "/code/vEnviornment/mysite/myframework/upfiles">
Order deny,allow
Allow from all
</Directory>
#must be a distinct name within your apache configuration
WSGIDaemonProcess mysite2
WSGIProcessGroup mysite2
WSGIScriptAlias / /code/vEnviornment/mysite/django.wsgi
#make all admin stuff except media go through secure connection
<LocationMatch "/admin(?!/media)">
RewriteEngine on
RewriteRule /admin(.*)$ https://128.101.35.71/admin$1 [L,R=301]
</LocationMatch>
# CustomLog /var/log/httpd/mysite/access_log common
# ErrorLog /var/log/httpd/mysite/error_log
CustomLog /var/log/apache2/mysite/access_log common
ErrorLog /var/log/apache2/mysite/error_log
LogLevel debug
</VirtualHost>
What am I doing wrong here to render the site incorrectly via https?
Alias /m/ /code/vEnviornment/mysite/static/
Alias /upfiles/ /code/vEnviornment/mysite/myframework/upfiles/
These two lines are missing in https virual host
and
your WSGIScriptAlias should point to / not /m/