Публичный префикс через OpenVPN: исправить обратный путь
Маршрутизируемый публичный префикс может пройти через TUN-соединение OpenVPN, но ответы должны возвращаться тем же путём. Делегируйте префикс и сохраните публичный адрес источника.
Наблюдайте, как поднимается туннель и клиент пингует противоположную сторону, а затем публичный адрес, который должен находиться за VPN, отвечает откуда-то ещё или не отвечает вовсе. Этот симптом обычно никак не связан с шифром или сертификатами. Префикс, маршрутизируемый провайдером, доставляется как IP-маршрут, и перенести его через OpenVPN значит воспроизвести этот маршрут на двух уровнях и сохранить адрес источника на обратном пути. Делать мост на WAN не требуется, и добавление адреса на интерфейс не создаёт вышестоящий маршрут.
Префикс сначала должен быть маршрутизирован к вам
Спросите провайдера, как доставляется блок. Префикс, маршрутизированный на основной адрес вашего сервера, — это не то же самое, что адреса, которые провайдер ожидает увидеть напрямую в сегменте WAN. Только первая модель работает с описанной здесь схемой.
Если провайдер маршрутизирует 198.51.100.64/28 на ваш входной сервер, пакеты этого диапазона приходят на сервер и останавливаются там, если вы их не пересылаете. Если же провайдер делает мост диапазона на ваш uplink, сервер должен отвечать на ARP за него, а это другая проблема.
Проверьте модель доставки до того, как трогать OpenVPN: снаружи пингуйте адрес из блока и смотрите, какой интерфейс его принимает. Если ничего не приходит, никакая настройка туннеля не поможет. Если адрес отвечает напрямую на WAN, провайдер делает мост, а не маршрутизирует, и схема ниже не применяется.
Два уровня маршрутизации: маршрут ядра и iroute
OpenVPN нужен префикс в двух местах. Ядро должно знать, что префикс принадлежит туннельному устройству, чтобы пересылаемые пакеты попадали в OpenVPN, а не в маршрут по умолчанию. OpenVPN также должен знать, какой аутентифицированный клиент владеет префиксом, и это запись iroute в каталоге для конкретного клиента.
Маршрут на стороне сервера выглядит так, причём префикс и маска должны соответствовать выделению:
ip route add 198.51.100.64/28 dev tun0
Конфигурация для конкретного клиента назначает владение. Поместите её в файл CCD, названный по общему имени сертификата клиента, и убедитесь, что именно этот каталог сервер действительно читает:
iroute 198.51.100.64 255.255.255.240
Документация OpenVPN о маршрутизируемых сетях описывает оба уровня и то, почему они разделены. Маршрут ядра без iroute отправляет пакеты в туннель без владельца, и OpenVPN их отбрасывает. iroute без маршрута ядра оставляет пакеты на пути по умолчанию сервера. Обе ошибки со стороны клиента выглядят как сломанный туннель.
Где живёт адрес службы
Делегированный префикс — не то же самое, что собственные адреса туннеля. При желании пронумеруйте линк из приватного пространства и разместите публичный адрес службы там, где служба действительно работает.
На Linux-клиенте, который завершает службу локально, достаточно одного адреса хоста:
ip address add 198.51.100.70/32 dev lo
Если префикс маршрутизируется дальше на хост VM или другую LAN, настройте вместо этого этот нисходящий путь и его обратный маршрут. Назначать каждый адрес блока VPN-клиенту не нужно, и это создаёт конфликты позже.
Сохраните публичный источник на обратном пути
Ответ из делегированного префикса должен выйти через туннель и достичь маршрута провайдера. Если удалённый хост отправляет его через своего ISP, адрес источника выглядит поддельным, и провайдер или получатель его отбрасывает. Решение — правило на основе источника или отдельная таблица маршрутизации, а не более широкий NAT. Без него служба работает от партнёра по туннелю и отказывает отовсюду ещё.
На входном сервере широкое правило masquerade — обычный виновник. Оно переписывает публичный источник на основной адрес сервера, и клиент никогда не видит настоящий:
iptables -t nat -S POSTROUTING
Ограничьте NAT теми приватными VPN-клиентами, которым он нужен, и оставьте делегированный префикс непереведённым. Затем убедитесь, что сервер вообще пересылает префикс, потому что цепочка пересылки с запретом по умолчанию тихо его отбрасывает.
Проверьте оба направления, прежде чем доверять
Проверка — это четыре наблюдения, а не одно. Убедитесь, что маршрут провайдера приходит, ядро отправляет префикс в туннель, OpenVPN привязывает его к нужному клиенту, а ответ возвращается с нетронутым публичным источником. У каждого наблюдения своя команда, поэтому сбой указывает на уровень, а не на всю схему. Выполняйте их в этом порядке после каждого изменения конфигурации.
Спросите ядро, какой путь выбирает делегированный адрес, и наблюдайте за туннелем, пока выполняется запрос:
ip route get 198.51.100.70
sudo tcpdump -ni tun0 host 198.51.100.70
Фильтрация обратного пути может отменить правильный маршрут. Проверьте действующую настройку на туннеле и на uplink и помните, что строгий режим отклоняет трафик, источник которого не совпадает с интерфейсом, через который он пришёл:
sysctl net.ipv4.conf.tun0.rp_filter net.ipv4.conf.eth0.rp_filter
Наконец, проверьте случай отказа. Остановите туннель и убедитесь, что публичный префикс не утекает через обычный uplink. Восстановление VPN должно вернуть службу, не расширяя набор портов, которые открывает хост.