I've got a simple SockJS and Express server in nodejs. Now id like to add SSL support for these servers.
Here is my server code:
var sockjs = require('sockjs');
var my_http = require("http");
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('test/keys/key.pem'),
cert: fs.readFileSync('test/keys/cert.pem')
};
// Create a service (the app object is just a callback).
var app = express();
// Create an HTTP service.
http.createServer(app).listen(8008);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);
var echo = sockjs.createServer({
log: function (severity, message) {}
});
echo.on('connection', function (conn) {
conn.on('data', function (message) {
conn.write(message);
});
conn.on('close', function () {
});
});
var server = my_http.createServer();
echo.installHandlers(server, {
prefix: '/echo'
});
server.listen(8081, '0.0.0.0');
var server_https = my_http.createServer(options);
echo.installHandlers(server_https, {
prefix: '/echo'
});
server_https.listen(443, '0.0.0.0');
app.get('/type/:channel', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send("Hello");
res.end();
});
Problem is that i get the port already in use error:
Error: listen EADDRINUSE
I've got Nginx listening on 443 otherwise my site would not work on ssl.
Any ideas how to set this up?
Inside of your nginx config you should have your port listed in 'upstream'. In your case you probably have the same port listed under server. It shows that error when you do that. See below for proper configuration (If you change "listen 80" to "listen 8000" you'll see that error):
upstream app_yourAppName {
server 127.0.0.1:8000;
}
# the nginx server instance
server {
listen 80;
...
...
}
Related
I am running my server on ionos hosting and executing nodejs on the default port of 80.
I don't know how to enable the HTTPS for it.
Following is my sample node js server creation code:
const Https = require('https');
const fs = require('fs');
const httpsServer = Https.createServer({
key: fs.readFileSync("private.key"),
cert: fs.readFileSync("Dev-2020-09-12-013930.cer")
}, app);
var io = require('socket.io').listen(Https);
global.SOCKET = io;
const ip = require('ip');
console.log('websocket server start.' + ' ipaddress = ' + ip.address() );
// const socket = io('http://localhost:5000');
httpsServer.listen(80, function () {
console.log('Server port: ' + port);
});
I have generated certificates and added them. On running the server it gives message of server started but does not load on browser.
Try adding these lines of code and see if you get "Hello" text in your browser.
https.get("/", (req, res) => {
res.send("Hello");
});
if that didn't work try doing it this way
httpsServer.get("/", (req, res) => {
res.send("Hello");
});
EDIT
Check out the official documentation https://nodejs.org/api/https.html
I am creating a chaincode project , in which nodejs is consuming the chaincoe smartcontract.
My project structure includes index.js - swagger specs , app.js - to consumer swagger specs and bin/www - where http specification is defined .
I have defined http with basic auth and it works fine. For making all the services https secure , I have downloaded open ssl in my linux machine and have generated the certificate and the private key. (https://www.linuxhelp.com/how-to-install-and-update-openssl-on-ubuntu-16-04/)
I have made changes in the bin/www.js for the https part :
#!/usr/bin/env node
var app = require('../app');
var fs = require('fs');
var http = require('http');
var https = require('https');
require("dotenv").config();
var privateKey = fs.readFileSync('key.pem').toString();
var certificate = fs.readFileSync('cert.pem').toString();
var port = normalizePort(process.env.PORT || '8080');
app.set('port', port);
var hostname = process.env.HOSTNAME;
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
https.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World!');
res.end();
}).listen(8080);
but this is not working . I have also imported the certificate and key in the mozilla. Request all to kindly help on this.
Thanks in advance.
You need to add the key and cert to the createServer function.
const options = {
key: fs.readFileSync('key.pem').toString();
cert: fs.readFileSync('cert.pem').toString();
}
https
.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
})
.listen(443, function(){
console.log("Server listening on localhost:443");
});
Now, as #aditi said in the comments, the callback in createServer is a request handler. That means it will trigger when there is a request event. A request event is triggered by mostly HTTP requesting the server. So, if you open localhost:443 it will show you the "hello world" text.
If you want to console log something when the server is started (listing) you need to add the callback in the listen function. Which you have done.
it worked ,
I used
https.createServer(httpsOptions,app)
.listen(port,function(){
console.log("Inside HTTPS creation");
})
Thanks all.
I am using nginx with my ssl certificates and it's giving me the https version of my site which is great. The problem is my socket.io communications don't work unless i use a regular http connection. I apologize if this is a bit long, but i'm not sure what i'm doing here and wanted to make sure you guys had everything you might need to know. I have tried the solutions of various different sites some of which were on here, but none of them worked.
I tried manually creating the https server instead of letting express do it but that resulted in nothing loading at all, with the current implementation i can at least see the site.
upstream project {
server example.org:4000;
}
server {
listen 80;
return https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /home/adam/SSL/public.crt;
ssl_certificate_key /home/adam/SSL/example.org.key;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://example.org;
}
}
That seems to be working as when i go to my site, it automatically takes me to the https version and the page is loaded. The issue is when is when the client side tries to connect i keep getting:
"https://MY_SERVER_IP:4040/socket.io/?EIO=3&transport=polling&t=M0CPjUDnet::ERR_CONNECTION_CLOSED"
printed to the console
Here's my client and server code:
var IPaddress = 'https://MY_SERVER_IP:4040';
var socket = io.connect(IPaddress,{secure:true});
socket.on('connect', function (socket) {
console.log('Connected!');
});
server code:
var express = require('express');
var app = express();
var privateKey = fs.readFileSync(__dirname+'/SSL/example.com.key','utf8');
var certificate = fs.readFileSync(__dirname+'/SSL/public.crt','utf8');
var intermediate = fs.readFileSync(__dirname+'/SSL/intermediate.crt','utf8');
var options = {key:privateKey,cert:certificate,ca:intermediate};
var io = require('socket.io').listen(4040,options);
//var io = require('socket.io').listen(4040);
io.sockets.on('connection', function (socket) {
socket.on('disconnect',function(){
console.log("A client has left us :(");
});
});
app.listen(4000);
Update - 02/12/2017
In my code i have this line:
require('./routes.js')(app);
which contains:
module.exports = function(app) {
app.get('/main',function(req,res){
if (req.session.user == null){
// if user is not logged-in redirect back to login page //
res.redirect('/');
} else{
res.sendFile(path.join(__dirname + '/FrontEnd/main.html'));
}
});
// viewed at http://localhost:8080
app.get('/', function(req, res) {
if(req.cookies.user == undefined || req.cookies.pass == undefined){
res.sendFile(path.join(__dirname + '/FrontEnd/login.html'));
}else {
//attempt automatic login
AM.autoLogin(req.cookies.user,req.cookies.pass,function(o){
if(o !=null){
req.session.user = o;
res.sendFile(path.join(__dirname + '/FrontEnd/home.html'));
}else{
res.sendFile(path.join(__dirname + '/FrontEnd/login.html'));
}
});
}
});
......
Could this be causing the 502 bad gateway error?
Expanding on my comment, in your current server code, both express and socket.io are only accepting regular HTTP connections. The socket.io listen(port[, options]) function does not accept HTTPS connections.
You started on the right approach with manually creating an HTTPS server. You then need to attach express and socket.io to that server.
var fs = require('fs');
var express = require('express');
var app = express();
var privateKey = fs.readFileSync(__dirname + '/SSL/example.com.key', 'utf8');
var certificate = fs.readFileSync(__dirname + '/SSL/public.crt', 'utf8');
var intermediate = fs.readFileSync(__dirname+'/SSL/intermediate.crt', 'utf8');
var options = { key: privateKey, cert: certificate, ca: intermediate };
// Create our HTTPS server here and attach express to it
var server = require('https').createServer(options, app);
// Attach socket.io to our existing HTTPS server
var io = require('socket.io')(server);
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function() {
console.log("A client has left us :(");
});
});
server.listen(4000);
I want to run nodejs & socket.io server in google compute engine with https / SSL.
I installed self-signed certificate from https://cloud.google.com/compute/docs/load-balancing/http/ssl-certificates.
Now, How Do I enable nodejs server to use https protocol?
Thanks,
Below is the code, which I used for HTTPS in nodejs,
var app = require('express')();
var https = require('https');
var fs = require('fs');
var PORT = 443;
var options = {
key: fs.readFileSync('XYZ.key'),
cert: fs.readFileSync('ABC.crt')
};
var server = https.createServer(options, app).listen(PORT, function () {
console.log("Express listening on port " + PORT);
});
// Post request.
var req_res = function (req, res) {
console.log("[200] " + req.url);
var fullBody = '';
// Read post data.
req.on('data', function (chunk) {
fullBody += chunk.toString();
if (fullBody.length > 1e6) {
// FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
req.connection.destroy();
}
});
// Send response.
req.on('end', function () {
// empty 200 OK response for now
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
'success': true
}));
});
};
// Hello World
app.get('/*', function (req, res) {
res.status(200).send('Hello World...');
});
// Post request to receive notifications.
app.post('/post', req_res);
Regarding google compute engine, you just need to enable 443 port from firewall.
gcloud compute firewall-rules create allow-https --description "https server" --allow tcp:443 --format json
You need a number of things to configure a nodeJS server to use HTTPs. I would suggest Nginx (http://nginx.org/en/docs/http/configuring_https_servers.html) to set up https port 443 connections to terminate at the nginx layer. Then proxy all these connections using the proxy_pass directive in Nginx to your NodeJS server. You could use the upstream directive in Nginx as well.
You would have to do this in a non-https set up as well, since nodeJS should not be listening on the default 80 port as it is a system port, and nodeJS won't allow you to start the process unless you run as sudo (again not recommended).
I'm a newbie to node-http-proxy module.
my aim
I need to use the module provide multi-SSL for multi-subdomain.
For example;
if a user call process.localhost:1443 then I should route the call to process.localhost:2443 and
if a user call api.localhost:1443 then I should route the call to api.localhost:3443
what's happening
I wrote the below server.js codes. However when I try to call process.localhost:1443 I get the following error;
D:\Work Space\...\http-proxy\node_modules\requires-port\index.js:13
protocol = protocol.split(':')[0];
TypeError: Cannot call method 'split' of undefined
protocol seems as undefined.
function required(port, protocol) {
protocol = protocol.split(':')[0];
What should I do?
server.js
var fs = require('fs'),
httpProxy = require('http-proxy'),
express = require('express'),
app = require('./app').service,
api = require('./api').service;
// PROXY
var options = {
changeOrigin: true,
forward: {
'process.localhost': 'process.localhost:2443',
'api.localhost' : 'api.localhost:3443'
}
}
httpProxy.createServer(options).listen(1443, function() {
console.log('Proxy is listening on port 1443')
})
// HTTP
app
.listen(2443, function() {
console.log('PROCESS APP server is listening on port 2443')
})
api
.listen(3443, function() {
console.log('API APP server is listening on port 3443')
})
I could solve this issue through someone from node-http-proxy forum.
var proxyTable = {}
proxyTable['api.localhost:1443'] = 'http://127.0.0.1:3443'
proxyTable['process.localhost:1443'] = 'http://127.0.0.1:2443'
var proxy = httpProxy.createServer({changeOrigin: true})
var http = require('http')
http.createServer(function(req, res) {
var options = {
target: proxyTable[req.headers.host]
}
proxy.web(req, res, options)
}).listen(1443, function() {
console.log('Proxy server is listening on port 1443')
})
app.listen(2443, function() {
console.log('APP server is listening on port 2443')
})
api.listen(3443, function() {
console.log('API server is listening on port 3443')
})