Раздельное туннелирование PPTP не работает: сначала исправьте путь GRE
Раздельное туннелирование PPTP сбоит по двум разным причинам: GRE заблокирован или отсутствует внутренний маршрут. Сначала проверьте транспорт, затем политику.
Понаблюдайте, как поднимается соединение PPTP, и легко поверить, что трудная часть позади: клиент проходит аутентификацию, появляется адаптер ppp0 или WAN Miniport, и окно состояния становится зелёным. Затем первый запрос к внутреннему хосту истекает по тайм-ауту, и виноватым оказывается профиль. На практике нужно пройти два независимых слоя: внешний транспорт, несущий TCP 1723 и GRE, и внутреннюю политику, решающую, какие получатели используют интерфейс PPP. Зелёный статус доказывает только то, что первый слой договорился; о втором он не говорит ничего.
Проследите клиент от профиля до управляющего сокета
Откройте журнал клиента и найдите место, где он обращается к серверу. PPTP сначала открывает TCP-соединение к порту 1723 и согласует параметры туннеля по этому каналу. Если этот шаг не удался, всё дальнейшее не имеет значения, и ошибка обычно называет адрес сервера или тайм-аут.
Подтвердите управляющее соединение в сети, прежде чем трогать любой маршрут. На клиенте или зеркальном порту захватите TCP 1723 для одной попытки подключения:
sudo tcpdump -ni any 'tcp port 1723' -c 20
Завершённое рукопожатие и установленная сессия означают, что внешний управляющий канал работает. SYN, который никогда не получает SYN-ACK, указывает на межсетевой экран, неверный адрес сервера или провайдера, фильтрующего порт. Рукопожатие с немедленным сбросом часто означает, что сервер отклонил учётные данные или тип туннеля.
GRE — это второй протокол, а не порт
PPTP несёт полезную нагрузку PPP внутри расширенного GRE, протокола IP 47, у которого нет номера порта, за которым мог бы следить маршрутизатор. Поэтому правило, разрешающее TCP 1723, всё равно может оставить туннель без пути данных. Устройства NAT с состоянием должны понимать идентификатор вызова внутри GRE, чтобы возвращать ответы, и многие этого не делают. Спецификация PPTP держит управляющий канал и полезную нагрузку GRE отдельными частями, и ваш план тестирования обязан быть таким же.
Следите за протоколом 47 в том же захвате, затем сравните, что уходит и что возвращается:
sudo tcpdump -ni any 'proto gre' -c 20
Пакеты, уходящие без ответов, пока TCP 1723 остаётся здоровым, — классическая подпись заблокированного GRE. Проброс PPTP на домашнем маршрутизаторе — функция именно этой прошивки, поэтому работающая гостиничная сеть ничего не доказывает о следующей. Если маршрутизатор не предлагает проброс и вы не можете его изменить, проблема в выборе протокола, а не в таблице маршрутов.
Докажите, что туннель передаёт один пакет
Как только GRE пошёл, согласование PPP назначает адрес интерфейсу клиента. Прочитайте назначение, а не предполагайте его:
ip -4 addr show ppp0
Пропингуйте адрес партнёра, показанный как пункт назначения связи точка-точка. Ответ на этом этапе доказывает, что инкапсулированный путь работает от конца до конца и что сервер отвечает внутри туннеля. Если партнёр отвечает, а внутренние хосты нет, внешний транспорт в порядке, и сбой перешёл внутрь.
Сделайте это до добавления любого раздельного маршрута. Изменение маршрута при сломанном транспорте создаёт вторую переменную и скрывает первую.
Напишите раздельную политику, включая DNS
Раздельная маршрутизация — это список решений, а не флажок. Каждому частному префиксу, который должен пройти через туннель, нужен маршрут через интерфейс PPP, а каждый префикс, который должен остаться локальным, должен в нём отсутствовать. Маршрут к подсети приложения без соответствующего маршрута к её частному резолверу — частый способ создать сбой, который выглядит как сломанное приложение.
Проверьте решение, которое ядро принимает для одного адреса в каждой категории:
ip route get 10.20.5.10
ip route get 203.0.113.25
Первый должен назвать ppp0, второй — обычный шлюз. Если оба называют один и тот же интерфейс, политика вовсе не разделена. Добавьте собственный адрес DNS-сервера в туннельный список, иначе разрешение имён для внутренних хостов уходит через локальный резолвер и не возвращает ничего полезного.
Повторяемая проверка в пять шагов
Запускайте слои по порядку и остановитесь на первом, который сбоит: управляющий канал, видимость GRE, ответ партнёра PPP, раздельный маршрут для одного внутреннего адреса и запрос приложения через туннель. У каждого шага своя команда, поэтому сбой можно отнести к причине, а не считать загадкой.
Компактная версия для клиента Linux выглядит так:
sudo tcpdump -ni any 'tcp port 1723 or proto gre' -c 40
ip -4 addr show ppp0
ping -c 3 192.0.2.1
ip route get 10.20.5.10
В Windows действует тот же порядок с route print и состоянием адаптера, показанным в клиенте. PPTP — устаревший протокол, и если сервер предлагает SSTP или IKEv2, переход обычно лучше использует время, чем настройка пути, зависящего от прохождения протокола 47 на каждом хопе. Проверьте сертификат и договор аутентификации замены, вместо того чтобы копировать старый профиль в новый выпуск.