0

I've got a GKE private k8s cluster with nginx and a django application running with wsgi and asgi. Logs from nginx show that websocket requests get a 403, and the logs on the daphne pod are showing "access denied" type errors. I've also got a cluster running the same application, but not within a VPC where these websockets are working as expected.

I've no issue with nginx traffic passing through to the react app powered by a django api over wsgi. But this service includes some "chat" functionality which relies on a pod running a daphne server for websockets and django-channels providing the application integration.

The cluster is managed with helm, including the nginx config and the daphne pod. Here's the key parts of the nginx config;

    server {
        listen 80;
        server_name {{ range .domains }}{{ .host }} {{ end -}};
        root /usr/src/app/;

        if ($http_x_forwarded_proto != "https") {
            return 301 https://$host$request_uri;
        }

        location / {
          try_files $uri /index.html;
          add_header X-Frame-Options "SAMEORIGIN";
        }

        location ^~ /api/ {
            proxy_pass                          http://draft-appserver:8000/;
            proxy_redirect                      default;
            proxy_set_header Host               $host;
            proxy_set_header X-Forwarded-Proto  https;
        }
        location ^~ /ws/ {
            proxy_pass                          http://draft-daphne:8301;
            proxy_redirect                      default;
            proxy_http_version                  1.1;
            proxy_set_header                    Upgrade $http_upgrade;
            proxy_set_header                    Connection "upgrade";
            proxy_set_header Host               $host;
            proxy_set_header X-Forwarded-Proto  https;
        }
    }

The daphne server runs with the following command;

  command: [
    "wait-for-it.sh", "{{ .Values.redis_server }}:6379", "-t", "60", "--",
    "wait-for-it.sh", "localhost:3306", "-t", "60", "--",
    "daphne",
      "-b", "0.0.0.0",
      "-v", "2",
      "-p", "8301",
      "myapp.asgi:application"
  ]

The server logs from nginx then look like this;

[24/May/2023:21:40:16 +0000] "GET /ws/1-1 HTTP/1.1" 403 5 "-" "Mozilla/5.0

And the daphne pod;

2023-05-24 21:40:19,433 daphne.server INFO failing WebSocket opening handshake ('Access denied')
2023-05-24 21:40:19,433 daphne.server WARNING dropping connection to peer tcp4:10.254.0.118:34828 with abort=False: Access denied

10.254.0.118 here is the IP of the nginx pod.

The ASGI side of django is setup as follows;

asgi.py

django_asgi_app = get_asgi_application()

from core import routing as core_routing

application = ProtocolTypeRouter(
    {
        "http": django_asgi_app,
        "websocket": AllowedHostsOriginValidator(
            AuthMiddlewareStack(URLRouter(core_routing.websocket_urlpatterns))
        ),
    }
)

I have ran this application without AllowedHostsOriginValidator to verify it's not an issue with the host validation.

And those URL patterns;

websocket_urlpatterns = [
    re_path(
        r"^ws/(?P<league_id>[0-9]+)-(?P<entry_id>[0-9]+)",
        consumers.MyConsumer.as_asgi(),
    )
]

1 Answer 1

1

This was a simple case of overlooking the django settings.

Although I had updated the ALLOWED_HOSTS for django, the SESSION_COOKIE_DOMAIN hadn't been updated to account for two domains being used by a single settings file.

The 403 seen in the nginx logs was being thrown in django-channels by AuthMiddlewareStack which performs checks on the session

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .