Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
fuentecilla86 opened this issue Apr 2, 2013 · 10 comments · Fixed by #419
Closed

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

fuentecilla86 opened this issue Apr 2, 2013 · 10 comments · Fixed by #419

Comments

@fuentecilla86
Copy link

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
Copy link
Contributor

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

@indutny
Copy link
Contributor

indutny commented Apr 2, 2013

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
Copy link
Author

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: https://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
Copy link

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
Copy link

same issue here

@niftylettuce
Copy link

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

@niftylettuce
Copy link

have same issue as @andysavage anyone have a solution?

@hongkongkiwi
Copy link

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
Copy link

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
Copy link
Contributor

pkarc commented Apr 30, 2013

same here

Raynos added a commit to Raynos/node-http-proxy that referenced this issue May 10, 2013
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 http-party#399
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants