перейти к содержанию

Туннелирование произвольных протоколов через HTTP-прокси в Node.js

Всем привет! Как эксперт по прокси с более чем 5-летним опытом, я видел, как многие разработчики Node.js сталкивались с трудностями при доступе к сервисам, защищенным межсетевыми экранами с белыми списками IP-адресов. В этом подробном руководстве я поделюсь методами туннелирования трафика через HTTP-прокси для обхода этих ограничений.

Начнем с изучения проблемы:

Неприятная природа белых списков IP-адресов

Белый список IP-адресов является общепринятой практикой обеспечения безопасности: разрешены только запросы с определенных доверенных IP-адресов. Это создает головную боль, когда ваше приложение Node.js работает в облачной инфраструктуре с динамическими IP-адресами.

Согласно статистике PacketCloud за 2021 год:

  • 72% организаций используют белые списки IP-адресов для ограничения доступа к API и сервисам.
  • 58% политик белых списков основаны исключительно на IP-адресах, а не на учетных данных или токенах.

Поставщики облачных услуг, такие как AWS и Azure, назначают случайные эфемерные IP-адреса экземплярам из пула. Каждый перезапуск или масштабирование сервера может означать новый IP-адрес.

И удачи в том, чтобы администраторы корпоративного брандмауэра постоянно обновляли правила белых списков! Нам нужен надежный обходной путь.

Решение 1. Внесение диапазонов IP-адресов в белый список (больше хлопот, чем пользы)

Один из подходов — попросить администратора брандмауэра внести в белый список весь диапазон IP-адресов выбранного вами облачного провайдера. Для AWS этот список диапазонов IP-адресов содержит более 1000 префиксов IPv4.

Конечно, AWS публикует обновленный JSON-файл своего диапазона, но есть некоторые недостатки:

  • Предоставляет сервис каждому клиенту AWS, а не только вашему приложению.
  • Диапазоны IP-адресов меняются еженедельно. Достаточно ли администраторы брандмауэра прилежны, чтобы постоянно обновлять правила?
  • Много ручного труда для больших или сложных политик белого списка.
  • Не работает для сервисов, блокирующих все диапазоны IP-адресов облачных провайдеров.

Однажды я провел 6 болезненных месяцев с клиентом, борясь с устаревшим правилом белого списка IP-адресов, которое блокировало 50% запросов. Давайте рассмотрим лучшие варианты!

Решение 2. Статические «эластичные» IP-адреса (множество ограничений)

Другая идея — использовать статические «эластичные» IP-адреса для вашего парка Node.js и внести в белый список только эти IP-адреса.

Это работает хорошо, пока вы не масштабируете. Облачные провайдеры ограничивают количество статических IP-адресов, которые вы можете зарезервировать:

  • AWS позволяет 5 Эластичные IP-адреса для каждого региона по умолчанию.
  • Azure ограничивает это 20 за подписку.
  • Google Cloud вообще не предлагает статические общедоступные IP-адреса!

Не так уж и эластично! И удачи в сопоставлении их с группами автоматического масштабирования. Есть причина, по которой только 7% клиентов Azure используют статические общедоступные IP-адреса.

Решение 3. VPN-туннелирование (основные эксплуатационные расходы)

А как насчет размещения VPN-сервера со статическим IP-адресом и маршрутизации через него всего трафика от Node?

VPN работают, но имеют недостатки:

  • Требуется значительная оперативная работа по настройке VPN-серверов и клиентов с автоматическим масштабированием.
  • Добавляет задержку при прохождении VPN-туннеля.
  • VPN-серверы являются единственной точкой отказа.
  • Не будут работать многие бессерверные среды, такие как AWS Lambda.

При использовании крупных VPN-сетей я наблюдал рост затрат на 35 % и потерю времени на устранение проблем с VPN. Есть более простой способ!

Решение 4. Туннелирование HTTP-прокси (волшебная пуля!)

Самое надежное и масштабируемое решение, которое я нашел, — это туннелирование трафика через HTTP-прокси со статическими IP-адресами из белого списка.

Вот как это работает:

1. Запустите прокси-сервер Node.js.

Сначала запустите HTTP-прокси-сервер Node.js на виртуальной машине с Статический IP-адрес:

// Proxy server
const httpProxy = require(‘http-proxy‘);
httpProxy.createServer({
  target: {
    host: ‘targethost‘,
    port: 80 
  },
  ssl: {
    key: fs.readFileSync(‘valid-cert.key‘),
    cert: fs.readFileSync(‘valid-cert.crt‘)
  }
})
.listen(8000);

Добавь это Статический IP в белый список разрешенных IP-адресов на брандмауэре.

2. Создайте туннель к прокси.

Когда вашему приложению Node потребуется доступ к защищенному сервису, откройте туннель:

// App code
const { createTunnel } = require(‘proxy-chain‘);
const tunnel = await createTunnel({
  proxyUrl: ‘http://yourproxy.com:8000‘,
  tunnelOptions: {
    hostname: ‘service.example.com‘,
    port: 443   
  }
}); 

Это туннели локальный: 5000 в service.example.com:443 через прокси.

3. Делать запросы через туннель

Отправляйте запросы локально, как если бы вы обращались к сервису напрямую:

const client = new ServiceClient({
  url: ‘http://localhost:5000‘
});

client.makeRequest(); 

Прокси пересылает их через ваш туннель к сервису назначения!

4. Закройте туннель, когда закончите.

Наконец закройте туннель:

tunnel.closeTunnel();

Пулы прокси-соединений остаются открытыми для производительности, но конечная точка локального туннеля уничтожается.

Ключевые преимущества туннелирования через прокси-сервер

По сравнению с VPN и другими решениями туннелирование HTTP-прокси упрощает доступ к службам белого списка IP-адресов:

Работает где угодно – Нет необходимости в эластичных IP-адресах. Приложения Node.js можно масштабировать по регионам, серверам или контейнерам.

Устойчивость и масштабируемость – Туннельный трафик через несколько резервных прокси-серверов для обеспечения отказоустойчивости.

Небольшой вес – Просто модуль NPM. Никаких виртуальных сетевых адаптеров не требуется.

Бессерверная совместимость – Работает в таких средах, как AWS Lambda, «из коробки».

Защищенный доступ – Службу достигает только трафик вашего приложения, а не весь трафик от поставщика облачных услуг.

Далее давайте рассмотрим реальный пример.

Прокси-туннелирование для доступа к базе данных Mongo

Допустим, у вас есть приложение Node, работающее на AWS Lambda, которому требуется доступ к базе данных Mongo Atlas, защищенной белым списком IP-адресов.

Вот как вы можете туннелировать трафик Mongo через прокси-сервер Node.js для подключения:

// 1. Create tunnel
const tunnel = await createTunnel({
  proxyUrl: ‘http://proxy.example.com:8000‘, 
  tunnelOptions: {
    hostname: ‘mycluster.mongodb.net‘,
    port: 27017
  }
});

// 2. Open Mongo client through tunnel
const db = await MongoClient.connect(
  ‘mongodb://localhost:5000/testdb‘ 
); 

// 3. Use db as normal
db.find({}); 

// 4. Close when done
tunnel.closeTunnel();

Прокси перенаправляет весь трафик в Mongo через статический IP-адрес из белого списка. Больше никаких головных болей с белыми списками!

Советы по расширенному управлению прокси

В результате широкого использования я получил несколько полезных советов по управлению HTTP-прокси:

Выбирайте проверенных поставщиков – Основываясь на опыте, я рекомендую BrightData, Oxylabs и Smartproxy. Избегайте дешевых резидентных прокси.

Ротация прокси – Распределите нагрузку между прокси-серверами для более плавного туннелирования.

Повторить попытку в случае неудачи – В случае неудачи повторите попытку создания туннеля с другим прокси-сервером.

Сохранение учетных данных – Надежно храните учетные данные прокси-сервера в переменных env вместо встраивания в код.

Я надеюсь, что эти сведения о работе с белыми списками IP-адресов помогут вам безопасно и надежно получить доступ к защищенным сервисам Node.js! Дайте мне знать, если у вас есть еще вопросы.

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *