Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Nodejs v0.10.2 "Proxying http from https using two certificates" #399

Closed
fuentecilla86 opened this Issue · 10 comments

6 participants

@fuentecilla86

Hey guys,

I've been trying to make work "Proxying http from https using two certificates" with the last version of Nodejs currently available (v0.10.2) but I've not been able to do it. However, I had tried it before with the version 0.6.12 of Nodejs and it worked perfectly.

I've seen that the problem is due to this:


tls.js:1028
throw new Error('Missing PFX or certificate + private key.');
^
Error: Missing PFX or certificate + private key.
at Server (tls.js:1028:11)
at new Server (https.js:35:14)
at Object.exports.createServer (https.js:54:10)
at Object.exports.createServer (/home/afuentes/node_modules/http-proxy/lib/node-http-proxy.js:178:13)
at Object. (/home/afuentes/nodejs_test/node4_https_2cert.js:53:11)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)


The reason of this is that in this file (tls.js) was added (compared with the version that worked) the following line


if (!self.pfx && (!self.cert || !self.key)) {
throw new Error('Missing PFX or certificate + private key.');
}


Therefore, it requieres the ".pfx" certificate. I have tried to solve it creating it, but It does not work yet.

Could anyone help me? Has anyone tried the same?

Thanks in advance.

@indexzero
Owner

No idea. Haven't played with v0.10.x yet much. @isaacs or @indutny?

@indutny

I believe you either forgot to put key or cert property in your options. Because this check is essentially the same as: !(self.pfx || self.cert && self.key)

@fuentecilla86

Hey guys,

First of all, thanks for you quickly replies!

I have tried the same scenary with two different syntax to show you better what's my problem. One of them fails and the other runs perfectly:

The one that runs perfectly (one certificate syntax):


var https = require("https"),
path = require("path"),
http = require("http"),
fs = require("fs"),
httpProxy = require("http-proxy"),
crypto = require("crypto");

//
// Proxy options
//
var options = {
https: {
key: fs.readFileSync('ryans-key.pem'),
cert: fs.readFileSync('ryans-cert.pem')
},
hostnameOnly: true,
router: {
'foobar.com': '127.0.0.1:8005',
}
};

//
// Create a standalone HTTPS proxy server
//
httpProxy.createServer(options).listen(8002);

//
// Create the target HTTPS server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('hello https\n');
res.end();
}).listen(8005);


Testing:

curl -k https://foobar.com:8002
hello https


The one that fails (two certificates syntax):


var https = require("https"),
path = require("path"),
http = require("http"),
httpProxy = require("http-proxy"),
fs = require("fs"),
crypto = require("crypto");

//
// generic function to load the credentials context from disk
//
function getCredentialsContext () {
return crypto.createCredentials({
key: fs.readFileSync('ryans-key.pem'),
cert: fs.readFileSync('ryans-cert.pem')
}).context;
}

//
// A certificate per domain hash
//
var certs = {
"foobar.com": getCredentialsContext(),
};

//
// Proxy options
//
var options = {
https: {
SNICallback: function (hostname) {
return certs[hostname];
}
},
hostnameOnly: true,
router: {
'foobar.com': '127.0.0.1:8005',
}
};

//
// Create a standalone HTTPS proxy server
//
httpProxy.createServer(options).listen(8002);

//
// Create the target HTTPS server
//
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('hello https\n');
res.end();
}).listen(8005);


Logs:


tls.js:1046
throw new Error('Missing PFX or certificate + private key.');
^
Error: Missing PFX or certificate + private key.
at Server (tls.js:1046:11)
at new Server (https.js:35:14)
at Object.exports.createServer (https.js:54:10)
at Object.exports.createServer (node_modules/http-proxy/lib/node-http-proxy.js:178:13)
at Object. (nodejs_test/ssl_test2.js:43:11)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)


I created the key and the certificate as the nodejs documentation: http://nodejs.org/api/tls.html
openssl genrsa -out ryans-key.pem 1024
openssl req -new -key ryans-key.pem -out ryans-csr.pem
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

How is possible if the first one run perfectly? Am I doing any mistake?

Thanks in advance!

@hongkongkiwi

Same issue here. It's pretty simple to replicate, just take the latest code from node.js npm repository and try the two certficates example.

The issue seems to be that the function to return the secure context simply returns blank when returning outside of the function. Not sure why, it doesn't make sense.

@niftylettuce

same issue here

@niftylettuce

line 386 of node-http-proxy.js doesn't contain 'pfx'

@niftylettuce

have same issue as @andysavage anyone have a solution?

@hongkongkiwi

I believe it has nothing to do with PFX or not, for some reason the context is null after returning from that method. Inside the helper method it resolves to an object but as soon as that method returns it gets 'released'.

I'm wondering if this is a lower level bug with the crypto library rather than this, but it's a pretty massive show stopper for us, hopefully the coders can fix this ASAP. Perhaps downgrading the crypto library may help?

@niftylettuce

fwiw here's the commit log, i'm not familiar with this code base though https://github.com/joyent/node/commits/v0.10.2-release/lib/crypto.js

@pkarc

same here

@Raynos Raynos referenced this issue from a commit in Raynos/node-http-proxy
@Raynos Raynos Pass default certs to SNICallback example
Using only SNICallback to create a HTTPS / TLS server is bad. It means all non SNI clients can't do anything because there are no certs.

in v0.10 of node TLS server was updated to throw if you forgot to supply certs.

Which means that every HTTPS server needs to supply certs as a fallback for when SNI is not available.

 - closes #399
f5e1844
@indexzero indexzero closed this in #419
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.