Прокси-сервер HTTPS в node.js - программирование
Подтвердить что ты не робот

Прокси-сервер HTTPS в node.js

Я разрабатываю прокси-сервер node.js, и я хочу, чтобы он поддерживал протоколы HTTP и HTTPS(SSL) (как сервер).

В настоящее время я использую node-http-proxy:

const httpProxy = require('http-proxy'),
      http = require('http');

var server = httpProxy.createServer(9000, 'localhost', function(req, res, proxy) {
    console.log(req.url);
    proxy.proxyRequest(req, res);
});

http.createServer(function(req, res) {
    res.end('hello!');
}).listen(9000);

server.listen(8000);

Я настраиваю свой браузер для использования прокси-сервера HTTP на localhost:8000, и он работает. Я также хочу поймать запросы HTTPS (т.е. Настроить мой браузер на использование localhost:8000 в качестве прокси-сервера HTTPS и уловить запросы в моем приложении). Не могли бы вы помочь мне, как я могу это сделать?

PS

Если я подписываюсь на upgrade событие объекта httpProxy сервера, я могу получить запросы, но я не знаю, как перенаправить запрос и отправить ответ клиенту:

server.on('upgrade', function(req, socket, head) {
    console.log(req.url);
    // I don't know how to forward the request and send the response to client
});

Любая помощь будет оценена.

4b9b3361

Ответ 1

Решения едва ли существуют для этого, и документация в лучшем случае плохая для поддержки как на одном сервере. Трюк здесь заключается в том, чтобы понять, что конфигурации клиентских прокси-серверов могут отправлять https-запросы на HTTP-прокси-сервер. Это верно для Firefox, если вы указываете прокси-сервер HTTP, а затем проверяете "одинаково для всех протоколов".

Вы можете обрабатывать соединения https, отправленные на HTTP-сервер, прослушивая событие "connect". Обратите внимание, что у вас не будет доступа к объекту ответа на событие connect, только сокет и боковые головки. Данные, отправленные через этот сокет, будут оставаться зашифрованными для вас в качестве прокси-сервера.

В этом решении вам не нужно создавать свои собственные сертификаты, и в результате у вас не будет конфликтов сертификатов. Трафик просто проксирован, не перехвачен и переписан с разными сертификатами.

//  Install npm dependencies first
//  npm init
//  npm install --save [email protected]
//  npm install --save [email protected]

var httpProxy = require("http-proxy");
var http = require("http");
var url = require("url");
var net = require('net');

var server = http.createServer(function (req, res) {
  var urlObj = url.parse(req.url);
  var target = urlObj.protocol + "//" + urlObj.host;

  console.log("Proxy HTTP request for:", target);

  var proxy = httpProxy.createProxyServer({});
  proxy.on("error", function (err, req, res) {
    console.log("proxy error", err);
    res.end();
  });

  proxy.web(req, res, {target: target});
}).listen(8080);  //this is the port your clients will connect to

var regex_hostport = /^([^:]+)(:([0-9]+))?$/;

var getHostPortFromString = function (hostString, defaultPort) {
  var host = hostString;
  var port = defaultPort;

  var result = regex_hostport.exec(hostString);
  if (result != null) {
    host = result[1];
    if (result[2] != null) {
      port = result[3];
    }
  }

  return ( [host, port] );
};

server.addListener('connect', function (req, socket, bodyhead) {
  var hostPort = getHostPortFromString(req.url, 443);
  var hostDomain = hostPort[0];
  var port = parseInt(hostPort[1]);
  console.log("Proxying HTTPS request for:", hostDomain, port);

  var proxySocket = new net.Socket();
  proxySocket.connect(port, hostDomain, function () {
      proxySocket.write(bodyhead);
      socket.write("HTTP/" + req.httpVersion + " 200 Connection established\r\n\r\n");
    }
  );

  proxySocket.on('data', function (chunk) {
    socket.write(chunk);
  });

  proxySocket.on('end', function () {
    socket.end();
  });

  proxySocket.on('error', function () {
    socket.write("HTTP/" + req.httpVersion + " 500 Connection error\r\n\r\n");
    socket.end();
  });

  socket.on('data', function (chunk) {
    proxySocket.write(chunk);
  });

  socket.on('end', function () {
    proxySocket.end();
  });

  socket.on('error', function () {
    proxySocket.end();
  });

});

Ответ 2

Я создал прокси http/https с помощью модуля http-proxy: https://gist.github.com/ncthis/6863947

Код на данный момент:

var fs = require('fs'),
  http = require('http'),
  https = require('https'),
  httpProxy = require('http-proxy');

var isHttps = true; // do you want a https proxy?

var options = {
  https: {
    key: fs.readFileSync('key.pem'),
    cert: fs.readFileSync('key-cert.pem')
  }
};

// this is the target server
var proxy = new httpProxy.HttpProxy({
  target: {
    host: '127.0.0.1',
    port: 8080
  }
});

if (isHttps)
  https.createServer(options.https, function(req, res) {
    console.log('Proxying https request at %s', new Date());
    proxy.proxyRequest(req, res);
  }).listen(443, function(err) {
    if (err)
      console.log('Error serving https proxy request: %s', req);

    console.log('Created https proxy. Forwarding requests from %s to %s:%s', '443', proxy.target.host, proxy.target.port);
  });
else
  http.createServer(options.https, function(req, res) {
    console.log('Proxying http request at %s', new Date());
    console.log(req);
    proxy.proxyRequest(req, res);
  }).listen(80, function(err) {
    if (err)
      console.log('Error serving http proxy request: %s', req);

    console.log('Created http proxy. Forwarding requests from %s to %s:%s', '80', proxy.target.host, proxy.target.port);
  });

Ответ 3

В документах node -http-proxy содержатся примеры этого. Найдите "Proxying to HTTPS from HTTPS" в https://github.com/nodejitsu/node-http-proxy Процесс настройки немного отличается в каждом браузере. У некоторых есть возможность использовать настройки прокси для всех протоколов; вам нужно настроить прокси-сервер отдельно.