Создайте прокси HTTPS для произвольных внешних URL-адресов

#node.js #https #proxy #axios #node-http-proxy

#node.js #https #прокси #axios #узел-http-прокси

Вопрос:

Я хочу создать простой прокси для запросов к произвольным веб-сайтам с Node.js (http-node-proxy) (и машинописный текст для моего случая). Я знаю, что существует несколько вопросов по этой сложной теме, но пока ни один из них мне не помог. Я пытался:

 import axios from 'axios';
import http from 'http';
import httpProxy from 'http-proxy';
import url from 'url';

async function mainHTTP() {
  // create the proxy
  const proxy = httpProxy.createProxy({});
  const server = http.createServer(function(request, response) {
    console.log([request.url, response.statusCode]);
    const requestURL = new url.URL(request.url!);
    const target = `${requestURL.protocol}//${requestURL.host}`;
    proxy.web(request, response, {target: target});
  });
  server.listen(8080);

  // make an example request
  const response = await axios.request({
    'url': 'http://www.example.org',
    'proxy': {host: 'localhost', port: 8080},
  });
  console.log(response);
}
mainHTTP();
  

И это отлично работает!Но только для HTTP-запросов. Итак, я попробовал то же самое «перевести» на HTTPS:

 // ...
import fs from 'fs';
import https from 'https';

async function mainHTTPs() {
  // create the proxy
  const proxy = httpProxy.createProxy({});
  const ssl = { // keys tested, they work in other situations
    'key': fs.readFileSync('key.pem'),
    'cert': fs.readFileSync('cert.pem'),
  }
  const server = https.createServer(ssl, function(request, response) {
    console.log([request.url, response.statusCode]); // error happens before this is executed!
    const requestURL = new url.URL(request.url!);
    const target = `${requestURL.protocol}//${requestURL.host}`;
    proxy.web(request, response, {target: target});
  });
  server.listen(8080);
  server.on('tlsClientError', (err) => console.log(err)); // added for debugging

  // make an example request
  const response = await axios.request({
    'url': 'https://www.example.org',
    'proxy': {host: 'localhost', port: 8080},
  });
  console.log(response);
}
mainHTTPs();
  

Но теперь я внезапно получаю сообщение об ошибке «зависание сокета». Строка отладки выдает следующую загадочную ошибку:

«Ошибка: 9356: ошибка: 1408F09C: процедуры SSL: ssl3_get_record: http-запрос: c: ws deps openssl openssl ssl record ssl3_record.c: 322:».

Обратите внимание, что ошибка возникает перед вызовом proxy.web , поэтому я предполагаю, что она не должна быть вызвана самим прокси.

Кто-нибудь понимает эту ошибку и может помочь мне избавиться от нее?

Комментарии:

1. Вы уверены, что используемые сертификат и ключ являются действительным сертификатом HTTPS для домена, к которому клиент пытается получить доступ через прокси (например, соответствующее доменное имя)? Добавили ли вы сертификат как доверенный для клиентского приложения?

2. На самом деле, я очень новичок в HTTPs. Я сгенерировал ключи, используя OpenSSL (самозаверяющий сертификат). Я не уверен, как утверждать, что сертификаты действительны для доступа к домену, потому что этот домен варьируется от запроса к запросу. Однако браузер также может это сделать, поэтому это должно быть возможно.

3. Извините, но если вы не понимаете, как работает система веб-ЦС и как работают прокси-серверы, перехватывающие HTTP, вам следует использовать существующий прокси, который делает это за вас. Я бы порекомендовал, например, mitmproxy для вас (на основе Python), он обрабатывает генерацию сертификатов для вас, вам просто нужно следовать инструкциям.

4. Это действительно так сложно? Я действительно думал, что мое решение близко к работе. Мне не нужны расширенные возможности, по сути, я просто регистрирую каждый запрос и ответ.

5. Я не понимаю, почему у вас есть localhost в качестве прокси; это должен быть прокси-IP