Подключились к OpenVPN, но ничего не загружается: путь от клиента наружу
Туннель поднят, а браузер всё крутится. Идите от клиента наружу: два перехвата, один переключатель в ядре, настоящий интерфейс выхода, затем DNS.
Окно клиента показывает Connected, адрес туннеля есть, а браузер всё крутится. Такое сочетание нормально, потому что успешное рукопожатие доказывает только то, что туннель построен; оно ничего не говорит о том, будет ли сервер пересылать ваши пакеты, переписывать их источник или отвечать на ваши запросы DNS. Ошибка большинства — сначала открыть конфигурацию сервера. Вместо этого идите от клиента наружу, потому что каждый шаг ниже говорит, стоит ли вообще проверять следующий.
Начните с клиента и идите наружу
Выполните три проверки в этом порядке и запишите, где падает первая. Пингуйте адрес туннеля на сервере — это доказывает, что сам туннель несёт трафик. Пингуйте публичный адрес по номеру — это доказывает пересылку и трансляцию без участия разрешения имён. Затем попробуйте разрешить имя хоста — это единственная проверка, которая задействует DNS. Каждый результат снимает целый слой подозрений.
Не перескакивайте к третьей проверке потому, что браузер кажется быстрее. Неудачная загрузка страницы покрывает все три слоя сразу, и именно с неё люди начинают, а потом перестраивают работающий туннель. Страница, которая не открывается, не говорит, какой из трёх слоёв сломан.
Два перехвата показывают, где останавливаются пакеты
Пока с клиента идёт ping на публичный адрес, сделайте один перехват на интерфейсе туннеля и один на вышестоящем канале, который должен выходить в интернет. Запустите оба одновременно, чтобы метки времени совпали.
sudo tcpdump -ni tun0 -c 20 icmp
sudo tcpdump -ni enp1s0 -c 20 icmp
Если запросы видны на туннеле и никогда на вышестоящем канале, сервер отбросил их между туннелем и проводом, и причина — пересылка или политика межсетевого экрана для пересылки, а не NAT. Если они видны на обоих, сервер сделал свою часть, а ответ потерян дальше, что указывает на трансляцию, фильтр выше или ограничение со стороны провайдера.
Берите имя вышестоящего канала из таблицы маршрутизации, а не из руководства. Облачные образы и переименованные адаптеры редко совпадают с примером интерфейса из инструкции, а перехват на неправильном устройстве выглядит точно как сервер, который не пересылает:
ip -4 route get 9.9.9.9
Поле dev в этом выводе — то имя, которое понадобится правилу NAT позже, так что сохраните его.
Пересылка — это переключатель в ядре и политика межсетевого экрана
Ядро должно вообще согласиться пересылать. Прочитайте текущее значение, а затем сделайте настройку постоянной, вместо того чтобы писать её только в работающее ядро:
sysctl net.ipv4.ip_forward
printf 'net.ipv4.ip_forward=1\n' > /etc/sysctl.d/70-vpn-forward.conf
sysctl --system
Пересылка — это только половина. На хосте с UFW политика пересылки задаётся в /etc/default/ufw и должна быть ACCEPT, прежде чем перезагрузка настроек вступит в силу. Отбрасывание по умолчанию на пути пересылки оставляет рукопожатие совершенно здоровым, но молча выбрасывает каждый пакет, который пытается выйти через туннель, — это ровно тот симптом, с которого вы начали.
Хосты, которые управляют nftables напрямую, сталкиваются с тем же вопросом в другом синтаксисе. Смотрите на счётчики цепочки пересылки, пока идёт проверка с клиента, потому что цепочка, к которой обращаются, и цепочка, которая отбрасывает, в файле конфигурации выглядят одинаково.
Назовите настоящий интерфейс выхода в правиле NAT
Трансляция источника относится к интерфейсу, который действительно покидает хост, с пулом, который выдаёт сервер. Обе половины этого правила должны описывать реальность, и ни одна из них не является необязательной.
iptables -t nat -A POSTROUTING -s 10.44.0.0/24 -o enp1s0 -j MASQUERADE
Классическая ошибка — правило, скопированное из руководства, где сказано -o eth0 на машине, чей адаптер называется иначе. Правило устанавливается без предупреждения, ни с чем не совпадает, и у клиента по-прежнему нет интернета. Пул — вторая половина той же ошибки: если сервер выдаёт 10.44.0.0/24, а правило покрывает 10.8.0.0/24, ничто никогда не совпадёт.
Смотрите на счётчики, а не доверяйте тексту правила. Список сообщает пакеты по каждому правилу, и правило, которое никогда не совпадает, остаётся на нуле, как бы правильно оно ни выглядело. Дайте ему минуту настоящего трафика клиента, прежде чем делать выводы из этого числа:
iptables -t nat -L POSTROUTING -v -n
Нулевой счётчик пакетов после настоящей проверки с клиента означает, что совпадение неверно, а не что туннель сломан. Как только оно начнёт совпадать, сохраните набор правил, чтобы он пережил перезагрузку; исправление, которое живёт только в истории вашей оболочки, исчезает при первой же перезагрузке.
Если сервер — это ещё и облачный экземпляр NAT, платформа тоже имеет голос. Экземпляру, который транслирует адреса, обычно нужно отключить проверку источника и назначения там, где провайдер предлагает такую настройку, а сам порт VPN должен быть доступен снаружи.
DNS — вторая поломка за первой
Работающий ping по адресу при падающих именах — это проблема резолвера, и у неё своя причина. Клиент, который сохраняет свой локальный резолвер, отправляет эти запросы в полный туннель и ждёт ответа, который никогда не придёт, потому что локальный резолвер теперь на неправильной стороне маршрута.
Отдайте резолвер с сервера, чтобы клиент знал, куда спрашивать. Две записи дают клиенту запасной вариант, если первая недоступна, и обе должны быть резолверами, которые туннель действительно разрешает.
push "dhcp-option DNS 9.9.9.9"
push "dhcp-option DNS 149.112.112.112"
Клиенты Windows после этого всё равно могут вернуться к локальному резолверу, и именно это призван предотвращать block-outside-dns, ценой потери имён, которые может разрешить только локальная сеть. Клиенты Linux с systemd-resolved часто игнорируют выданный резолвер, если скрипт его не установит, поэтому проверьте resolvectl status для устройства туннеля, прежде чем заключать, что выдачу проигнорировали.
Завершите путь так, как его проживает пользователь. Загрузите настоящую страницу с клиента, подтвердите адрес, с которого она выходит, перезагрузите сервер, переподключитесь и повторите три проверки. Только этот второй проход доказывает, что сохранённые правила, политика межсетевого экрана и выданный резолвер выжили все вместе.