Почему сервер за VPN-клиентом отвечает через туннель
Входящие подключения не проходят, когда ответы идут по маршруту по умолчанию VPN вместо пути прибытия. Маршрутизация по политике или NAT источника восстанавливает обратный путь.
Входящие подключения к хосту, на котором также работает VPN-клиент, не проходят очень специфическим образом: рукопожатие приходит, демон отвечает, а клиент не получает ничего обратно. Ничто не блокирует порт. Ответ ушёл через туннель, потому что туннель владеет маршрутом по умолчанию, а ядро маршрутизирует ответы по назначению, а не по памяти о том, откуда пришёл запрос. Это единственное упущение объясняет каждый следующий симптом.
Ответ маршрутизируется, а не запоминается
VPN-клиент, устанавливающий маршрут по умолчанию, добавляет запись, которая превосходит шлюз LAN, — либо по метрике, либо разделяя пространство на две более конкретные половины. Исходящие пакеты теперь выбирают интерфейс туннеля. Ядро никогда не спрашивает, откуда изначально пришёл пакет, на который отвечают. Это единственное упущение объясняет каждый следующий симптом.
Прямое направление маршрутизируется по назначению, и обратное тоже. Ответ адресован публичному клиенту, которого туннель охотно понесёт. Дальний конец получает пакет, источник которого ему не принадлежит, отбрасывает его, а исходный клиент ждёт, пока не истечёт время.
Строгая фильтрация обратного пути может отбросить входящий пакет ещё до того, как демон его прочитает. Сначала проверьте этот счётчик, потому что отбрасывание фильтром и ошибка маршрутизации снаружи выглядят одинаково.
ip route show default sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.eth0.rp_filter nft list ruleset | grep -A3 'hook forward'
Первая команда показывает, какой маршрут по умолчанию побеждает сейчас. Вторая сообщает, действует ли строгая фильтрация глобально или для каждого интерфейса, а третья показывает любое правило цепочки пересылки, которое может быть задействовано.
Три способа сохранить обратный путь
Исключение назначения службы из туннеля — самый узкий вариант. Маршрут к хосту, направленный на шлюз LAN, плюс демон, привязанный к физическому адресу вместо всех адресов, держит этот единственный поток вне туннеля. Изменение локально и легко отменяется.
Маршрутизация по политике — общий ответ. Правило, привязанное к адресу источника или к метке брандмауэра, выбирает таблицу, маршрут по умолчанию которой указывает на шлюз WAN, а собственные соединения хоста продолжают использовать туннель. Держите приоритет явным, чтобы правило не было позже затенено.
ip rule add from 203.0.113.25/32 table 100 priority 100 ip route add default via 192.0.2.1 dev eth0 table 100 ip route get 198.51.100.7 from 203.0.113.25
Первые две команды строят альтернативный путь для ответов с источником в публичном адресе. Третья спрашивает ядро, какой путь выберут именно этот источник и назначение, и так вы подтверждаете, что правило вообще действует.
Трансляция источника — третий вариант и единственный, который выживает перед маршрутизатором, уже выполняющим NAT перед службой. Ответ должен вернуться к этому маршрутизатору, и маскарадинг на интерфейс WAN достигает этого, скрывая клиента из журналов службы. Замена маршрута по умолчанию вручную после подключения — это диагностика, потому что клиент перепишет таблицу при следующем переподключении.
Когда машина маршрутизирует и для LAN
Та же неисправность проявляется на один шаг дальше, когда хост маршрутизирует для устройств за собой. Входящее соединение перенаправляется на внутреннее устройство, единственный обратный путь которого — туннель, и ответ достигает внешнего клиента с адреса провайдера. Внутреннее устройство всё это время работает правильно.
Тогда отслеживание соединений видит ответ для потока, который никогда не записывало, и отбрасывает его. Трансляция назначения доставляет входящее соединение устройству, а трансляция источника заставляет ответ выглядеть так, будто он исходит от самого маршрутизатора.
Правило политики, удерживающее перенаправленный порт на WAN, пока собственный трафик маршрутизатора использует туннель, — более чистый эквивалент. Без трансляции источника ответ адресован внешнему клиенту, и у внутреннего устройства вообще нет маршрута к этому адресу.
Три проверки, разделяющие причины
Выполните три проверки: соединение внутрь машины из интернета, соединение из неё к публичному хосту и поиск имени. Когда первые две расходятся, виноват обратный путь. Когда имена не разрешаются в обе стороны, распознаватель — другая неисправность, которая лишь делит туннель.
Сначала исправьте вопрос маршрутизации, затем смотрите на имена. Смешивать оба — это способ обвинить работающий сервер в сломанном распознавателе.
Запишите, какой интерфейс называет исключение, и держите конфигурацию под контролем версий. Правило, написанное для интерфейса, который переименовывают после обновления, проходит сегодня и не проходит после следующей перезагрузки.