I used the websocket protokoll for a period of time and didn't have any problem with that. But now I installed nginx and ssl on my server and cannot connect to that. My setup is quasar (VueJs), Node Js,Nginx, Ubuntu 18.4.
My nginx config:
server {
server_name mySite.mySiteCountry;
location = /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_pass http://localhost:4510;
}
location / {
proxy_set_header Host $host;
proxy_pass http://localhost:81;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/...; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/...; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
My nodejs server:
const app = express();
app.use(cors(corsOptionsDelegate));
app.use(headerSetter);
const sslPort = dev ? 4041 : 4510;
let serverForWs = app.listen(sslPort);
const WebSocket = require("ws");
const wss = new WebSocket.Server({
noServer: true,
clientTracking: true,
});
wss.on("connection", function connection(ws, request) {
...
If I try to connect without ssl to the 4510 port (ws://mySite.mySiteCountry:4510) its working. If I try through the nginx proxy (wss://mySite.mySiteCountry/ws | ws://mySite.mySiteCountry/ws) its not. What am I doing wrong?
Thanks in advance!
Edit:
I get this error from client. The backend doesn't recieve anything. As I see, the request reaches the nginx, but I don't know what happens after that.
Related
const https = require(`https`);
const fs = require(`fs`);
const options = {
key: fs.readFileSync(...),
cert: fs.readFileSync(...)
};
https.createServer(options, app).listen(8000);
My node js server looks like this.
does it mean I have to configure nginx like this?
location / {
proxy_pass https://localhost:8000/;
}
Not, proxy_pass to http://localhost:8000/
what makes me confused is that I think network inside the server does'n need ssl.
https server on application server also needs ssl configuration on nginx, right?
I also tried app.listen instead of https.createServer.
My node js app and nginx configuration looks like this.
app.listen(4416);
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
root /root/app;
index template.html;
ssl_certificate ...;
ssl_certificate_key ...;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
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 $scheme;
proxy_pass http://localhost:4416/;
proxy_buffering off;
proxy_read_timeout 90;
#websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server{
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
return 404;
}
In this case, redirection keeps incurred, and I don't know the reason why. What did I miss?
If I did https.createServer(SSL_OPTION, app).listen(4416) instead of app.listen(4416), it doesn't have a connection at all. And if I fix nginx configuration proxy_pass to https://localhost:4416;, then it works well. Things are done well but, I wonder why this is happening.
We have recently configured https for our backend server and are now running into some issues with socket. It seems that the sockets sort of work but it doesn't seem to transfer data between devices as intended. The socket is on port 3000 and instead of configuring SSL certification with sockets I just proxy_passed HTTPS requests to localhost port 3000. My suspicion is that it is linked to my nginx config any ideas where I might be going wrong?
server {
server_name app.domain.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_pass http://localhost:3000;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/app.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/app.domain.com/privkey.pem; # managed by Certbot
}
This was working when testing out the app. When i switched the DNS over to the server and then added SSL cert, signalR stopped working (my chat). I presume it's to do with the proxy now redirecting to port 443. The rest of the website works, just not its' chat functionality.
Firefox can’t establish a connection to the server at wss://www.my-website.com/chatHub?id=qDsSrV-APYXpnyk_EfsrXw. signalr.min.js:16:110126
Uncaught (in promise) Error: Server returned handshake error: Handshake was canceled.
and the config in nginx:
server {
server_name www.my-website.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.my-website.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.my-website.com/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 = www.my-website.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.my-website.com;
return 404; # managed by Certbot
}
Any help on getting signalR working again would be greatly appreciated, thanks.
So, turns out that when Certbot edited the config, it added an extra unncessary }. and that's all that was breaking it. The config was broken and was serving a cached state. So i was viewing the website via https:// but was trying to make a websocket connection on port 80, and was failing because it was unsecure.
I have a websocket server (node.js) which runs fine on localhost and on a previous heroku deployment. I am now migrating to google compute engine and running into some issues.
The websocket handshake is failing returning a 301 error. As pointed out in this answer this can be due to the request going through front end servers that do not support a websocket connection and can be worked around by targeting ws://my_external_gce_ip directly. I am wondering if there is some load balancing configuration I can update so that I can address my backend using the custom domain name.
While I understand the problem, it seems to me that the domain should be resolved to the external ip after a dns lookup so I don't understand the constraint really.
Sorry if this is very obvious. I'm new to GCE and have been googling all day trying to get this. I will paste my code below as well as the NGINX config but I don't think either are particularly helpful as all works fine addressing using the IP
index.js:
/* requirements */
var bodyParser = require("body-parser");
const WebSocket = require("ws");
const http = require("http");
const express = require("express");
const port = process.env.PORT || 3000;
/*
server definition and config
*/
const app = express();
app.use(bodyParser.json());
const server = http.createServer(app);
/*
web socket stuff
*/
const webSocketServer = new WebSocket.Server({
server,
});
webSocketServer.on("connection", (webSocket) => {
console.log("board trying to connect...");
webSocket.on("message", (data) => {
webSocketServer.clients.forEach((client) => {
if (client === webSocket && client.readyState === WebSocket.OPEN) {
client.send("[SERVER MESSAGE]: You are connected to the server :)");
}
});
});
});
/*
activate server
*/
server.listen(port, () => {
console.log(`Server is now running on port ${port}\n`);
});
nginx config
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location \ {
# we're actually going to proxy all requests to
# a Nodejs backend
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# I added this baby in
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server
{
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name my_domain; # managed by Certbot
location / {
# we're actually going to proxy all requests to
# a Nodejs backend
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/my_domain/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/my_domain/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 = my_domain) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name my_domain;
return 404; # managed by Certbot
}
Thanks very much in advance and sorry if this is a noob question. Total noob when it comes to load balancing
Solved. After a lot more googling I found this thread of people facing the same problem most either using apache servers or elastic beanstalk so not using nginx.
It seems that a lot of people get websockets to "work" using socket.io but they don't really have a duplex connection as it is falling back to long polling.
In my case the answer was simple, I didn't include the server name in my nginx (facepalm) and I may have forgot to include a header. The https forwarding now looks like this (and addressing using my domain works)
location / {
# we're actually going to proxy all requests to
# a Nodejs backend
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_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;
proxy_read_timeout 90;
}
Don't forget to restart your nginx after you update
sudo systemctl restart nginx
I have a problem with socket.io. When I start my Nodejs App Sockets works correctly but after few minutes the connection to websocket is closed and after reconnecting Socket.io fires emit again.
I'm using NGINX Proxy and I have noticed that bypassing NGINX the problem is solved, which configuration I need to edit? I think that the problem is my nginx configuration.
This is my NGINX default config:
server {
listen 80; #listen for all the HTTP requests
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri; }
server {
server_name example.com;
listen 443 ssl http2;
#Optimize Webserver work
#client_max_body_size 16M;
keepalive_timeout 20;
ssl on;
ssl_certificate /root/social/ssl/cert.pem;
ssl_certificate_key /root/social/ssl/key.pem;
location / {
proxy_pass http://localhost:5430;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
upstream io_nodes {
server 127.0.0.1:5430;
keepalive 20;
}
Please help
You should add another parameter:
proxy_read_timeout 96000;
The default value is 60s. You will get a message "lost connect" after 60s idles with the default value.