“使用两个证书从https代理http”

时间:2013-04-04 09:52:25

标签: node.js node-http-proxy

我一直在尝试使用当前可用的最后一个版本的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

有人可以帮助我吗?

提前致谢

1 个答案:

答案 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',
    }
};