Making Node js apps https secure - node.js

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.

Related

Nodejs, nodemon app crashed (screenshot inside)

don't understand what's wrong with my server and code. I am passing tutorial and did everything just like in the video but still have the problem
Image
It seems like you are using https connection without handling TLS certificates passing.
Here is a code snippet to make you access your openweathermap API without configurating certificates.
const express = require('express')
const https = require('https')
const app = express()
app.get("/", function(req, res) {
const url = "<openweathermap>"
var options = require('url').parse( /**String*/ url );
options.rejectUnauthorized = false;
https.get(options, function(response) {
console.log(response);
}).on( 'error',function ( e ) {
console.log(err);
}).end();
res.send("Sever up and running");
}
app.listen(3000, function(){
console.log("Server running on port 3000";
}
I would suggest to read more on how to setup certificates for HTTPS in Node.JS,
refer this doc. for more details.

HTTPS with NodeJS swagger-express-mw npm package

I am using swagger-express-mw NPM package for creating REST services, when I run the project with "swagger project start" then it publishes the APIs over HTTP, how can I use HTTPS instead.
I have used HTTPS using vanilla npm packages as below:
var fs = require('fs');
var https = require('https');
var app = require('express')();
var options = {
key : fs.readFileSync('my.private.key'),
cert : fs.readFileSync('my.certificate.cer')
};
app.get('/', function (req, res) {
res.send('Yuhooo! Response over HTTPS!!! ');
});
https.createServer(options, app).listen(8443, function () {
console.log('Server started # 8443!');
});
But I am not sure how to achieve the same with swagger-express-mw, Below is the code snippet from my app.js which starts the listener. Not getting any option to use HTTPS as the protocol here
SwaggerExpress.create(configuration, function(err, swaggerExpress) {
if (err) { throw err; }
// install middleware
swaggerExpress.register(app);
var port = config.get('server.port') || process.env.PORT || 8080;
app.listen(port);
console.log('Server started at port %d', port);
});
var swaggerDoc = jsYaml.load(fs.readFileSync('./api/swagger/swagger.yaml'));
// Initialize the Swagger middleware for the api doc purpose
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
// Serve the Swagger documents and Swagger UI
app.use(middleware.swaggerUi());
});
app.listen is simply a shortcut you can use
SwaggerExpress.create(configuration, function(err, swaggerExpress) {
if (err) { throw err; }
// install middleware
swaggerExpress.register(app);
var port = process.env.PORT || 443;
https.createServer(options, app).listen(port, function () {
console.log('Server started # %s!', port);
});
});
Using Swagger 2.0 spec with middleware your swagger configuration file can be set to only accept certain schemes:
# Schemes is statically set here but will be overridden in app.js with
swagger object
schemes:
- https
You can review the specification and go to Fixed Fields: http://swagger.io/specification/

nodejs can't work with SSL

Im trying to run nodejs app to work with my php project. the problem is I think with SSL which is enabled in the server.
I have two files that I found in my root directory after SSL install: domain.com.csr and domain.com.key and I tried to combine them to connection while creating https server, but nothing worked for me.
so far I have this code:
var socket = require('socket.io');
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
var io = socket.listen(server);
app.get('/test', function(req, res) {
res.send('hello world');
console.log('visited test')
});
io.sockets.on('connection', function (client) {
console.log("New client !");
client.on('message', function (data) {
console.log('Message received ' + data.name + ":" + data.message);
io.sockets.emit('message', {name: data.name, message: data.message});
});
});
server.listen(8080, function () {
console.log('listen me on: 8080');
});
and it works well when I'm trying to visit http://ip:8080/test so it means that node server is working, but when I try to create socket connection on my view file var socket = io.connect('http://ip:8080'); it gives me error:
The page at 'https://www.domain.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://ip:8080/socket.io/?EIO=3&transport=polling&t=1446818946199-0'. This request has been blocked; the content must be served over HTTPS.
so the problem is clear enough, but how to deal with it?
also I have tried this connection:
var socket = io.connect('https://www.domain.com:8080');
but the result is 404 GET Error. How to deal with it?
Update
now the part of code I should use, but don't know how to get cert of existing SSL in the server.
var socket = require('socket.io');
var express = require('express');
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('path/to/key.pem'), // dont have
cert: fs.readFileSync('path/to/cert.cert') // dont have
};
var app = express();
var server = https.createServer(options, app);
var io = socket.listen(server);
app.get('/test', function(req, res) {
res.send('hello world');
console.log('visited test')
});
io.sockets.on('connection', function (client) {
console.log("New client !");
client.on('message', function (data) {
console.log('Message received ' + data.name + ":" + data.message);
io.sockets.emit('message', {name: data.name, message: data.message});
});
});
server.listen(443, function () {
console.log('listen me on: 443');
});
I think you need to contact your certificate authority (the organization that issued your first ssl certificate) and get a copy of the certificate (the path/to/key.pem and path/to/cert.cert) or find the existing keys somewhere on your existing server.
If you're running apache, your configuration file will have a section with values for the paths of the .cert and .pem files labeled SSLCertificateFile and SSLCertificateKeyFile, then just update the paths in your node app to point to them. You also have to make sure that your SSL certificate meets the requirements (for example, needs to be Multi-domain if your node app runs on a different domain, or a Wildcard SSL certificate to run your node app on a subdomain).
The domain.com.csr and domain.com.key files you found are the private key and certificate request used to generate your initial SSL certificate and aren't going to do anything to enable SSL on your node app.

Node.JS https server for Webhook gets handshake error

The following NodeJS just handles a webhook coming from another source. I tested it out, it works on http port 80 but the source requires https.
When I opened that port and ran this script on 443, testing it with curl gets the following error. Yet I don't think it should require a certificate should it? How would I even solve this?
curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect
Here is the script:
var http = require('https')
var server = http.createServer(function(req, res) {
if (req.method == "POST") {
var str = ''
req.on('data', function(data) {
str += data
})
req.on('end', function() {
var json = JSON.parse(str)
res.end(json.meta.status)
})
}
})
console.log("HTTPS server listening on port 443...")
server.listen(443)
UPDATE:
Here's the latest code. I created a self-signed cert without a passphrase. I get further but I still get an error using curl with the -k option added. I get a certificate verification error without the -k.
Cannot POST /
var https = require('https')
var fs = require('fs')
var express = require('express');
var options = {
key: fs.readFileSync('./server.key'),
cert: fs.readFileSync('./server.cert')
}
var app = express()
var server = https.createServer(options, app, function(req, res) {
if (req.method == "POST") {
var str = ''
req.on('data', function(data) {
str += data
})
req.on('end', function() {
var json = JSON.parse(str)
res.end(json.meta.status)
})
}
})
console.log("HTTPS server listening on port 443...")
server.listen(443)
HTTPS server config always requires SSL certificate. You can generate it using openssl here is in more details.
Then for node server use crypto,fs modules. Detailed config is here.

Nodejs SSL for SockJS + Express

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;
...
...
}

Resources