Прокси-сервер - это шлюз между клиентом и всем Интернетом. Но есть несколько вариантов использования прокси. Например: если вы находитесь в корпоративной сети, с вероятностью 99% вы находитесь за прокси-сервером, который контролирует ваш доступ в Интернет, разрешая и ограничивая то, что вы можете посещать, а что нет. Такой прокси-сервер известен как прямой прокси.

Если мы говорим о стороне сервера, предположим, что у вас есть приложение, развернутое на некоторых серверах и доступное в Интернет, но вы хотите реализовать посредника, который может предотвратить прямой доступ ваших серверов приложений к Интернету, скорее всего, вы хотите иметь прокси-сервер, который может принимать запросы от клиентов в Интернете и пересылать их на серверы приложений, а затем отправлять им ответ. Такой прокси-сервер известен как обратный прокси.

Концепция прямого прокси

Давайте разберемся в этом на простом примере. Вы работаете в компании, имеющей компьютеры A, B и C, и эти компьютеры хотят получить доступ к веб-сайту X, но администратор заблокировал прямой доступ в Интернет в целях корпоративной безопасности, но он настроил прокси-сервер P, через который можно получить доступ в Интернет.

Прокси-сервер, упомянутый в приведенном выше сценарии, является прямым прокси-сервером.

Концепция обратного прокси

Допустим, вы являетесь клиентом C, обращающимся к веб-сайту W. Но администратор веб-сайта заблокировал прямой доступ к серверам и реализовал прокси-сервер P, который принимает от вас запросы и перенаправляет их на фактические серверы, а затем принимает ответы от них и отправляет их вам. У вас сложилось впечатление, что вы обращаетесь к веб-сайту напрямую C - ›W, но на самом деле вы обращаетесь к прокси-серверу, который, в свою очередь, перенаправляет ваш запрос на фактический сервер приложений, то есть C -› P - ›W. Представление выглядит следующим образом ниже:

Прокси-сервер, упомянутый в приведенном выше сценарии, является обратным прокси-сервером.

Кодирование прокси-сервера

Полный код можно найти на github: https://github.com/kasattejaswi/nodejs-proxy-server

Хватит теории, давайте сразу перейдем к кодированию нашего прокси-сервера. Для разработки мы собираемся использовать определенные встроенные в node.js модули для сети. Первый - сетевой модуль, а второй - потоковый модуль. Важно сначала взглянуть на эти модули, прежде чем переходить к написанию кода. Для документации и точного объяснения этих модулей вы можете обратиться по следующим ссылкам:

Сетевой модуль:

  1. Официальная документация: https://nodejs.org/api/net.html

Модуль потока:

  1. Официальная документация: https://nodejs.org/api/stream.html
  2. Очень четкое объяснение: https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/

Теперь, чтобы начать, убедитесь, что в вашей системе установлен node.js и готова любая IDE.

Сначала мы импортируем сетевой модуль в наш код и вызываем createServer ()

После инициализации нашего сервера мы можем прослушивать хост 0.0.0.0 (для приема входящего запроса со всех IP-адресов) и порт 8080, а в обратном вызове мы можем зарегистрировать, что сервер работает на 0.0.0.0:8080

Net-модуль запускает определенные события всякий раз, когда на сервер приходит новый запрос. А пока мы собираемся прослушать события «соединение», «ошибка» и «закрытие». Для этого давайте добавим слушателей.

Событие подключения дает нам объект сокета с подробной информацией о запросе, который захватывает сервер. Событие ошибки предоставляет нам ошибку, которая передается в обратном вызове. Итак, в приведенном выше примере мы зарегистрировали данные.

В приведенном выше коде clientToProxySocket также запускает событие «данные» после получения данных. Для каждого запроса, поскольку нам нужно получить данные только один раз, мы будем прослушивать только один раз для события «данные» только в первый раз и собираем из него достаточно данных.

До этого момента мы настроили простой сервер, который будет получать запросы и печатать детали запросов в консоли. Чтобы протестировать его, нам нужно сначала настроить нашу тестовую среду.

Настройка тестовой среды

Для этого я собираюсь использовать Mozilla Firefox. Однако вы можете использовать любой из браузеров, процедура будет такой же.

В адресной строке введите about: preferences, и откроется страница настроек.

Найдите прокси в поле поиска, и опция прокси будет отфильтрована.

Нажмите «Настройки», и откроется страница настройки прокси. Выберите «Ручная настройка прокси». В этом случае для HTTP-прокси укажите localhost и порт как 8080 и установите флажок «Также использовать этот прокси для FTP и HTTPS». Теперь они будут выглядеть примерно так.

Нажмите OK, и вы закончите настройку тестовой среды.

Получение деталей запроса

Теперь, когда наш базовый сервер и тестовая среда готовы, давайте запустим его в первый раз и посмотрим, какие сведения мы получим в запросе. Мы сделаем два запроса - один будет http, а другой - https.

Как видите, наш журнал прослушивания сервера теперь распечатан и готов принимать входящие запросы.

Для тестирования мы собираемся использовать linkedin.com в качестве URL-адресов http и https.

Когда мы зашли на linkedin.com, мы получили следующие данные:

А теперь давайте попробуем с https://linkedin.com. Мы получили следующие данные:

Здесь есть большая разница в обоих запросах. Для http мы получили запрос GET с http в адресе. В случае https мы получили CONNECT с номером порта 443. Поэтому мы будем использовать это для проверки, является ли запрос http или https, и назначим порты соответственно. Предположим, что целевой веб-сайт следует стандартным методам и использует порт 80 для HTTP-соединения и порт 443 для https-соединения. На данный момент мы не будем рассматривать пользовательские порты, но их можно получить аналогичным образом.

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

Чтобы проверить, является ли соединение http или https, мы будем использовать строку CONNECT, присутствующую в запросе. Давайте добавим этот код.

До этого момента у нас есть вся необходимая информация для пересылки запроса по назначению. Но как? Ответ - потоки node.js. Если мы говорим о запросе от клиента к прокси-серверу, это читаемый поток, а если мы говорим о прокси-сервере к месту назначения, это доступный для записи поток. Но когда данные получены от пункта назначения на прокси-сервер, они будут читаемым потоком, а затем, когда они будут отправлены обратно клиенту с прокси-сервера, это будет доступный для записи поток . Если мы выполним трубопровод, мы можем пересылать запросы на оба конца.

Итак, давайте начнем с создания соединения от прокси-сервера к месту назначения с помощью метода createConnection () с использованием сетевого модуля с хостом и портом, которые мы извлекли из запроса клиента.

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

И это все. Наш полноценный прокси-сервер готов.

Давайте запустим его и зайдем на наш сайт прямо сейчас.

Страница Linkedin успешно открыта. Если мы видим консоль, значит, у нас есть масса напечатанных запросов.

Это показывает, что наш прокси-сервер работает правильно. В этом коде мы можем сделать гораздо больше улучшений. Мы можем использовать его как обратный прокси, запустив его на сервере и настроив соответствующим образом.

Полный код можно найти на github: https://github.com/kasattejaswi/nodejs-proxy-server

Спасибо, что прочитали эту статью, если вы хотите прочитать больше статей о JavaScript, не забудьте подписаться на: https://thejsway.medium.com/