I'm facing an issue with peerjs on nginx. The same code works fine on localhost, but doesn't work when I host it on a production sereverv via Nginx. Following the code below, two peers can connect to and regcognize eachother, but can't communicate when I try to send an image over.
I have added some comments in the frontend code, where I suspect the error. Can anyone help me please? Thanks :)
Here is the backend code:
const fs = require('fs');
const express = require('express');
const { ExpressPeerServer } = require('peer');
const app = express();
app.get('/', (req, res, next) => res.send('Hello world!'));
const sslOptions = {
key: fs.readFileSync('/etc/letsencrypt/live/<server_URL>/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/<server_URL>/fullchain.pem')
}
const server = app.listen(5000);
const peerServer = ExpressPeerServer(server, {
path: '/myApp',
debug: true,
proxied: true,
ssl: sslOptions
});
app.use('/peerjs', peerServer);
Frontend:
const peerConfig = {
secure: true,
host: '<server_URL>',
path: '/peerjs/myApp',
debug: 3
}
const peer = new Peer('any_ID_1', peerConfig);
console.log(peer) // this works fine and the object has "_open:true"
const conn = peer.connect('any_ID_2');
console.log(conn) // however, the object here returns "_open:false"
Nginx conf:
server{
server_name <server_URL>;
root /var/www/backend;
location / {
proxy_pass http://localhost:5000;
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/<server_URL>/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/<server_URL>/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
}
Related
I'm trying to pass through all the directories in my app through to express, and in some cases directories that contain a dynamic 'key' which I'll :capture.
I can't get even a defined sub-directory, /pretest, to pass through to express. Despite copying the the same options for Location /, it serves me an Ngxin 404
Ideally, I want domain.com/prepop/{lookup_key} to pass to localhost:8080/prepop/{lookup_key}
Where {lookup_key} is a different value each time
Any ideas what I'm doing wrong here? Any/all help is much appreciated.
Code-
server.js
const path = require('path');
const express = require("express");
const mysql = require('mysql2');
const cors = require("cors")
const port = process.env.PORT || 8080;
const app = express();
app.use(cors())
app.get('/', (req, res) => {
res.send('hello');
});
app.get('/pretest', (req, res) => {
res.send('test');
});
app.get('/prepop/:lookup_key', (req, res) => {
let connection = mysql.createConnection({
//commented out for stackoverflow
});
connection.connect();
connection.query('SELECT * FROM table_incoming_leads WHERE leadid = '+req.params.send_key, (err, response, fields) => {
if (err) console.log(err);
res.json({
email: response[0].email,
first_name: response[0].first_name,
last_name: response[0].last_name
})
});
connection.end();
})
app.listen(port, () => console.log(`Server listening on port ${port}`));
/etc/nginx/sites-available/default
server {
root /var/www/html;
location / {
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;
try_files $uri $uri/ =404;
}
location /pretest {
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;
try_files $uri $uri/ =404;
}
location /prepop {
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;
try_files $uri $uri/ =404;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/subdomain.mydomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/subdomain.mydomain.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 = subdomain.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name subdomain.mydomain.com;
return 404; # managed by Certbot
}
You need to remove try_files directive from /prepop location because when nginx receives a request for let's say /prepop/somekey it looks for a file with that name (somekey) in your root directory. Since there is no such file it returns 404.
I have adapted a tutorial to get a simple Socket.io chat going in Node. It works when hosted locally, but after pushing it to a test server I can't get the socket connection to be accepted. Seems to be a cross-origin related matter, though I'm slightly confused about how to route things in Nginx also. Following the advice in the related questions hasn't helped.
Client script:
var socket = io.connect('http://localhost/socket.io');
Index.js:
const express = require('express');
const app = express();
const path = require('path');
const httpServer = require('http').createServer(app);
const io = require('socket.io')(httpServer, {
cors:true,
origins:["*"],
// origins:["http://xxx.xxx.xxx.xxx:8080"],
// transports: ['websocket'],
});
const views_path = (__dirname + '/views');
app.set('views',views_path);
app.use(express.static(__dirname + '/public'));
app.get('/', function(req,res){
console.log('render request received');
res.render('startPage.ejs');
});
io.sockets.on('connection', socket => {
console.log('connection received.')
socket.on('username', function(username) {
socket.username = username;
io.emit('is_online', socket.username);
});
//...
});
httpServer.listen(8080);
nginx sites-available:
server {
server_name campfire;
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/campfire/html;
index index.html index.htm index.nginx-debian.html;
location ^~ /assets/ {
gzip_static on;
expires 12h;
add_header Cache-Control public;
}
location / {
proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8080;
}
location /socket.io/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
proxy_http_version 1.1;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:8080/socket.io/;
}
}
Any insights welcome!
Hope this will help with all the CORS error
Because it will handle it for you
const cors = require('cors');
app.use(cors());
Docs CORS
Making this change fixed the issue:
Client script: var socket = io.connect();
This way uses the default connection destination with socket.
I'm trying to connect to my Nodejs server by Nginx.
my server runs on port 3000 and my Nodejs client successfully connects to the server using https://example.com:3000, while https://example.com/socket.io returns:
{"code":0,"message":"Transport unknown"}
I used certbot for SSL certification and it configured my nginx.conf
this is Nginx .conf file for my socket.io server:
upstream nodesocket {
server 127.0.0.1:3000;
}
server {
listen 443 ssl;
server_name example.com www.example.com;
access_log /var/log/nginx/access-ssl.log;
error_log /var/log/nginx/error-ssl.log;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
keepalive_timeout 60;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
large_client_header_buffers 8 32k;
location /socket.io/ {
proxy_pass https://nodesocket;
proxy_redirect off;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
and this is my socket io server:
const express = require('express')
const https = require('https')
const socketIo = require('socket.io')
var fs = require('fs')
var options = {
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem'),
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/example.com/chain.pem')
}
var app = express();
var server = https.createServer(options, app);
var io = socketIo(server);
server.listen(3000, function(){
console.log('listening on :3000');
});
I checked nodejs and nginx logs but there were no related logs and no error.
I had the exact same issue and this worked for me
I deleted proxy_http_version 1.1;
and here is my nginx.conf
location /socket.io/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:3000/socket.io/;
}
I have managed to setup HTTPS using Nginx on a Node server at localhost:4000 by placing the cert and key paths in the Nginx conf file, however, I would also like to understand how to embed the ssl certificate inside the node index.js file and just pass the proxy'd address to the localhost:4000 with the certs inside the application rather than the nginx.conf file.
This nginx.conf file will work correctly with https/ssl once node isn't being served as ssl.
server {
listen 4500 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
access_log /var/log/nginx/example.com.access.log;
location / {
proxy_pass http://localhost:4000;
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;
}
}
However, if I comment out the following nginx.conf
# ssl_certificate /etc/letsencrypt/live/api.ballers.ie/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/api.ballers.ie/privkey.pem;
And then add the certs to my node server as follows, it tells me that the site can't be reached.
// ...
// dependencies & config
// ...
const privateKey = fs.readFileSync('/etc/letsencrypt/live/example.com.privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/example.com.cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/example.com.chain.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate,
ca,
};
const httpsServer = https.createServer(credentials, app);
app.get('*', (req, res) => {
res.send('I am a HTTPS endpoint !');
});
httpsServer.listen(4000);
I have also tried changing proxy_pass to proxy_pass https://localhost:4000;
I'd be very interested to understand how to make this work, thanks for your assistance.
I am currently trying to set up nginx virtual server blocks, which I have me absolutely ripping my hair out.
Essentially, I have a NodeJS instance running on a droplet at DigitalOcean. The point of this application, is to host both a website as well as an api. I want both of these to run on the same droplet.
I have set up my NodeJS app with express to create the routing and so on, and then create an http server with the express app. As my explanation might cause confusion, I have included the essentials of the code below:
const API_PORT = 8080;
const WEB_PORT = 8081;
const api = express();
const web = express();
web.use(express.static(path.join(__dirname, '../build')));
web.get('//', (req, res) => {
res.sendFile(path.join(__dirname, '../build', 'index.html'));
})
api.use((req, res, next) => {
const ip = (req. headers['x-forwarded-for'] || '').split(',').pop()
|| req.connection.remoteAddress
|| req.socket.remoteAddress
|| req.connection.socket.remoteAddress
if (req.headers.auth !== AUTHCODE) {
httpError(400, 'Validation failed');
console.warn('Bad Auth Code');
console.warn(req.headers.auth);
console.warn(ip);
return (res.json('Validation failed'));
}
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
next();
});
Graph.route(api);
const apiServer = http.createServer(api);
const webServer = http.createServer(web);
apiServer.listen(WEB_PORT, '127.0.0.1', () => {
console.log(`API Server is running on port ${API_PORT}`);
});
webServer.listen(API_PORT, '127.0.0.1', () => {
console.log(`WEB Server is running on port ${WEB_PORT}`);
});
What I want to achieve is shown in the code above, but essentially I am trying to have a my api server listening to port 8080, and my website server to listen on port 8081.
I was told that I could use nginx to create a proxy_pass for this although I have not managed to make it work as intended. Below you see two examples of what I tried to do !
Anyone able to help me out would forever be my hero !
server {
listen lace.guide:443 ssl;
server_name lace.guide www.lace.guide;
ssl_certificate /var/my-server/ssl/myapp.crt;
ssl_certificate_key /var/my-server/ssl/myapp.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_pass http://127.0.0.1:8080/$request_uri;
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;
}
}
server {
listen api.lace.guide:443 ssl default_server;
server_name api.lace.guide www.api.lace.guide;
ssl_certificate /var/my-server/ssl/myapp.crt;
ssl_certificate_key /var/my-server/ssl/myapp.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_pass http://127.0.0.1:8081/$request_uri;
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 am also having another quite peculiar error which means that if I access my api.lace.url/something/somethingElse it actually hits //something/somethingElse on my server (console.log from req.url)
Here is an example of how server and client live on one server and are being managed with nginx (ssl setup omitted for simplicity). All request prefixed with /api get routed to the server and the rest - to the client.
upstream client {
server client:3000;
}
upstream api {
server api:5000;
}
server {
listen 80;
location / {
proxy_pass http://client;
}
location /api {
proxy_set_header X-Forwarded-For $remote_addr;
rewrite /api/(.*) /$1 break;
proxy_pass http://api;
}
}