node http-proxy and HTTPS - node.js

I am having issues getting https working with node http-proxy.
I've created a server using node http-server
forever /usr/local/lib/node_modules/http-server/bin/http-server /home/blah/public_html/ -p 5000 -S -C /myencrypt/blah.com/cert.pem -K /myencrypt/blah.com/privkey.pem
If I go to https://blah.com:5000 the Certs are working correctly.
If I go to blah.com I get the following error
Error: unable to verify the first certificate
at TLSSocket.<anonymous> (_tls_wrap.js:1088:38)
at emitNone (events.js:86:13)
at TLSSocket.emit (events.js:188:7)
at TLSSocket._finishInit (_tls_wrap.js:610:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:440:38)
What am I missing here?
var fs = require('fs');
var http = require('http');
var https = require('https');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxy();
var options = {
'blah.com':{
target:'https://blah.com:5000',
ssl:{
key:fs.readFileSync('/myencrypt/blah.com/privkey.pem', 'utf8'),
cert:fs.readFileSync('/myencrypt/blah.com/cert.pem', 'utf8')
}
}
}
http.createServer(function(req, res) {
proxy.web(req, res, {
target: options[req.headers.host].target,
ssl : options[req.headers.host].ssl
});
}).listen(80);

I decided to solve my problem using redbird
var redbird = require('redbird')({
port: 80,
secure:false,
ssl: {
port:443,
key: "/myencrypt/blah.com/privkey.pem",
cert: "/myencrypt/blah.com/cert.pem",
}
});
redbird.register('blah.com', 'https://blah.com:5000', {
ssl: {
key: "/myencrypt/blah.com/privkey.pem",
cert: "/myencrypt/blah.com/cert.pem",
}
});

Related

Client network socket disconnected before secure TLS connection was established error while creating a secure websocket connection

I am trying to create a secure websocket client and server.
Server code:
var options = {
key: clientKey,
cert: clientCert,
ca: caCert,
passphrase: 'test',
requestCert: true
};
var httpsServer = https.createServer(options);
var WebSocketServer = WebSocket.Server;
var wss = new WebSocketServer({
verifyClient: (info) => {
console.log('Request from client :'+ info.req.rawHeaders);
console.log('Request from client auth :'+ info.req.client.authorized);
success = !!info.req.client.authorized;
return success;
},
server: httpsServer
});
Client Code:
const ws = new WebSocket('wss://localhost:8989/',
'com.hp.cdm.service.ioFilter.version.1.type.filterStream', {
cert: fs.readFileSync(path.normalize(serverCertPath)),
key: fs.readFileSync(path.normalize(serverKeyPath)),
ca: fs.readFileSync(path.normalize(caCert)),
passphrase: 'test',
rejectUnauthorized: false,
});
When I try to make a connection from client to server, I am getting the following error,
{ Error: Client network socket disconnected before secure TLS connection was established
at TLSSocket.onConnectEnd (_tls_wrap.js:1086:19)
at Object.onceWrapper (events.js:273:13)
at TLSSocket.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1094:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
code: 'ECONNRESET',
path: undefined,
host: 'localhost',
port: '8989',
localAddress: undefined }
What am I doing error? Any TLS version mismatch? Or some certificate error?

Node running HTTPS Server?

I am writing a program that will serve a particular file. However, I get an exception. I am not sure on the error since I am a bit new to node based programming.
I have got the certificates correct.
var tls = require('tls');
var fs = require('fs');
var options = {
key: fs.readFileSync('/home/test/key.pem'),
cert: fs.readFileSync('/home/test/server.crt')
};
tls.createServer(options, function (s) {
content = fs.readFileSync('/home/test/abc.conf','utf8');
s.write(content);
s.setEncoding('utf8');
s.pipe(s);
}).listen(8000);
node app.js
events.js:160
throw er; // Unhandled 'error' event
^
Error: write ECONNRESET
at exports._errnoException (util.js:1020:11)
at WriteWrap.afterWrite (net.js:800:14)
Realized, it is quite easy using just https.createServer and provide options of ciphers there.
var ciphers = [
'AES128-SHA',
'AES256-SHA'
].join(':');
var options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem'),
ciphers: ciphers
};
https.createServer(options, function(req, res) {
console.log("Running node now");
}).listen(443);
Since, I am using 443 https standard port, I need to start this node app with admin permission i.e. sudo.

Error: self signed certificate in Node JS Client

Example Program:
Server:
var fs = require('fs');
var https = require('https');
var options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-crt.pem'),
ca: fs.readFileSync('ca-crt.pem'),
};
https.createServer(options, function (req, res) {
console.log(new Date()+' '+
req.connection.remoteAddress+' '+
req.method+' '+req.url);
res.writeHead(200);
res.end("hello world\n");
}).listen(4433);
Client:
var fs = require('fs');
var https = require('https');
var options = {
hostname: 'localhost',
port: 4433,
path: '/',
method: 'GET',
ca: fs.readFileSync('ca-crt.pem')
};
var req = https.request(options, function(res) {
res.on('data', function(data) {
process.stdout.write(data);
});
});
req.end();
I have generated the Keys and certificate using openssl in my Linux server.
But while running client program its showing as Error: self signed certificate . By referring some websites and even stack overflow discussions some have mentioned that using a option called rejectUnauthorized: false even though there is no use in using this parameter while using certificates for secure transfer of data.
Is there any way to trust the certificates in Linux server?
Any example program with certificates and node JS Program ?
Node JS Client to connect to server?
Without Using rejectUnauthorized: false?

TypeError: dest.end is not a function

I am trying to use HTTP/2. My express version is 5.0.0-alpha.2, http2 version is 3.3.4.
I suppose http2 should work well with express 5.
const http2 = require('http2');
// const http2 = require('spdy'); // using spdy package here, everything works perfect
const options = {
key: fs.readFileSync(path.join(__dirname, 'private', 'server.key')),
cert: fs.readFileSync(path.join(__dirname, 'private', 'server.crt'))
};
const server = http2
.createServer(options, app)
.listen(3000, err => {
if (err) throw new Error(err);
// I can see "Listening..." message, which means the server starts running well.
console.log('Listening...');
});
The server starts running well, but when I open client website, it gives me this error in the terminal:
_stream_readable.js:512
dest.end();
^
TypeError: dest.end is not a function
at Stream.onend (_stream_readable.js:512:10)
at Stream.g (events.js:286:16)
at emitNone (events.js:91:20)
at Stream.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:975:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
It seems node-http2 has not been supported by Express yet.
Please track this issue Support for module http on github.
In the meanwhile, you can stay with node-spdy.
const spdy = require('spdy');
const options = {
key: fs.readFileSync(path.join(__dirname, 'private', 'server.key')),
cert: fs.readFileSync(path.join(__dirname, 'private', 'server.crt'))
};
const server = spdy
.createServer(options, app)
.listen(3000, err => {
if (err) throw new Error(err);
console.log('Listening...');
});
With Express 5.0 we have another solution :
express = require( 'express' ), //Web framework
// Solution
express.request.__proto__ = http2.IncomingMessage.prototype;
express.response.__proto__ = http2.ServerResponse.prototype;
// Create app for server http/2
var apph2 = express();
And this is the server code :
var
application_root = __dirname,
express = require( 'express' ), //Web framework
http2 = require('http2')
logger = require('morgan')
fs = require('fs')
constants = require('constants');
// Bunyan logger
var bunyan = require('bunyan');
var app = require('./apps/app_name');
var bunlog = bunyan.createLogger({name: "brqx_app"});
var credentials = {
// log : bunlog ,
key : fs.readFileSync('/etc/letsencrypt/live/domain/privkey.pem' ),
cert : fs.readFileSync('/etc/letsencrypt/live/domain/fullchain.pem' ),
ca : fs.readFileSync("/etc/letsencrypt/live/domain/chain.pem" ),
dhparam : fs.readFileSync("/etc/letsencrypt/archive/domain/dh1.pem" ),
secureOptions: constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_SSLv2
};
// Configure server
server = http2.createServer( credentials , app);
server.listen(PORT , function () {
console.log('Started Brqx http/2!');
} )
I hope these easy lines helps to people.
One thing is important when we search information on Internet is the date of test when code was tested : 2017 - October.
Regards.
Ricardo/Brqx.

subdomains using http-proxy does not display node running app

I am following http://blog.nodejitsu.com/http-proxy-intro/ to write up my proxy server to point sub domains to node apps running on different port
var http = require('http'),
httpProxy = require('http-proxy');
//
// Just set up your options...
//
var options = {
hostnameOnly: true,
router: {
'localhost': '127.0.0.1:80'
'sub.localhost': '127.0.0.1:9012',
}
}
//
// ...and then pass them in when you create your proxy.
//
var proxyServer = httpProxy.createServer(options).listen(80)
When i run this file using node and try to access localhost or sub.localhost, I get this error back. I cant really understand whats going wrong.
Error: Must provide a proper URL as target
at ProxyServer.<anonymous> (D:\myProjects\bitbucket\temp\node_modules\http-proxy\lib\http-proxy\index.js:68:35)
at Server.closure (D:\myProjects\bitbucket\temp\node_modules\http-proxy\lib\http-proxy\index.js:125:43)
at emitTwo (events.js:87:13)
at Server.emit (events.js:172:7)
at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:525:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:88:23)
Try this:
var http = require("http");
var httpProxy = require("http-proxy");
// reverse proxy
var proxy = httpProxy.createProxyServer();
http.createServer(function (req, res) {
var target,
domain = req.headers.host,
host = domain.split(":")[0];
////////////////// change this as per your local setup
////////////////// (or create your own more fancy version! you can use regex, wildcards, whatever...)
if (host === "localhost") target = {host: "localhost", port: "2000"};
if (host === "testone.localhost") target = {host: "localhost", port: "3000"};
if (host === "api.testone.localhost") target = {host: "localhost", port: "4000"};
//////////////////
proxy.web(req, res, {
target: target
});
}).listen(8000);

Resources