Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client disconnects if idle and server is behind Nginx #35

Open
zorchenhimer opened this issue Mar 16, 2019 · 12 comments · Fixed by #182
Open

Client disconnects if idle and server is behind Nginx #35

zorchenhimer opened this issue Mar 16, 2019 · 12 comments · Fixed by #182
Assignees
Labels
bug Something isn't working hardening Changes that are not new features, but benefit the developer

Comments

@zorchenhimer
Copy link
Owner

The chat client will disconnect if it is behind an Nginx reverse-proxy if no messages are sent within about a minute.

The client should send a PING to the server to keep the connection alive. The server needs to read the PING from the client, but I don't think it needs to respond with a PONG to keep the connection open.

@zorchenhimer zorchenhimer added bug Something isn't working hardening Changes that are not new features, but benefit the developer labels Mar 16, 2019
@zorchenhimer zorchenhimer self-assigned this Mar 16, 2019
@MrAureliusR
Copy link

I've just set MovieNight up behind nginx, and I'm having this issue. Is there a particular nginx option or header that needs to be added?

@zorglube
Copy link
Contributor

zorglube commented Mar 27, 2022

Here is my Nginx conf, may you find something useful..

map $remote_addr $proxy_forwarded_elem {
	# IPv4 addresses can be sent as-is
	~^[0-9.]+$			"for=$remote_addr";
	
	# IPv6 addresses need to be bracketed and quoted
	~^[0-9A-Fa-f:.]+$	"for=\"[$remote_addr]\"";
	
	# Unix domain socket names cannot be represented in RFC 7239 syntax
	default				"for=unknown";
}

map $http_forwarded $proxy_add_forwarded {
	# If the incoming Forwarded header is syntactically valid, append to it
	"~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$"	"$http_forwarded, $proxy_forwarded_elem";

	# Otherwise, replace it
	default				"$proxy_forwarded_elem";
}

map $http_upgrade $connection_upgrade {
		default	upgrade;
		''		close;
}

server {
	listen 						80;

	server_name					[my domain].[tld];
	access_log 					/var/log/nginx/movienight.access.log;
	error_log 					/var/log/nginx/movienight.error.log;

	set 	$upstream 	xxx.xxx.xxx.xxx:8089;

	# Movie Night
	location / {
		proxy_pass			http://$upstream;
		proxy_http_version 		1.1;
		
		proxy_set_header		Host $host;
		proxy_set_header		X-Real-IP $remote_addr;
		proxy_set_header		Upgrade $http_upgrade;
		proxy_set_header		Connection $connection_upgrade;
		proxy_set_header		X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header		Forwarded "$proxy_add_forwarded;proto=$scheme";
		
		proxy_redirect			off;
		proxy_next_upstream	error timeout invalid_header http_500 http_404;
		proxy_connect_timeout	2;
		proxy_intercept_errors	on;
	}

	# Movie Night Chat Websoket forward 
	location /ws {
		proxy_pass			http://$upstream;
		proxy_http_version		1.1;
		proxy_set_header		Host $host;
		proxy_set_header		Upgrade $http_upgrade;
		proxy_set_header		Connection $connection_upgrade;
		proxy_set_header		X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header		Forwarded "$proxy_add_forwarded;proto=$scheme";
	}

	error_page 500 502 503 504 /error.html;
	location /error.html {
		return 				200 "<!DOCTYPE html><html><head><title>Movie Night</title></head><body style=\"background-color:black;\"><h1 style=\"color:grey;\">Server is down</h1></body></html>";
	}
}

@zorchenhimer
Copy link
Owner Author

@MrAureliusR Do you have any log output? Can you post your Nginx config (remove IP addresses if necessary)?

@zorchenhimer zorchenhimer reopened this Mar 27, 2022
@MrAureliusR
Copy link

MrAureliusR commented Mar 27, 2022

Here's what I came up with for the nginx config. I couldn't see anything in the readme about MovieNight requiring anything special, so I started off with just proxy_pass and then added a few other bits and pieces I've used when proxying other applications. The MovieNight log doesn't show anything when this happens -- it just shows the user leaving the chat.

After some more experimenting last night, I ended up adding

		proxy_connect_timeout 1d;
		proxy_send_timeout 1d;
		proxy_read_timeout 1d;

and that has fixed the issue, but that's kind of an ugly way to solve it.

server {
	server_name removed;

	location / {
		proxy_pass http://localhost:8089/;
		proxy_set_header Host $host;
		proxy_set_header Upgrade $http_upgrade;
		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-Forwarded-Proto $scheme;

		add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
		add_header Referrer-Policy "same-origin";

		access_log /var/log/nginx/movienight.access.log;
		error_log /var/log/nginx/movienight.error.log;
	}

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/removed/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/removed/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = removed) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


	server_name removed;

	listen 80;
    return 404; # managed by Certbot


}

@zorchenhimer
Copy link
Owner Author

zorchenhimer commented Mar 27, 2022

Hmm, the only real differences I have from your config are that I separated out websocket connections into their own block and set the proxy_http_version to 1.1 in the websocket block:

location / {
        proxy_pass http://movienight;
}

location /ws {
        proxy_pass http://movienight;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Do you have anything in your Nginx logs?

@MrAureliusR
Copy link

MrAureliusR commented Mar 28, 2022 via email

@joeyak
Copy link
Collaborator

joeyak commented Mar 28, 2022

I think what happened was in the removal of wasm I forgot to convert this line over to the javascript, so now there's nothing to keep the websocket connection open
80be381#diff-1a75e4f727f20d549964a1872e088c634844e0b3aa68233bf822ab6a125ffe87R264

@joeyak
Copy link
Collaborator

joeyak commented Mar 28, 2022

Turns out nginx times out websocket connections at 60 seconds http://nginx.org/en/docs/http/websocket.html

@joeyak
Copy link
Collaborator

joeyak commented Mar 28, 2022

@MrAureliusR I worked with someone else to check the fix in PR #182. I'm pretty sure this is solved we can reopen the issue if you still have it

@joeyak
Copy link
Collaborator

joeyak commented Mar 28, 2022

Or not, seems like they didn't change the nginx config back to the original setup that broke it

@joeyak joeyak reopened this Mar 28, 2022
@MrAureliusR
Copy link

MrAureliusR commented Mar 28, 2022 via email

@CptPie
Copy link

CptPie commented Mar 28, 2022

Mine is set up as a docker container. If there's a docker image I can pull and test quickly I'd be happy to do so.

I am not 100% certain on this one but you SHOULD be able to just git pull and then restart the container (maybe rebuild the container to be save).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working hardening Changes that are not new features, but benefit the developer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants