Ваш туннель поднят, сервис слушает, а офисная LAN всё равно ничего не получает обратно. Никто не ломал VPN. Со стороны LAN адрес туннеля ноутбука не существует, пока что-то не скажет LAN, как до него добраться, и ответ должен вернуться тем же путём, которым ушёл запрос. Я видел, как люди трижды пересобирали полностью исправный туннель, прежде чем кто-то посмотрел на обратный путь.

Сломался не туннель

Оба конца находятся в частных диапазонах, и это нормальный случай, а не ошибка конфигурации. Адрес вроде 10.8.0.6 реален внутри туннеля и нигде больше не существует, поэтому у LAN нет причин что-либо туда отправлять. Прежде чем трогать маршрутизацию, убедитесь, что сервис вообще доступен внутри туннеля: на клиенте ss -ltn показывает, привязан ли слушатель к 127.0.0.1, к интерфейсу LAN или к адресу туннеля. Демон, привязанный только к loopback, не отвечает никому, кроме себя, и никакой маршрут, DNAT или проброс порта этого не меняет.

Прокси на порту 80 или 443 — другой инструмент с другой видимостью. Он перемещает запросы, а не пакеты, поэтому это неверный уровень для прямого подключения к базе данных, и именно обращение к нему приводит к тому, что эта проблема оказывается на три инструмента глубже, прежде чем кто-то что-то измерит.

Форма маршрута: скажите LAN, где находится пул

Статический маршрут на шлюзе LAN — самый чистый ответ, когда LAN и пул туннеля не пересекаются. Направьте пул на машину, которая завершает туннель:

ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12   # Windows, persistent

Это исправляет только одно направление, поэтому недоделанные версии этого изменения выглядят как прогресс. Стороне туннеля нужна соответствующая половина, иначе ответ покидает клиента по его собственному маршруту по умолчанию и погибает в пути:

push "route 192.168.1.0 255.255.255.0"

Для подсети, которая находится за одним клиентом, а не за сервером, серверу нужны и системный маршрут, и запись iroute в файле этого клиента под client-config-dir. Без iroute OpenVPN знает, что префикс существует, и не имеет представления, какой клиент им владеет: пакеты приходят, а демону не с чем их сопоставить.

Вот миф, который стоит назвать. Маршрут делает адрес достижимым; он не делает противоположную сторону готовой ответить. Партнёры «сайт-сайт» добавляют ещё один слой сверху, потому что удалённый шлюз принимает только источники внутри префиксов из своей политики, а ноутбук, приходящий из домашнего пула, в них не входит.

Форма NAT: DNAT внутрь и строка SNAT, которую все пропускают

Когда нельзя трогать шлюз LAN или нужно опубликовать ровно один порт, трансляция на хосте VPN работает вообще без маршрута в LAN. Опубликуйте порт, пробросьте его и транслируйте источник на пути в туннель:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1

Третья строка — та, которая теряется. Пропустите её, и клиент увидит исходный адрес LAN как источник, ответит по своему маршруту по умолчанию, и этот ответ уйдёт в туннель вместо возврата к LAN. Выживет ли соединение, зависит тогда от маршрутизации, которую вы никогда не планировали. С SNAT клиент видит адрес туннеля сервера, поэтому ответ идёт по туннелю назад к единственному хосту, который может отменить трансляцию.

Потребительская прошивка использует собственные имена цепочек и не создаёт эту трансляцию за вас. На Tomato входящее правило попадает в WANPREROUTING, а затем в цепочку фильтрации вроде wanin, и набор правил, который кажется полным, всё равно требует ручной строки POSTROUTING. Это не ошибка прошивки; это набор правил, написанный только для входящего трафика.

Почему правило, которое выглядит правильным, всё равно отбрасывает пакет

Большинство этих сбоев не в том правиле, на которое вы смотрите. Проверьте четыре вещи в этом порядке и остановитесь на первой, которая не выполняется:

  • Порядок цепочек. iptables -I вставляет сверху, а -A добавляет в конец, поэтому более раннее разрешающее или блокирующее правило решает первым.
  • Не та цепочка. Трафик, адресованный самому маршрутизатору, проходит через INPUT, а пересылаемый трафик её никогда не касается. Публикация одного сервиса может требовать правил в обеих.
  • Флаги направления. -i tun0 совпадает с трафиком, приходящим от клиентов, а -o tun0 — с уходящим к ним. REJECT с неверным флагом блокирует то, чего вы не планировали.
  • Ограничение источника. Пересылка, принимающая один адрес клиента, работает от этого клиента и отбрасывает любой другой источник без единого слова.

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

Локальный проброс, когда в LAN ничего нельзя изменить

Локальный проброс SSH обходит весь вопрос. Ему не нужен маршрут в LAN, не нужно сотрудничество брандмауэра клиента и не нужен порт, опубликованный где-либо:

ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host

Тогда сервис появляется на localhost:3000 машины, которая держит туннель, и нигде больше. Это и есть граница: одна рабочая станция, один порт, и проброс умирает вместе с сеансом, если что-то его не перезапустит. Для администратора, проверяющего тестовую базу данных, это правильный инструмент. Для камеры или сканера, до которых должны добраться другие люди, — нет, потому что каждому пользователю понадобился бы свой проброс.

Проверьте оба направления, прежде чем добавлять ещё одно правило

Трансляция оставляет следы, и читать их лучше, чем гадать. На хосте VPN conntrack -L показывает, произошла ли трансляция вообще, iptables -t nat -L -n -v показывает, сдвинулись ли счётчики, а tcpdump -ni any port 3000 показывает, какой адрес источника действительно пришёл. На клиенте ss -ltn подтверждает, что слушатель находится на адресе, до которого туннель может добраться.

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

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