14

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.

Lauren
  • 281
  • 2
  • 7

4 Answers4

1

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.

arthursribeiro
  • 326
  • 3
  • 9
  • Hi sir, Don't you have any issue about code changes, and if you restart the supervisor the server is still not updated? – Shift 'n Tab Aug 29 '20 at 19:29
  • It happened that I forgot to update in the server `DEBUG=True` mode then immediately set it to `False`. After a couple of supervisor/ngix restart the django app is still in debug mode. :/ – Shift 'n Tab Aug 29 '20 at 19:32
  • @Roel I'm afraid I didn't understand your issue here, basically when I do changes to my Django code and want to redeploy it I restart supervisor, nginx and uwsgi to have them reflected there, hope this helps you. – arthursribeiro Aug 31 '20 at 18:29
  • My apologies, It happened that the supervisor is not reading the .env so it defaulted to the development settings instead of production that is why I'm still getting a debug mode site. – Shift 'n Tab Aug 31 '20 at 19:54
0

your nginx expects a wss request not a ws request.

doubleo46
  • 475
  • 4
  • 12
0

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;
}
CumaTekin
  • 63
  • 1
  • 7
  • How do you run Daphe as a service? Systemd? Supervisor? I'd love to see that config file too – mrj Mar 24 '20 at 19:45
  • [Unit] Description=Daphne Web Server After=network.target [Service] PIDFile=/run/daphne/pid User=root Group=www-data WorkingDirectory=/home/django ExecStart=/home/django/venv/bin/daphne -e ssl:8443:privateKey=/home/django/ssl/my_website.key:certKey=/home/django/ssl/my_website.com.chained.crt mysite.asgi:application ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID Restart=on-abort PrivateTmp=true [Install] WantedBy=multi-user.target – CumaTekin Aug 06 '22 at 16:14
0
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;
}
CumaTekin
  • 63
  • 1
  • 7