После смены IP сервера правило SNAT по-прежнему называет старый
Туннель может подключиться, но каждый пересылаемый пакет застревает, потому что правило трансляции по-прежнему переписывает на адрес, которым хост больше не владеет.
Сервер переехал на новый адрес, клиенты по-прежнему подключаются, и ничего из того, что они отправляют, не доходит до интернета. Именно это разделение и есть подсказка: слушающий сокет и проброс порта пережили переезд, поэтому туннель поднимается, а трансляция источника, применяемая к пересылаемым пакетам по-прежнему называет адрес, которым хост больше не владеет. Ответы на эти переписанные пакеты уходят на машину, которой больше нет.
Подключение и пересылка отказывают в разных местах
Установка зависит от конечной точки, которую клиенты уже знают: публичного адреса, проброса порта перед ним и слушателя внутри. Пересылаемый трафик зависит от второго решения, принимаемого после того, как пакет попадает в туннель, когда хост переписывает свой источник, чтобы ответы нашли обратный путь.
Смена адреса ломает только второе решение, и поэтому симптом читается как "подключено, но без интернета". Это же объясняет, почему обычные проверки на стороне клиента выглядят здоровыми: рукопожатие завершается, клиент получает адрес, и даже ping на туннельный адрес сервера может ответить. Часы тратятся на клиента из-за неисправности, которая живёт на другой стороне, поэтому таблица правил — первое место, куда стоит смотреть.
Прочитайте правило и его счётчики перед редактированием
Выведите правила трансляции со счётчиками и сравните настроенный источник с адресами, которые хост действительно держит. Правило, переписанное на мёртвый адрес, обычно показывает трафик на входе, потому что пакеты до него доходят и транслируются, и ничего на обратном пути.
sudo iptables -t nat -L POSTROUTING -n -v --line-numbers
ip -4 addr show
Проверьте три поля, пока вы там: пул в совпадении источника, выходной интерфейс, если правило его называет, и исключение, которое не даёт переписывать трафик между туннелями. Это исключение легко потерять при редактировании, а его потеря создаёт видимость работающего трафика между узлами, хотя его ответы идут странным путём.
Если счётчики стоят на нуле, пакеты никогда не доходят до этого правила, и адрес здесь ни при чём. Ищите конкурирующее правило выше по цепочке, что бывает, когда кто-то добавляет замену вместо правки оригинала. Сравните номера правил с выводом, который вы записали минуту назад. Порядок — часть конфигурации, а не косметическая деталь.
Замените источник или перестаньте его называть
Если у хоста стабильный адрес, замените правило на месте, а не добавляйте ещё одно. Замена по номеру правила сохраняет порядок, от которого зависит остальная цепочка.
sudo iptables -t nat -R POSTROUTING 1 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source 10.151.0.40
Когда адрес выдаётся динамически, не называйте источник вообще и дайте ядру выбрать текущий из выходного интерфейса. Этот вариант переживает следующий переезд без правки, ценой того, что скрывает, какой адрес использовался.
sudo iptables -t nat -R POSTROUTING 1 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -o eth0 -j MASQUERADE
Убедитесь, что пересылка IPv4 по-прежнему включена через управляемую конфигурацию, затем закрепите правило собственным механизмом дистрибутива. Изменение, сделанное только в работающем ядре, вернётся при следующей перезагрузке, обычно в окно обслуживания, которое никто не связывает с изменением.
Два способа ошибиться с заменой
Трансляция пула на туннельный адрес сервера вместо его LAN-адреса отправляет ответы прямо назад в туннель, где они маршрутизируются к клиенту, который их никогда не запрашивал. Соединение застревает так, что это похоже на петлю маршрутизации, потому что это она и есть.
Наслоение второй трансляции поверх старой — другая ошибка. Побеждает первое подходящее правило, поэтому устаревшая запись продолжает обрабатывать пакеты, пока её не удалят, а счётчики нового правила остаются на нуле, пока все винят замену. Удалите дубликат, прежде чем добавлять что-то новое. Затем прочитайте список ещё раз и убедитесь, что пулу соответствует ровно одна трансляция.
Если туннель несёт и IPv6, повторите весь обзор на другом стеке. Маршрут по умолчанию IPv6 без трансляции и без маршрутизируемого префикса отказывает так же тихо, и это легко забыть, потому что всё выше выглядит одинаково.
Входящим службам нужна обратная трансляция
Службе на клиенте VPN, которая должна быть доступна снаружи, нужна трансляция назначения, а не источника: публичный порт переписывается на туннельный адрес клиента до входа. Затем пути пересылки нужно явное правило, разрешающее этот трафик.
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.9.8.2:8080
Никогда не транслируйте порт, который несёт сам туннель, потому что это переписывание прерывает соединение, поддерживающее доступность службы. Держите туннельный порт полностью вне правил назначения. В конце проверьте с обеих сторон: счётчики на новом правиле, короткая запись на туннельном устройстве и один запрос на адрес внутри туннеля, прежде чем пробовать публичный.