This is actually not a duplicated question. Please read.
I’m trying to connect my subdomain (node-ssl.example.com
) to my ubuntu server to obtain a secure SSL websocket connection (wss://node-ssl.example.con
)
So i have configured my simplest nodejs websocket application with Nginx and SSL (issued by letsencrypt via certbot).
Whenever i try to open a connection to my app, i get a 502 error. Since i have configured access_log
and error_log
directives for nginx, here is the log of those files:
# /var/log/nginx/domains/node-ssl/access:
xx.xxx.xx.xx - - [06/Jun/2024:02:40:07 +0330] "GET / HTTP/1.1" 502 166 "-" "Apidog/1.0.0 (https://apidog.com)"
# /var/log/nginx/domains/node-ssl/error:
2024/06/06 02:40:07 [error] 30289#30289: *37 upstream prematurely closed connection while reading response header from upstream, client: xx.xxx.xx.xx, server: node-ssl.example.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:6007/", host: "node-ssl.example.com"
My certificate is available at this location:
- fullchain: /etc/letsencrypt/live/example.com/fullchain.pem
- fullchain: /etc/letsencrypt/live/example.com/privkey.pem
My Nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
if ($host = www.example.com) {
return 301 https://$host$request_uri;
}
if ($host = example.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 443 ssl;
server_name node-ssl.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
error_log /var/log/nginx/domains/node-ssl/error;
access_log /var/log/nginx/domains/node-ssl/access;
location / {
proxy_pass http://127.0.0.1:6007;
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_redirect off;
}
}
My nodejs program:
const express = require('express');
const https = require('https');
const fs = require('fs');
const WebSocket = require('ws');
const app = express();
const server = https.createServer({
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem'),
keepAliveTimeout: 6000000
}, app);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
console.log('A client connected.');
ws.on('message', function incoming(message) {
console.log('Received:', message);
ws.send(`Your message was: ${message}`);
});
});
server.listen(6007, function() {
console.log('WebSocket server listening on port 6007');
});
systemctl service (for when i was trying to run nodejs with systemctl):
# /etc/systemd/system/node-ssl.service
[Unit]
Description=WebSocket Server
[Service]
ExecStart=/home/me/.nvm/versions/node/v18.20.3/bin/node /var/www/example.com/jws/index.js
Restart=always
User=root
Group=root
WorkingDirectory=/var/www/example.com/jws/
[Install]
WantedBy=multi-user.target
supervisor service (for when i was trying to run nodejs with supervisor instead of systemctl):
# /etc/supervisor/conf.d
[program:jws]
directory=/var/www/example.com/jws/
command=/home/me/.nvm/versions/node/v18.20.3/bin/node /var/www/example.com/jws/index.js
autostart=true
autorestart=true
stderr_logfile=/var/log/nginx/domains/jws/err.log
stdout_logfile=/var/log/nginx/domains/jws/out.log
More details:
-
My server configuration:
- OS: Ubuntu 22.04.4 LTS
- Mem: 8G
- CPUs: 2
-
I have generated my certificated with this command:
sudo certbot --nginx -d example.com -d www.example.com
- I have opened the port
6007
withufw
command:
sudo ufw allow 6007
What i tried so far:
It’s actually about 5 days im struggling with it, searching the web and asking AIs
-
As you see in the logs, I used APIDog to establish the connection. But i also tried to use wscat, piehost, new WebSocket(…)
-
In my nodejs program, i also tried to pass the second parameter to
fs.readFileSync
asutf8
. -
In my nodejs program, i used
console.log
to log the result offs.readFileSync
methods, Both are reading the.pem
files correctly. -
My nodejs program is now running on port
6007
. But i also tried from6001
to6008
-
I also have a laravel websocket application, I get the same result from that as well.
-
I also tried to configure nginx to proxy requests from a subdirectory (
wss://example.com/ws
) instead ofwss://node-ssl.example.com
subdomain. -
I also used Supervisor instead of a systemctl servers.
-
I tried to start my application with
root
user usingnode index.js
command.
I can confirm these:
- The
6007
port is open (sudo ufw allow 6007
) - My certificate is not expired (It’s working on other subdomains, and the main domain)
- My CDN provider is not proxying requests
- If i remove SSL specific configurations from Nginx config and my nodejs program, the program works correctly without any issue. (I could access to my ssl-freed program with
ws://node-ssl.example.com
) - The program is correctly running (tested with systemctl and supervisor)