Nginx+daphne WebSocket connect doesn't receive - django

I use nginx as reverse proxy for daphne to use django channels.
Here's my nginx.conf
server {
listen 80;
server_name <ip_addr>;
location / {
proxy_pass http://0.0.0.0:8001;
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;
}
}
in daphne's log:
2017-07-17 08:45:35,011 DEBUG WebSocket daphne.response.xxx open and established
2017-07-17 08:45:35,011 DEBUG WebSocket daphne.response.xxx accepted by application
but WebSocket's connect in client side doesn't receive any message
Can you help me?
UPDATE:
client-side code (I use Starscream library for WebSocket connection in Swift):
socket = WebSocket(url: URL(string: "ws://site/proxy?token="+token!)!)
func websocketDidConnect(socket: WebSocket) {
print("websocket is connected")
}
socket.connect()
routing.py:
channel_routing = [
route("websocket.receive", 'project.consumers.ws_message'),
route("websocket.connect", 'project.consumers.ws_connect'),
]
consumers.py:
#rest_token_user
def ws_connect(message):
message.reply_channel.send({"accept": True})
res_user from: https://gist.github.com/leonardoo/9574251b3c7eefccd84fc38905110ce4

Related

Channels django nginx 502

I ran into a problem once I install and add "channels" to the settings and after that to the asgi file. Server crashes, I get 502 and nginx won't start. How can I add these channels and start working already
ASGI_APPLICATION = "mysite.asgi.application"
application = ProtocolTypeRouter({
"http": get_asgi_application(),
# Just HTTP for now. (We can add other protocols later.)
# WebSocket chat handler
"websocket": AuthMiddlewareStack(
URLRouter([
])
),
})
help, I'm sure a lot of people have come across this, thanks
Did you configure Nginx properly? Below is a sample Nginx config.
upstream channels-backend {
server localhost:8000;
}
...
server {
...
location / {
try_files $uri #proxy_to_app;
}
...
location #proxy_to_app {
proxy_pass http://channels-backend;
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;
}
...
}
See the deployment guide here: https://channels.readthedocs.io/en/latest/deploying.html

How to get GraphQL schema of a subscription from Spring Boot backend in AWS Elastic Beanstalk

For testing, I added Playground into the project.
In http://localhost:5000/playground case, everything is OK and connected to the Spring Boot backend and listening to notifications
Now, in Elastic Beanstalk, I cannot fetch subscription schema. (notifications)
To make the wss, I added these 2 lines to .platform\nginx\conf.d\https.conf
([according to this url]
enter link description here
graphql subscription Could not connect to websocket endpoint at elastic beanstalk)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
so the result is
# .platform\nginx\conf.d\https.conf
server {
listen 443;
server_name localhost;
ssl on;
ssl_certificate /etc/letsencrypt/live/XXXXXX.us-east-1.elasticbeanstalk.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/XXXXXX.us-east-1.elasticbeanstalk.com/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Upgrade $http_upgrade; // HERE
proxy_set_header Connection "upgrade"; // And HERE
proxy_http_version 1.1;
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 https;
}
}
# .platform\nginx\conf.d\elasticbeanstalk\00_application.conf
location / {
if ($http_x_forwarded_proto = "http") {
set $redirect "https";
}
if ($http_x_forwarded_proto = "ws") {
set $redirect "wss";
}
if ($http_user_agent ~* "ELB-HealthChecker") {
set $redirect "nope";
}
if ($redirect = "https") {
return 301 https://$host$request_uri;
}
if ($redirect = "wss") {
return 301 wss://$host$request_uri;
}
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
How do I have to set files in .platform\nginx\conf.d to handle this issue?

Nginx websocket proxy

I'm trying to use nginx to proxy websocket requests using a regularexpression as follows:
server {
listen 9092;
server_name ~^(?<pc_name>.*)\.(.*)$;
location / {
include proxy_params;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://$pc_name:9092;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
and it's not working like that, i'm getting errors about not being able to resolve the host if i try to access pc-addr.localhost:9092 i get the error:
2017/08/07 08:42:37 [error] 22021#22021: *2 no resolver defined to resolve pc-addr, client: 127.0.0.1, server: ~^(?<pc_name>.*)\.(.*)$, request: "GET / HTTP/1.1", host: "pc-addr.localhost:9092"
However, if I replace the variable name with with pc-addr directly (i.e. all requests will be forwarded to pc-add:9092) it works fine and the requests are proxied as expected
server {
listen 9092;
server_name ~^(?<pc_name>.*)\.(.*)$;
location / {
include proxy_params;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://pc-addr:9092;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

Nginx reverse proxy configuration for AWS web console

Is there a way to access AWS web console via nginx reverse proxy through my subdomain?
Here is the nginx configuration is have been using :
server {
listen localhost:443 ssl;
server_name aws1.subdomain.com;
include snippets/proxy_ssl.conf;
location / {
proxy_pass https://console.aws.amazon.com/;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_hide_header X-Frame-Options;
}
}
The above configuration throws:
NetworkError: 400 Bad Request
And shows amazon's default 400 bad request page when i try to access https://aws1.subdomain.com in my browser.
I have this working using the following lines in nginx.conf. You can also add lines for http auth as required depending on your config.
location = / { rewrite ^ /_plugin/kibana/ redirect; }
location / {
proxy_pass https://<es-domain-url>.es.amazonaws.com;
proxy_http_version 1.1;
proxy_set_header Authorization "";
proxy_hide_header Authorization;
proxy_set_header X-Forwarded-Proto $scheme;
}

Nginx Share Cookies Between Subdomains without Access to Backend

TLDR: How to share cookies between subdomains for a backend application sever that I cannot "configure" using nginx (1.8.x) as a proxy - some magical combination of proxy_*?
A tornado web server is running on "127.0.0.1:9999/ipython" that I cannot configure (it's running as part of an ipython notebook server). I'm using nginx to proxy from "www.mysite.com" to 127.0.0.1:9999 successfully (http traffic at least).
However, part of the backend application requires Websockets. Because I am using CloudFlare, I have to use a separate domain for Websockets ("Websockets are currently only available for Enterprise customers ... All other customers ... should create a subdomain for Websockets in their CloudFlare DNS and disable the CloudFlare proxy"). I'm using "ws.mysite.com".
When a user logs in at "https :// www.mysite.com", a cookie is set by the tornado web server for "www.mysite.com" (I can't seem to configure it, otherwise I would just set it to ".mysite.com"). When the websocket part of the application kicks in, it sends a request to "wss :// ws.mysite.com", but fails to authenticate because the cookie is set for a different domain("www.mysite.com").
Is it possible for nginx to "spoof" the domain so the tornado webserver registers it for ".mysite.com"? proxy_cookie_domain doesn't seem to work as I'd expect... Should I hard code "proxy_set_header Host"?
I was thinking a nginx conf similar to....
upstream ipython_server {
server 127.0.0.1:8888;
}
server {
listen 443;
server_name www.mysite.com;
ssl_certificate cert.crt;
ssl_certificate_key cert.key;
ssl on;
# **** THIS DOESN'T WORK ??? ****
proxy_cookie_domain www.mysite.com .mysite.com;
location /ipython/static {
proxy_pass https://ipython_server$request_uri;
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 /ipython/api/sessions {
proxy_pass https://ipython_server$request_uri;
proxy_set_header Host $host;
proxy_set_header Origin "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ipython {
proxy_pass https://ipython_server$request_uri;
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 / {
try_files $uri $uri/ =404;
}
}
server {
listen 443;
server_name ws.azampagl.com;
ssl_certificate cert.crt;
ssl_certificate_key cert.key;
ssl on;
# **** THIS DOESN'T WORK ??? ****
proxy_cookie_domain ws.mysite.com .mysite.com;
# This is the websocket location
location /ipython/api/kernels/ {
proxy_pass https://ipython_server$request_uri;
proxy_redirect off;
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_read_timeout 86400;
proxy_set_header Host $host;
proxy_set_header Origin "";
proxy_set_header Upgrade websocket;
proxy_set_header Connection "upgrade";
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;
}
}
I've been looking in the nginx lua module? It looks like you can set cookie domains, but it looks hackish...
Thanks greatly in advance for your assistance!
(Side note: I do technically have access to the tornado configuration, but there is zero documentation on how to set the "cookie domain" for the server. i.e.
c.NotebookApp.tornado_settings = {'cookie_domain????':'.mysite.com'}
)