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

Куда на самом деле попадает перенаправленный пакет

Прозрачный прокси на шлюзе использует REDIRECT в таблице nat при PREROUTING, чтобы переписать назначение входящего соединения на локальный порт. Переписанное назначение — это локальный адрес с точки зрения интерфейса, на который пришёл пакет, а не адрес loopback процесса, запущенного где-то ещё. Слушатель, привязанный только к 127.0.0.1, принимает соединения, которые уже были локальными на хосте, и именно этот случай продолжает работать, пока трафик туннеля терпит неудачу. Собственный loopback клиента — это третий адрес, и он никогда не является целью правила шлюза.

Поэтому, прежде чем трогать учётные данные верхнего уровня, установите два факта: на какой локальный адрес переписывает правило и к какому адресу привязан сокет прокси.

Читайте слушатель и правило перенаправления вместе

Выведите таблицу сокетов и правила nat за один проход, потому что правило, указывающее на порт, которым никто не владеет, выглядит так же, как правило, указывающее на неправильный адрес. sudo ss -ltnp | grep redsocks показывает адрес привязки и процесс-владелец. sudo iptables -t nat -S PREROUTING показывает цель REDIRECT, а sudo iptables -t nat -L PREROUTING -v -n показывает, совпало ли с ним что-нибудь.

Переход в пользовательскую цепочку с именем REDSOCKS ничего не даёт, если эта цепочка не существует и не несёт нужные исключения и действие REDIRECT. Читайте цепочку, в которую выполняется переход, с помощью sudo iptables -t nat -S REDSOCKS, а не предполагайте, что имя делает работу.

Затем сравните два значения. Если правило перенаправляет на адрес шлюза на порту 12345, а слушатель сообщает 127.0.0.1:12345, несоответствие объясняет сбой без какой-либо дополнительной диагностики.

Привязывайте узко, а затем ограничьте, что может до него добраться

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

Открывать порт на публичном интерфейсе для перенаправленного трафика VPN не требуется никогда, потому что соединение завершается локально после переписывания. Не выставляйте прокси в интернет, чтобы заработало локальное перенаправление.

Докажите это новым соединением от клиента

Проверяйте с реального клиента VPN новым TCP-соединением, а не из оболочки на шлюзе. curl -sS -o /dev/null -w '%{http_code}\n' http://example.com на клиенте проходит перенаправленный путь от начала до конца.

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

Наконец, помните, что этот путь не покрывает. Обычное перенаправление TCP в redsocks не превращает UDP, QUIC или DNS в трафик SOCKS, а частные назначения обычно требуют явных исключений. Успешный локальный тест доказывает только путь через loopback, который никогда не был проблемой.

Похожие статьи