Вопрос или проблема
Я хочу перенаправить весь трафик, который обычно идет на определенный TCP порт на remotehost
(до которого я могу добраться через openvpn), вместо этого на localhost
, где у меня есть прослушивание ssh-переадресации на этом порту. Я пробую это с такой настройкой:
На remotehost
для тестирования:
nc -l -p 12345 -k -v
На MacBook:
sudo sysctl -w net.inet.ip.forwarding=1 # не должно быть нужно
echo 'rdr pass proto tcp from any to any port 12345 -> 127.0.0.1 port 12345
pass out route-to (lo0 127.0.0.1) proto tcp from any to any port 12345' | sudo pfctl -e -f -
ssh -4 -L 12345:127.0.0.1:12345 remotehost
На тесте MacBook:
echo foo | nc -v remotehost 12345
Идея заключается в том, что я могу “симулировать” на MacBook, что могу добраться до remotehost
на TCP порту 12345, когда на самом деле у него открыт только SSH порт 22.
Вышеуказанные команды работают, когда remotehost
является, например, общедоступным сервером Linux, но это не работает, когда это сервер Linux, который можно достичь только через openvpn
. Это должно быть связано с преобладанием таблицы маршрутов над PF, поскольку, когда я добавляю эту запись:
sudo route add -net <remotehost>/32 -iface lo0
Переадресация PF внезапно начинает работать, но больше не работает трафик SSH туннеля.
Я попытался воспроизвести это на FreeBSD, но, к моему удивлению, там обе работали безупречно, с VPN или без, так что проблема, вероятно, специфична для macOS.
Есть ли у кого-нибудь идея, как я мог бы достичь этого на macOS тоже? Как-то запись в таблице маршрутов, которую добавляет openvpn
, обходит правило pfctl
.
Я нашел эти ссылки, которые, кажется, относятся к связанным вопросам, но не помогли мне:
Ответ или решение
Для перенаправления исходящего трафика VPN на macOS с определённого порта на localhost, особенно в контексте вашего случая, необходимо учитывать несколько факторов. Давайте разберёмся в деталях, шаг за шагом.
Проблема
Вы хотите перенаправить весь трафик, который обычно направляется на определённый TCP-порт на remotehost
, в localhost, где установлен SSH-переадресатор, который слушает на этом же порту. Это необходимо для того, чтобы обмануть систему и сделать так, чтобы macOS думал, что она может получить доступ к remotehost
на TCP-порту 12345, когда фактически доступен только порт SSH (22).
Описание текущей конфигурации
Вы использовали следующие команды для тестирования на remotehost
:
nc -l -p 12345 -k -v
На вашем MacBook выполнено:
sudo sysctl -w net.inet.ip.forwarding=1 # Позволяет IP-переадресацию
echo 'rdr pass proto tcp from any to any port 12345 -> 127.0.0.1 port 12345
pass out route-to (lo0 127.0.0.1) proto tcp from any to any port 12345' | sudo pfctl -e -f -
ssh -4 -L 12345:127.0.0.1:12345 remotehost
Затем вы проверили работу перенаправления с помощью команды:
echo foo | nc -v remotehost 12345
У вас возникли проблемы, когда remotehost
был доступен только через OpenVPN. Вы также заметили, что добавление маршрута к remotehost
через команду sudo route add -net <remotehost>/32 -iface lo0
влияло на работу правила PF.
Решение
-
Настройка PF (Packet Filter)
Убедитесь, что PF корректно настроен. Посмотрите на ваш файл конфигурации PF и убедитесь, что он содержит правильные правила:
echo 'rdr pass proto tcp from any to <remotehost> port 12345 -> 127.0.0.1 port 12345 pass on lo0 proto tcp from any to 127.0.0.1 port 12345' | sudo pfctl -f - # Перезагрузка конфигурации PF
-
Использование правильного интерфейса в маршруте
Поскольку OpenVPN создаёт виртуальный интерфейс, попробуйте явно указать интерфейс OpenVPN в маршруте:
sudo route add -net <remotehost>/32 -interface <vpn-interface>
Здесь
<vpn-interface>
нужно заменить на название интерфейса, который предоставляет OpenVPN, напримерtun0
. -
Проверка конфигурации OpenVPN
Убедитесь, что конфигурация OpenVPN не переопределяет ваши маршруты и не блокирует трафик PF. Отключите дополнительные маршруты в конфигурации OpenVPN, если они есть.
-
Логирование и отладка
Для диагностики попробуйте включить журнал PF. Это поможет вам видеть, какие пакеты обрабатываются:
echo 'set loginterface <vpn-interface>' | sudo pfctl -f -
-
Запуск вашего ssh команды
При установке SSH-туннеля используйте дополнительный параметр
-N
, чтобы не запускать удаленную команду, если это не требуется:ssh -4 -N -L 12345:127.0.0.1:12345 remotehost
Это поможет избежать каких-либо конфликтов с правилами маршрутизации.
Заключение
Если после выполнения всех шагов проблема всё ещё сохраняется, может потребоваться более сложная отладка. Попробуйте использовать утилиты, такие как tcpdump
, для анализа трафика и проверки того, направляются ли пакеты в нужное направление. Убедитесь, что все команды выполняются с правами суперпользователя, так как многие из них требуют таких привилегий для успешного выполнения.
Если у вас есть дополнительные вопросы или вам нужна помощь в конкретных аспектах, не стесняйтесь обращаться!