Возможно, вы когда-нибудь задумывались о том, как на определенной машине под управлением MS Windows перенаправить входящий траффик в другой сетевой интерфейс, на другой адрес и другой порт? Такая возможность есть, называется она portproxy. Сделать это совсем несложно и я объясню как, но сначала — небольшая предыстория.

Наверное, не стоит судить об организации только на основании того, какие у них в ходу решения и технологии, но иной раз так и хочется «навесить ярлык» на очередную фирму. В этот раз история пойдет о крупной транспортной конторе для которой мы сначала делали, а потом интегрировали целый «проект». И, если обычно в цивилизованном мире для предоставления доступа посредством VPN используют решения, такие как SSTP, L2TP/IPsec, OpenVPN или даже WireGuard (т.е.открытые и общедоступные технологии), то некоторых хлебом не корми, дай подложить свинью в виде Cisco Any Connect, GlobalProtect или даже RadminVPN. Наш заказчик использовал именно Cisco Any Connect, причем, отнюдь не ванильное решение — на клиентские машины с Windows поставлялись какие-то явно самопальные, но брендированные дистрибутивы. Была заявлена (формально) поддержка Linux и MacOS, но на поверку поставляемые решения оказались просто-напросто неработоспособными (о чем, как оказалось, заказчик знал, но сообщить не посчитал нужным). Признаюсь, даже на этом этапе во мне еще теплилась надежда, что можно поднять VPN-клиент на роутере (как я обычно поступаю) и красиво маршрутизировать траффик на машины наших разработчиков, работающих удаленно и использующих, в основном, Arch и Ubuntu в качестве операционных систем. Развернув в виртуалке чистую Windows, я установил дистрибутив Cisco Any Connect, после чего попробовал подключиться к серверу заказчика по ранее переданным мне реквизитам. Всплывающее окошко радостно сообщило, что «подключение успешно установлено», однако что-то было явно не так. Присмотревшись внимательнее я увидел, что при подключении к заказчику практически все прежние имеющиеся сетевые маршруты (которые у меня анонсирует роутер) были просто-напросто перекроены. Если бы я установил этот Cisco Any Connect на свою девелоперскую машину, то это был бы тот еще гемморой. В такой ситуации я предпринял самый разумный и логичный шаг, я спросил у заказчика — как вы вообще собираетесь нам предоставлять необходимый доступ? Мы же, дескать, обговаривали вопросы доступа заранее, я вам четко обозначил возможные варианты, вы подтвердили, что проблем не будет. «Проблемы негров шерифа не интересуют» — примерно так ответил заказчик на этот раз, после чего для успокоения совести я пробежался по репозиториям, почитал профильные форумы, посоветовался с несколькими знакомыми — и, к сожалению, все вело к тому, что адекватного решения «здесь и сейчас» нет, нужно было тратить определенное количество времени (достаточно ограниченного) без гарантии результата. Все выводы я изложил генеральному, после чего получил полный карт-бланш на оперативное решение проблемы.

В работе случается всякое, сейчас мы сами примерим значок шерифа, а вот заказчику придется перевоплотиться в негра. Возвращаемся в виртуалку с поднятой Windows и установленным клиентом Cisco Any Connect. Проверяем настройки виртуальной машины, в частности, тип подключения к сети — сетевой мост. В самой Windows видим, что при подключении к заказчику поднимается отдельный интерфейс виртуальной сетевой карты, ему присваивается определенный адрес. Открываем службы, ищем пункт «Вспомогательная служба IP» — меняем тип запуска на «Автоматически», после чего запускаем эту службу. Эта служба, как следует из описания, «Обеспечивает возможность туннельного подключения с помощью технологий туннелирования для IP версии 6 (6to4, ISATAP, порты прокси и Teredo), а также IP-HTTPS», из всего этого перечня нам нужно только проксирование портов.

Теперь открываем командную строку от имени администратора. Пусть у первого адаптера виртуальной машины будет адрес 192.168.0.50, у адаптера Cisco Any Connect 10.0.70.60, а адрес удаленного сервера заказчика — 10.0.77.66 (будем считать, что предварительно мы посмотрели маршруты и на 10.0.77.66 можно попасть через шлюз интерфейса Cisco Any Connect). На текущем этапе наша виртуальная машина смотрит сразу в две сети — нашу основную (и, посколько она подключена бриджем, то мы видем её на роутере наряду с другими компьютерами) и сеть заказчика. Пишем в командной строке следующее:

netsh interface portproxy add v4tov4 listenport=1234 listenaddress=192.168.0.50 connectport=8084 connectaddress=10.0.77.66

Тем самым мы обозначаем, что если на нашу виртуальную машину кто-то постучится извне на порт 1234, то, фактически, он постучится на сервер заказчика 10.0.77.66 на порт 8084. Таким образом мы сделали проксирование не только портов, но получили возможность направлять траффик вообще в другую сеть. Далее, тут же в командной строке проверяем локальный порт 1234:

netstat -na|find "1234"

Если все сделано правильно, то вы увидите, что порт 1234 теперь прослушивается. По образу и подобию можно указать и другие порты для проброса. Просмотреть весь список проброшенных таким образом портов можно следующей командой:

netsh interface portproxy show all

Чтобы удалить отдельное взятое правило, нужно сделать следующее:

netsh interface portproxy delete v4tov4 listenport=1234 listenaddress=192.168.0.50

А чтобы полностью удалить все имеющиеся правила подойдет эта команда:

netsh interface portproxy reset

Общие принципы, я думаю, понятны. Особо стоит отметить, что таким образом можно перенаправлять траффик только для TCP портов. Траффик на UDP порты перенаправить не выйдет, помимо этого нельзя использовать 127.0.0.1 в качестве адреса назначения. Для настройки перенаправления UDP траффика можно использовать Windows Server с ролями RRAS и NAT (помимо командной строки можно будет использовать графическую оснастку rrasmgmt.msc). Официальная документация по portproxy находится здесь.

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