
Возникла необходимость организовать трафик к внешнему сервису из сегмента сети с ограничением на исходящие соединения. Этот внешний сервис работал одновременно со множеством tcp/udp сокетов. При беглом обзоре существующих утилит не обнаружил готовое решение инкапсуляции множества сокетов с поддержкой «обратного» соединения.
Решил сделать свое решение, основными требованиями которого являются:
-
Использовать один белый IP адрес с одним tcp портом, по умолчанию 80 порт http.
-
Транспорт туннеля по websocket или http, перфоманс или доступность. Идеально если будет автоматический выбор лучшего из доступных протоколов обмена.
-
Туннелирование одновременно множества tcp и udp сокетов.
-
Кросс-платформенное консольное приложение, конфигурируемое параметрами запуска.
Исходя из пунктов 2 и 4 были выбраны .NET7 и библиотека SignalR. С этим набором я создал open-source проект, репозиторий https://github.com/viordash/TuToDataTunnel. В результате получилось два приложения TutoProxy.Server и TutoProxy.Client, в артефактах GitHub actions хранятся скомпилированные бинарники (x64), для linux и windows.
SignalR — это отличная библиотека для real-time транспорта данных, которая умеет автоматически выбирать протокол обмена: если недоступен websocket, то она переключается на http (long polling).
Приложение TutoProxy.Server — это сервер входящих подключений для клиентов туннелирования и также конечных tcp/udp клиентов.
Аргументы его запуска:
-
<host>, адрес сервера, например http://200.100.10.1:8088
-
—tcp <tcp>, список прослушиваемых tcp-портов, например —tcp=80,81,443,8000-8100. Опционально, при условии наличия параметра —udp.
-
—udp <udp>, список прослушиваемых udp-портов, например —udp=700-900,65500. Опционально, при условии наличия параметра —tcp.
-
—clients <clients> опциональный список разрешенных клиентов, например —clients=Client1,Client2 если этот параметр опущен, то не будет проверок доступа для подключаемого клиента
Например, строка запуска входного туннелирования около 50-ти tcp/udp портов на три клиента будет выглядеть так:
TutoProxy.Server http://200.100.10.1:8088 --tcp=3389,8071-8073,10000-10010,20000-20010 --udp=5000-5010,7000-7010 --clients=Client0Linux,ClientSecLinux,Client3Win
Приложение TutoProxy.Client — это клиент туннелирования выходного трафика.
Аргументы его запуска:
-
<server>, адрес сервера TutoProxy.Server, например http://200.100.10.1:8088
-
<sendto>, IP получателя данных, например 127.0.0.1
-
—id <id>, ID клиента, например —id=Client1
-
—tcp <tcp>, список tcp-портов, например —tcp=80,81,443,8000-8100. Опционально, при условии наличия параметра —udp.
-
—udp <udp>, список udp-портов, например —udp=700-900,65500. Опционально, при условии наличия параметра —tcp.
Например, строка запуска выходного туннелирования 5-ти tcp и 3-х udp портов будет выглядеть так:
TutoProxy.Client http://200.100.10.1:8088 127.0.0.1 --tcp=8071,10000,20004-20006 --udp=7000-7002 --id= Client0Linux.
Важно учесть то, что порты у различных TutoProxy.Client не должны пересекаться, т.е. каждый клиент обслуживает уникальный набор сокетов/портов.
Данное решение также может подойти для разворачивания веб-сервисов на «серых» IP, т.е. можно сэкономить на дорогостоящем VPS.
Известные на данный момент недостатки:
-
Оверхед трафика, для его минимизации используется MessagePack.
-
Нет поддержки keep-alive на выходе туннелей. Вероятно в будущем придется добавить парсинг http заголовков на входе в туннель, чтобы активировать keep-alive хотя бы для http трафика
ссылка на оригинал статьи https://habr.com/ru/post/709002/
Добавить комментарий