Кто-то пробрасывает 1723, клиент доходит до сервера, начинается аутентификация, и затем всё останавливается без ошибки. Естественный вывод — неверный пароль, поэтому пароль вводят заново три раза. Проброс был в порядке, и учётные данные были в порядке. Сломался второй протокол, который проброс никогда не покрывал, и значение ядра по умолчанию, которое тихо перестало помогать с ним.

Проброс никогда не был проблемой

Правило проброса порта описывает трафик TCP или UDP. Оно не может описать полезную нагрузку, которая на середине сессии переходит на другой протокол IP, а PPTP делает именно это.

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

TCP для управления, GRE для данных

Вызов согласуется по TCP 1723. Как только он поднят, полезная нагрузка уходит в GRE, протокол IP 47, который вообще не несёт номеров портов. Правилу, опирающемуся на порты, нечего сопоставлять.

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

Голый GRE без PPTP не требует такой перезаписи, поэтому обычный туннель GRE может работать через маршрутизатор, который отказывает клиенту PPTP на том же пути.

Четыре модуля и sysctl, который их выключил

Два модуля отвечают за кадрирование, nf_conntrack_proto_gre и nf_nat_proto_gre. Ещё два отвечают за идентификатор вызова, nf_conntrack_pptp и nf_nat_pptp. Загрузка последнего подтягивает остальные через зависимости, поэтому в списке модулей должны быть все четыре.

Старые инструкции используют префикс ip_ из эпохи 2.6. Эти команды могут выглядеть работающими, ничего не загружая, поэтому проверяйте загруженный список, а не код возврата.

Загруженности уже недостаточно. Начиная с Linux 4.7 sysctl net.netfilter.nf_conntrack_helper по умолчанию равен 0, что отключает автоматическое назначение помощника для новых потоков. У маршрутизатора могут быть все модули, и он всё равно ничего не транслирует. Проверьте действующее значение, прежде чем снова смотреть на список модулей.

Либо снова включите автоматическое назначение глобально, либо привяжите помощник к потокам, которым он нужен, и оставьте всё остальное в покое:

iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptp

Второй вариант предпочтительнее. Он ограничивает поведение трафиком PPTP, вместо того чтобы снова включать автоматическое назначение на всём маршрутизаторе.

Открытие протокола, у которого нет портов

Правило брандмауэра, разрешающее 1723, ничего не говорит о протоколе 47. В firewalld разрешите протокол в зоне, обращённой к клиенту. В обычном iptables примите протокол gre во входной цепочке.

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

После подключения — ограничение размера

GRE вставляет заголовок, а PPP внутри добавляет ещё, поэтому работающее соединение сообщает MTU заметно ниже 1500. Малые ответы загружаются, а большие замирают, что выглядит как вторая, несвязанная проблема, появляющаяся в тот момент, когда решена первая.

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

Ремонт пути возвращает пользователя к работе, и это не делает PPTP хорошим выбором. MS-CHAPv2 и RC4 давно устарели, поэтому относитесь к загрузке модулей как к временному исправлению и планируйте переход на поддерживаемый протокол.

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