0

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

有人可以帮我吗?

提前致谢

4

1 回答 1

2

您缺少服务器要使用的默认证书和密钥。您需要像普通 https 代理一样在选项对象中添加证书和密钥属性,例如:

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',
    }
};
于 2013-07-19T15:15:52.927 回答