Qeli 0.8.1 · dual-stack и routed IPv6

IPv6 и dual-stack в Qeli

Внешний IPv4/IPv6 carrier, внутренний NetworkPlan v2, ULA/GUA, NAT66 или маршрутизация, DNS, MTU, leak-контроль и безопасная миграция старого профиля.

Два уровня

Внешний carrier и внутренний TUN независимы

Начиная с 0.8.0 Qeli разделяет семейство соединения с сервером и семейства пакетов внутри туннеля. bind/listen/server могут использовать IPv4, IPv6 или hostname с A/AAAA, а tun.ip_mode, пулы и аутентифицированный NetworkPlan определяют внутренний IPv4/IPv6 data plane.

IPv4-carrier может переносить внутренний IPv6, а IPv6-carrier — внутренний IPv4. IPv6-literal в клиентском INI всегда пишется со скобками: server = [2001:db8::10]:443.
Режим профиля

tun.ip_mode = ipv4 | dual | ipv6

РежимЧто получает клиентПрименение
ipv4IPv4 lease, маршруты и DNS.Совместимость или сервер без готового IPv6 uplink.
dualНезависимые IPv4 /32 и IPv6 /128 на L3 TUN, оба набора маршрутов и DNS.Рекомендуемый обычный режим.
ipv6Только IPv6 lease и план.Специализированная IPv6-only сеть; доступа к IPv4-only сервисам без отдельного NAT64 не будет.

NetworkPlan v2 отдельно передаёт assigned address, on-link prefix и gateway для каждого семейства и применяется атомарно. Полуприменённый план не считается успешным подключением.

Базовый профиль

Минимальный dual-stack пример

server.conf · [profile:main]
tun.ip_mode = dual
tun.name = vpn0
tun.address = 10.19.0.1
tun.ipv6_address = fd71:e1:8000:102::1
tun.mtu = 1400
tun.device_type = tun

pool.cidr = 10.19.0.0/24
pool.ipv6.cidr = fd71:e1:8000:102::/64

routing.nat.enabled = true
routing.ipv6.mode = nat66

dns.enabled = true
dns.listen = 10.19.0.1
dns.listen_ipv6 = fd71:e1:8000:102::1
dns.push_servers = 10.19.0.1, fd71:e1:8000:102::1

Используйте уникальный для развёртывания RFC 4193 ULA /48 и отдельный /64 на профиль. Не копируйте пример fd71:… буквально между независимыми установками и не используйте link-local fe80::/10 как пул. Quick Start генерирует случайный 40-битный Global ID.

Выход и маршруты

routing.ipv6.mode

ЗначениеЧто делаетТребования
nat66Подменяет ULA-источник на IPv6 WAN сервера.IPv6 default route, публичный GUA из 2000::/3 и рабочий ip6tables NAT. Удобно на обычном VPS, но это NAT.
routeСохраняет исходный IPv6 клиента.Для выхода в интернет — маршрутизируемый провайдером GUA-префикс и обратный маршрут. Для LAN/site-to-site достаточно маршрутов между своими сетями.
offНе выпускает IPv6 из профиля и ставит fail-closed изоляцию.Рабочий ip6tables нужен, чтобы DROP был гарантирован.
Не используйте WAN /64, уже назначенный uplink-интерфейсу, как клиентский pool. Нужен отдельный routed или отдельный on-link префикс; для второго в 0.8.1 доступен session-aware NDP proxy.

Для routed GUA задавайте reservation или static_ipv6; CLI поддерживает qeli add-client --static-ipv6 ….

Routed IPv6 · 0.8.1

routing.ipv6.ndp_proxy = off | auto | required

Предпочтительная схема — провайдер маршрутизирует отдельный клиентский префикс на WAN-адрес сервера. В ней оставьте off. Если провайдер считает отдельный префикс on-link и отправляет Neighbor Solicitation для каждого адреса, включите встроенный session-aware responder.

server.conf · [profile:public-v6]
routing.ipv6.mode = route
routing.ipv6.interface = ens3
routing.ipv6.ndp_proxy = required
routing.ipv6.ndp_proxy_interface = ens3
РежимПоведение
offДефолт. Правильный выбор для обычного L3-routed префикса.
autoПытается открыть responder; при неподходящем интерфейсе, отсутствии Ethernet или CAP_NET_RAW предупреждает и продолжает без него.
requiredНе запускает профиль, пока responder не привязан к выбранному интерфейсу.

Responder отвечает MAC-адресом сервера только за точный IPv6 lease живой сессии и адреса внутри активного non-default client_subnet. Disconnect, revoke или замена сессии снимают ownership немедленно; /0, link-local, multicast, неверные NS и чужие адреса игнорируются.

Не назначайте клиентский prefix WAN-интерфейсу и не создавайте для него competing connected route через WAN: единственным владельцем маршрута должен оставаться TUN профиля. NDP proxy работает только с source-preserving route, не с nat66 или off.
Политика клиента

ipv6 = auto | required | off

ПолитикаРезультат
autoПринимает IPv4, dual или IPv6. Dual может безопасно понизиться до IPv4, если платформа не умеет полный IPv6-контракт.
requiredТребует внутренний IPv6 и fail-closed при старом сервере, IPv4-only профиле, MTU ниже 1280 или неполной поддержке платформы.
offПросит IPv4 у dual-профиля и отклоняет IPv6-only план.

В full-tunnel отсутствие одного семейства блокируется по умолчанию. allow_ipv6_leak=true или allow_ipv4_leak=true — явный escape hatch, разрешающий отсутствующему семейству идти физическим путём. Оба значения по умолчанию false.

DNS и MTU

Настройте оба семейства целиком

  • dns.listen и dns.listen_ipv6 должны совпадать с активными gateway-адресами профиля; dns.push_servers не должен раздавать недоступный listener.
  • IPv6 требует MTU не меньше 1280. Политика required отвергает меньший план, а PMTU probing подбирает безопасный carrier budget.
  • route, route_file, server push и ACL принимают IPv4/IPv6 CIDR, но применяются только для согласованного семейства.
  • Outer DNS для hostname endpoint может вернуть A и AAAA; roaming способен перенести сессию между семьями после аутентифицированной проверки пути.
Миграция

Старый конфиг не становится dual-stack автоматически

  1. Сделайте backup и обновите сервер до 0.8.1.
  2. Выберите уникальный ULA /64 либо получите у провайдера routed GUA-префикс.
  3. Добавьте tun.ip_mode, tun.ipv6_address, pool.ipv6.cidr, IPv6 DNS и routing.ipv6.mode.
  4. Выполните qeli check-config; для NAT66 дополнительно проверьте default route, публичный source GUA и ip6tables NAT.
  5. Оставьте клиентам ipv6=auto, проверьте IPv4 и IPv6 отдельно, затем при необходимости ужесточайте до required.
Установщик сохраняет active dual-stack только при подтверждённом IPv6 uplink и NAT; иначе создаёт безопасный активный IPv4-only профиль, а подготовленные IPv6 значения остаются для ручного включения после исправления uplink.
Границы

Чего Qeli не делает

  • Qeli не предоставляет NAT64/DNS64. IPv6-only клиент не откроет IPv4-only ресурс без отдельной NAT64-инфраструктуры.
  • Qeli не превращает случайный WAN /64 в клиентский pool: нужен отдельный routed/on-link префикс и корректный обратный путь.
  • IPv6 внутри туннеля не означает, что серверный uplink автоматически готов: проверяйте адрес, default route, firewall и обратный маршрут.
Первоисточники

Полная документация IPv6 0.8.1