使用http-node-proxy创build一个正向https代理

我正在尝试创build一个能够处理HTTPS网站的转发代理。 我正在尝试观察和修改不同网站的stream量。 这是我的代码适用于http网站,但不适用于https网站。

httpProxy.createServer(function(req, res, next) { //custom logic next(); }, function(req, res) { var proxy = new httpProxy.RoutingProxy(); var buffer = httpProxy.buffer(req); var urlObj = url.parse(req.url); req.headers.host = urlObj.host; req.url = urlObj.path; console.log(urlObj.protocol); setTimeout(function() { proxy.proxyRequest(req, res, { host: urlObj.host, port: 80, buffer: buffer, } )}, 5000); }).listen(9000, function() { console.log("Waiting for requests..."); }); 

谢谢你们的帮助!

处理httpsstream量时必须指定https选项。 这是我在我的代理设置中正在做的事情。

 var fs = require('fs'), httpProxy = require('http-proxy'); var proxyTable = {}; proxyTable['domain.com'] = 'localhost:3001'; proxyTable['domain.com/path'] = 'localhost:3002'; proxyTable['sub.domain.com'] = 'localhost:3003'; var httpOptions = { router: proxyTable }; var httpsOptions = { router: proxyTable, https: { passphrase: 'xxxxxxx', key: fs.readFileSync('/path/to/key'), ca: fs.readFileSync('/path/to/ca'), cert: fs.readFileSync('/path/to/crt')} }; httpProxy.createServer(httpOptions).listen(80); httpProxy.createServer(httpsOptions).listen(443); 

https的文档也在他们的github页面上。

https://github.com/nodejitsu/node-http-proxy

如果你只是做一个远期代理,那么你需要考虑一些事情。

  • 在HTTPS请求的代理上不会触发常规请求 – 相反,您将看到HTTP CONNECT。

这是您需要处理的顺序stream程。

  1. CONNECT事件从浏览器发送到HTTPS部分中指定的代理。 你会在这里看到这个: http : //nodejs.org/api/http.html#http_event_connect请注意,这是通过HTTP模块,而不是HTTPS连接。
  2. 您创build一个新的套接字连接到所请求的域(或您的映射域)。 [srvSocket]
  3. 你会回应一个200的CONNECTsockets
  4. 你将使用CONNECT事件将你收到的缓冲区写入srvSocket,然后将这两个套接字连接在一起srvSocket.pipe(socket);
  5. socket.pipe(srvSocket);

由于您试图在本地欺骗请求的域名,因此您需要做更多的事情

  1. 你需要生成一个根CA.
  2. 您将需要将此证书作为可信权限导入到您的操作系统
  3. 您将使用此证书为您尝试访问的域创build新的密钥/证书文件
  4. 您映射的主机将需要使用步骤3中为您映射的每个域生成的相应密钥/证书文件进行响应。

https://github.com/substack/bouncy

 var bouncy = require('bouncy'); var server = bouncy(function (req, res, bounce) { if (req.headers.host === 'beep.example.com') { bounce(8001); } else if (req.headers.host === 'boop.example.com') { bounce(8002); } else { res.statusCode = 404; res.end('no such host'); } }); server.listen(8000); 

如果指定opts.key和opts.cert,则使用tls将连接设置为安全模式。 如果要制作https路由器,请执行此操作。

我们可以有一个中间件如下

request = require("request"); app.use(function (req, res, next) { request(' http://anotherurl.that.serves/the/request ').pipe(res); });

请参阅示例https://github.com/manuks/proxy

基本上,在http代理下,npm是Node使用的一些networking库(特别是http://nodejs.org/api/https.html和TLS)。 即使我的Apache能够通过在我的浏览器中访问代理,而无需使用代理的自签名证书即可连接到我:

 https://localhost:8002 

您需要build立一个证书颁发机构,以通过节点(我使用SSLCACertificateFile选项)中的“无法validation叶签名”错误。 然后,你会碰到“self_signed_cert_in_chain”。 这导致了一些谷歌的结果表明npm放弃了自签名证书,但我很确定这不关心节点。

你最终得到的是一些人指示你在你的https代理中使用process.env.NODE_TLS_REJECT_UNAUTHORIZEDrejectUnauthorized 。 如果您深入了解http代理,您会发现它接受代理选项。 用这个:

 /** * Module dependencies */ // basic includes express = require('express'); fs = require('fs'); http = require('http'); https = require('https'); httpProxy = require('http-proxy'); require('child_process').spawn(__dirname+'/../../../dependencies/apache/bin/httpd.exe',['-f',__dirname+'/../../../dependencies/apache/conf/httpd-payments.conf']); var app = module.exports = express(); app.set('port', process.env.PORT || 8001); // we sometimes change the port // creates an output object for this particular request //app.use(express.cookieParser('')); //app.use(express.bodyParser()); //app.use(express.methodOverride()); proxy = httpProxy.createProxyServer(); proxy.on('error', function (err, req, res) { console.log(err); res.send(500,err); res.end(); }); app.all('*',function(req,res,next) { var options = { hostname: '127.0.0.1', port: 8002, rejectUnauthorized: false, key: fs.readFileSync(__dirname+"/../../../deployment/server.key.pem"), cert: fs.readFileSync(__dirname+"/../../../deployment/server.crt.pem") }; agent = new https.Agent(options); try { proxy.web(req,res, { target: "https://localhost:8002", proxyTimeout: 30, agent: agent }); } catch(e) { // 500 error res.send(500,e); } }) /** * Start Server */ var options = { key: fs.readFileSync(__dirname+"/../../../deployment/server.key.pem"), cert: fs.readFileSync(__dirname+"/../../../deployment/server.crt.pem") }; server = https.createServer(options,app).listen(app.get('port'), function () { console.log('Running payments server on port ' + app.get('port')); });