我一直在尝试使用当前可用的最后一个版本的Nodejs(v0.10.2)进行“使用两个证书从https代理http”,但是我无法做到。
我用一张证书做了这件事并且有效:
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);
测试它完美无缺:
curl -k https://foobar.com:8002 你好https
但是,如果我要使用两个虚拟主机和两个不同的证书但是我无法使其工作(这是我尝试过的语法示例),我试图做一些事情:
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);
这是最后一个示例的日志:
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)
似乎无法识别按键。可能是因为函数crypto.createCredentials?
我在nodejs文档中创建了密钥和证书: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
有人可以帮助我吗?
提前致谢
答案 0 :(得分:2)
您缺少要使用的服务器的默认证书和密钥。您需要像普通的https代理一样在options对象中添加cert和key属性,例如:
var options = {
https: {
SNICallback: function (hostname) {
return certs[hostname];
},
key: fs.readFileSync('ryans-key.pem'),
cert: fs.readFileSync('ryans-cert.pem'),
},
hostnameOnly: true,
router: {
'foobar.com': '127.0.0.1:8005',
}
};