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(),
)
]