Ваш клиент VPN на IPv6 доходит до рабочей нагрузки, рабочая нагрузка отвечает в туннель, а ответ так и не приходит. Первый инстинкт — винить межсетевой экран или туннель, и обычно ни то, ни другое не виновато. Адрес, который выдаёт OpenVPN, — это внутренняя сеть, существующая только внутри туннеля; Google Cloud понятия не имеет, что fd42:90::/64 должен находиться за одной конкретной ВМ, пока вы ему не скажете.

Этот факт должны усвоить две отдельные системы, и только одна из них — OpenVPN. VPC нужен маршрут, прежде чем он сможет что-то отправить назад, а ВМ должно быть разрешено пересылать то, что приходит. Ошибётесь в любой из двух половин — и симптом будет выглядеть одинаково.

Пул — это внутренняя сеть, а не подсеть

OpenVPN может выдавать адреса IPv6 из диапазона, который вы выберете, и этот диапазон — фикция, о которой договариваются два конца туннеля. Он не является подсетью Google Cloud, не появляется в списке подсетей VPC, и сетевой интерфейс ВМ не получает эти адреса. Поэтому рабочая нагрузка, отвечающая клиенту, отправляет пакет на адрес, который сеть считает немаршрутизируемым.

Держите пул вне каждого диапазона, который VPC уже использует. Держите его и вне диапазонов за вашими другими туннелями. Перекрытие превращает чистый отказ маршрутизации в периодический, который проявляется только под нагрузкой.

Уникальная локальная адресация, такая как fd42:90::/64, — разумный выбор для этой внутренней сети. Префикс также напоминает, что дизайн по своей природе приватен. Ничто в пуле ULA не делает его законным источником в публичном интернете.

Дайте VPC пункт назначения и следующий шаг

Ответу нужен маршрут VPC, пункт назначения которого — пул, а следующий шаг — ВМ VPN. Текущая документация по статическим маршрутам охватывает диапазоны назначения IPv6 и перечисляет, какие типы следующего шага допустимы, поэтому проверьте поддерживаемую форму для вашей топологии, а не копируйте старый пример IPv4.

Адрес следующего шага должен быть тем, который фактически назначен облачному интерфейсу инстанса. Внутренний адрес туннеля ВМ — не этот адрес. Если всё же использовать его, получится маршрут, который чисто устанавливается и никогда не совпадает с пакетом. Прочитайте список интерфейсов, прежде чем писать маршрут.

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

gcloud compute routes create vpn6-return \
  --network=vpn-vpc \
  --destination-range=fd42:90::/64 \
  --next-hop-instance=openvpn-vm \
  --next-hop-instance-zone=europe-west1-b

Пересылку нужно включить дважды

Маршрут доставляет пакет инстансу. Он не делает инстанс готовым пересылать то, что ему не адресовано, и это разрешение существует на двух уровнях.

Облачной стороне нужна включённая способность пересылки инстанса; это параметр, который позволяет ВМ принимать трафик для адресов, которыми она не владеет, и передавать его дальше. Гостевой стороне нужна собственная пересылка IPv6, потому что ядро принимает отдельное решение после прихода пакета. Оба должны быть включены, прежде чем единственный ответ пересечёт туннель.

sysctl -w net.ipv6.conf.all.forwarding=1

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

Скажите OpenVPN, кому что принадлежит

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

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

Держите выход в интернет вне этого дизайна

Приватный доступ и доступ в интернет — отдельные планы. Пул ULA может достигать рабочих нагрузок VPC через туннель, когда маршрутизация и пересылка согласованы, а у этого же пула нет пути в публичный интернет через VPC, потому что облачный шлюз не примет произвольный источник туннеля как свой.

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

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