Шлюз может выдать мобильному пользователю и IPv4-, и IPv6-виртуальный адрес, тогда как внешний туннель по-прежнему идёт поверх IPv4. Это независимые решения, и именно их рассмотрение как одного — то место, где планы двойного стека обычно разваливаются. Внутренние семейства клиента, защищённые префиксы, до которых он может дотянуться, и транспорт, который несёт инкапсуляцию, — это три отдельных выбора.

Большая часть путаницы возникает из-за того, что слово «двойной стек» применяют к проекту, который является двойным стеком только в одном месте. Служба может быть двойным стеком внутри, одиночным стеком на своём внешнем адресе и всё равно прекрасно работать для клиентов. Чего она не может — работать случайно.

Два семейства внутри, один путь снаружи

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

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

Дайте клиенту адрес в каждом семействе

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

pools {
  pool4 { addrs = 10.90.0.0/24 }
  pool6 { addrs = fd42:90::/64 }
}
connections {
  private-access {
    version = 2
    pools = pool4, pool6
    local  { auth = pubkey  certs = gateway.pem  id = vpn.example.com }
    remote { auth = pubkey  cacerts = ca.pem  vips = 0.0.0.0, :: }
    children {
      private { local_ts = 10.60.0.0/16, fd42:60::/48  remote_ts = dynamic }
    }
  }
}

Значение vips запрашивает по одному адресу из каждого семейства, а список пулов решает, откуда берутся эти адреса. Документация strongSwan о виртуальных IP-адресах охватывает множественные запросы и распределение по пулам, включая тот момент, что клиент, запрашивающий конкретный адрес, лишь выражает предпочтение, которое отвечающая сторона может отменить. Не создавайте правило доступа, которое предполагает, что клиент всегда получает одно и то же значение.

Сгенерируйте собственный уникальный локальный префикс вместо копирования примера. Две организации, которые обе fd42::/16 внедрят его, обнаружат конфликт при первом же соединении друг с другом, и диагностировать это неприятно.

Селекторы описывают назначения, а не источники

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

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

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

DNS и путь ответа решают, выглядит ли это завершённым

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

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

Проверьте оба семейства, прежде чем объявить это готовым

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

swanctl --list-sas
swanctl --list-pools
ip -6 addr show scope global
ip -6 route get fd42:60::10

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

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

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