Deploying Django Channels with Daphne + NGINX using SSL - python

I had a working configuration of nginx proxying to an upstream daphne server for django channels. However, when I moved my site to ssl, I started running into issues 403 errors with the websocket requests. This is from my error log:
None - - [24/Apr/2017:02:43:36] "WSCONNECTING /pulse_events" - -
None - - [24/Apr/2017:02:43:36] "WSREJECT /pulse_events" - -
2017/04/24 02:43:37 [info] 465#465: *10 client 69.203.115.135 closed keepalive
connection
And from the access log:
- - [24/Apr/2017:02:48:54 +0000] "GET /pulse_events HTTP/1.1" 403 5 "-" "-"
- - [24/Apr/2017:02:49:03 +0000] "GET /pulse_state/ HTTP/2.0" 200 1376 "-" "Pulse/1 CFNetwork/811.4.18 Darwin/16.1.0"
My nginx config is as follows:
upstream pulse_web_server {
server unix:/home/pulseweb/run/gunicorn.sock fail_timeout=0;
}
upstream pulse_web_sockets {
server unix:/home/pulseweb/run/daphne.sock;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name backend.com;
return 301 https://$host$request_uri;
}
server {
listen 443 http2 ssl;
server_name backend.com;
root /var/www/vhosts/backend.com;
location ~ /.well-known {
allow all;
}
include snippets/ssl-params.conf;
ssl_certificate /etc/letsencrypt/live/backend.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/backend.com/privkey.pem;
client_max_body_size 4G;
access_log /var/log/nginx/pulse-access.log;
error_log /var/log/nginx/pulse-error.log info;
location /static/ {
alias /var/www/vhosts/backend.com/static/;
}
location /pulse_events {
proxy_pass http://pulse_web_sockets;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
server_tokens off;
proxy_buffering on;
if (!-f $request_filename) {
proxy_pass http://pulse_web_server;
break;
}
}
}
This is my requirements.txt:
asgi-redis==0.14.0
asgiref==0.14.0
asyncio==3.4.3
autobahn==0.16.0
channels==0.17.2
daphne==0.14.3
Django==1.10
django-extensions==1.7.2
django-webpack-loader==0.3.3
djangorestframework==3.4.4
msgpack-python==0.4.8
python-dateutil==2.5.3
redis==2.10.5
requests==2.11.0
six==1.10.0
Twisted==16.2.0
txaio==2.5.1
zope.interface==4.2.0
Any insight would be greatly appreciated.

I do have a working configuration for Django+Daphne+nginx+ssl without any issues, I run daphne via supervisor with the following config file:
[program:project]
directory=<project_directory>
command=daphne -u <path_to_socket>/daphne.sock --root-path=<project_directory> <project>.asgi:channel_layer
stdout_logfile = <log_path>
stderr_logfile= <error_log_path>
[program:project_asgi_workers]
command=python <project_directory>/manage.py runworker
stdout_logfile=<log_file_path_2>
stderr_logfile=<log_error_path_2>
process_name=asgi_worker%(process_num)s
numprocs=2
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8 ; Set UTF-8 as default encoding
autostart=true
autorestart=true
redirect_stderr=true
stopasgroup=true
To stop and start these workers I run the commands:
sudo supervisorctl stop all
sudo supervisorctl start all
Inside nginx I have the following configuration to connect to my websockets:
location /pulse_events/ {
proxy_pass http://unix:<path_to_socket>/daphne.sock;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
I used on this project daphne version 1.4.1, asgi-redis 1.4.3, redis 2.10.6 and channels 1.1.8.
If you still have issues, maybe it's also a good idea to check your routing and consumers for django channels.

your nginx expects a wss request not a ws request.

I use Django + Daphne + Nginx + SSL and here is my nginx mysite.conf. Your conf file is missed for handling /ws request. And ws and wss will be handle with this parameters. Please be sure you have a backend socket server like Daphne(i see you have), and run this server in bash and accept request in 8443(this is important because most servers permit only in this socket). And enjoy it..
location /ws {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:8443;
}

server {
#https
listen 443 ssl;
server_name my_site.com www.my_site.com my_ip;
root /usr/share/nginx/html;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 3000;
fastcgi_send_timeout 3000;
fastcgi_read_timeout 3000;
gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
gzip_disable "MSIE [1-6]\.";
#your SSL configuration
ssl on;
ssl_certificate /home/django/ssl/my_site.com.chained.crt;
ssl_certificate_key /home/django/ssl/my_site.key;
client_max_body_size 4G;
keepalive_timeout 500;
add_header Strict-Transport-Security "max-age=31536000";
include /etc/nginx/default.d/*.conf;
# Your Django project's media files - amend as required
location /media {
alias /home/django/media;
}
# your Django project's static files - amend as required
location /static {
alias /home/django/static;
}
# Proxy the static assests for the Django Admin panel
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://unix:/home/django/mysite.sock;
}
location /ws {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:8443;
}
}
server {
listen 80;
listen [::]:80;
server_name my_site.com www.my_site.com my_ip;
return 301 https://$server_name$request_uri;
}

Related

How to setup Nginx to display a website served by an internal Python server

I'm using Nginx as a reverse proxy for several web services and it works well, however, now I need to redirect the input to this server to display a website.
This web runs on an internal server, localhost:51000, and its main page is localhost:51000/login. The server runs under Python.
I would like to use an arbitrary URI to access this website from any computer but I'm not able to configure Nginx for this purpose. Needless to say, I have followed various examples and instructions found on the web and in the nginx documentation.
For example, using the following configuration:
server {
listen 443 ssl;
server_name myweb.com;
server_tokens off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate ...;
ssl_certificate_key ...;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ...
location / {
root html;
index index.html index.php;
}
location /vis2 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
rewrite ^/vis2(.*) /$1 break;
proxy_pass http://localhost:51000/login;
}
writing myweb.com/vis2 on a web browser the server redirects to https://myweb.com/login, and the result is a 404 code because it expects to find the login file in the root of myweb.com
Instead, if I use this other configuration:
location /vis1 {
rewrite ^/vis1(.*) /$1 break;
proxy_pass http://localhost:51000/login;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-Proto $scheme;
}
writing myweb.com/vis1 on a web browser the server redirects to https://localhost:51000/login, and this is not accessible from outside the server.
I wonder what am I doing wrong or maybe it is not possible. Any advice?
Thanks in advance

What is the correct connection string?

I have a couchbase server behind a NGINX reverse proxy (behind the subpath /db).
How do I specify the correct connection string in Python?
I tried
from couchbase.cluster import Cluster, ClusterOptions
from couchbase.auth import PasswordAuthenticator
cluster = Cluster('couchbase://testserver.com/db', ClusterOptions(
PasswordAuthenticator('Administrator', 'password')))
But I get
ValueError: Cannot pass bucket to connection string: db
Accessing the admin website at https://testserver.com/db/_utils/index.html works.
NGINX configuration:
server {
listen 80;
server_name testserver.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name stagingpos.rsj.de;
ssl_certificate /etc/ssl/xxx.crt;
ssl_certificate_key /etc/ssl/xxx.key;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /db {
rewrite /db/(.*) /$1 break;
proxy_pass http://127.0.0.1:5984/;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
}
location /_session {
proxy_pass http://127.0.0.1:5984/_session;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X_Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded_Ssl on;
}
}

Flask deployment server redirects add server name to address

I configured Nginx as a reverse proxy to a Gunicorn server running on 127.0.0.1:8000.
Nginx configuration is like this:
server {
server_name www.programlama.tk;
rewrite ^ http://programlama.tk/ permanent;
}
server {
listen 80; # listen onport 80
server_name programlama.tk localhost; #requests to this domain or ip
location / {
include proxy_params;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
So far so good. In my flask application when the user authenticates there is a simple method that redirects to the user's home page which is 'ev'. 'Ev' means home.
#app.route('/ev')
def ev():
return render_template('ev.html')
But instead of http://programlama.tk/ev this, it redirects to
http://programlama.tk%2Cprogramlama.tk/ev
this address, which doesn't exist. Also, it adds the server name to the redirect address.
I changed the nginx configuration a bit as described in the documentation.
Now it works as expected.
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

Flask Nginx url_for _external

How does one make the server name replace the localhost when using url_for with _external = True (so: url_for('foobar', _external=True)) under Nginx?
I'm running a flask application.
nginx setting
server {
listen 80;
server_name _;
access_log /var/log/nginx/simplemadetutor.access.log;
error_log /var/log/nginx/simplemadetutor.error.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
alias /home/implemad/www/simplemadetutor/app/static;
}
location /favicon.ico {
alias /home/implemad/www/simplemadetutor/app/static/img/favicon.ico;
}
}
the problem is if i type url_for('main.index', _external=True) instead of seeing something like http://simplemadetutor.com I see http://127.0.0.1:8000/
I have tried setting SERVER_NAME = 'simplemadetutor.com'; however, this seem to put the simplemadetutor.com in front of every url generated by url_for extead of just the ones with external=True.

Connection Refused while deploying sentry server in Nginx

Am using python sentry server for tracking logs of my website.And i have used nginx server to deploy it, my servers IP is xx.xx.xx.xx when i open this in browser it shows me 502 Bad Gateway and when i checked the log it shows
"connect() failed (111: Connection refused) while connecting to upstream".
Below is configuration i have used in NGINX ,
log_format timed_combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe';
server {
listen 80;
server_name xx.xx.xx.xx ;
root /srv/www/name-sentry;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 default ssl;
ssl on;
ssl_certificate /etc/ssl/xx.xx.xx.xx/ssl.crt;
ssl_certificate_key /etc/ssl/xx.xx.xx.xx/ssl.key;
ssl_ciphers '';
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=2592000; includeSubDomains";
keepalive_timeout 0;
# CHANGE ME: long timeout for ERP POST images
proxy_read_timeout 200;
proxy_send_timeout 200;
server_name xx.xx.xx.xx ;
root /srv/www/name-sentry;
access_log /var/log/nginx/name-sentry-access.log timed_combined;
error_log /var/log/nginx/name-sentry-error.log;
error_page 502 /502.html;
error_page 503 /503.html;
error_page 504 /504.html;
try_files $uri #name-sentry;
location / {
proxy_pass http://xx.xx.xx.xx;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header Host $http_host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Protocol https;
#add_header Access-Control-Allow-Origin "*";
#add_header Access-Control-Allow-Credentials "true";
#add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
#add_header X-Backend-Server $hostname;
}
}
NOTE: xx.xx.xx.xx--is my IP.Command to start sentry server is "sentry start" and it works and sentry uses 9000 port.What is the solution of this ?

Categories

Resources