Делегування префікса IPv6 через VPN між майданчиками: контрольний список
Перевірки маршрутизації делегованого префікса IPv6 через VPN між майданчиками: карта префіксів, селектори трафіку, пересилання, MTU, зворотний шлях і перенумерація.
Підняти тунель — це проста половина. Я бачив, як з'єднання між майданчиками залишалося встановленим днями, а кожен хост у віддаленій локальній мережі отримував у відповідь лише тишу, бо делегований префікс за цим шлюзом був налаштований на інтерфейсі, але так і не був маршрутизований у тунель. Адреси тунелю весь цей час відповідали на ping, і саме тому ніхто не дивився на префікс. Ось порядок, який я перевіряю, коли делегований префікс IPv6 має пройти через VPN майданчика: карта префіксів, селектори трафіку, пересилання й міжмережевий екран, а потім зворотний шлях.
Спершу напишіть карту префіксів, а вже потім чіпайте тунель
Делегування префікса віддає блок тому маршрутизатору, який його запросив. Воно не встановлює маршрут на партнері, не розширює цей блок як on-link і не повідомляє віддаленому шлюзу, що стоїть за запитувальним маршрутизатором. Ці три речі налаштовуєте ви, і їм місце в плані адресації до того, як зміниться будь-який конфігураційний файл.
Для кожного майданчика запишіть делегований префікс, фактично використовуваний у локальній мережі /64, адреси тунелю й власника кожного маршруту. Провайдер делегує майданчику A префікс 2001:db8:a1::/56, який обслуговує у своїй локальній мережі 2001:db8:a1:10::/64; майданчик B зберігає 2001:db8:b2::/64. Якщо майданчик A обслуговує лише цей єдиний /64, обидві сторони мають вказувати 2001:db8:a1:10::/64, а не весь /56.
Майже завжди виявляються дві помилки. Одна — вважати віддалений префікс on-link, з'єднувати його мостом або ставити на інтерфейс тунелю, через що шлюз відповідає на запити сусідів за хости, до яких не може дістатися. Друга — анонсувати весь /56, коли налаштовано лише один /64: таблиця маршрутів стверджує, що блок доступний, і більшість адрес іде в чорну діру.
Узгодьте селектори трафіку обох сторін із маршрутами
IKEv2 і WireGuard обидва відхиляють невідповідний трафік, достатньо тихо, щоб тунель і далі виглядав здоровим.
У strongSwan селектори задаються явно. На майданчику A:
conn a-to-b
left=2001:db8:ff::1
leftsubnet=2001:db8:a1:10::/64
right=2001:db8:ff::2
rightsubnet=2001:db8:b2::/64
auto=startconn майданчика B дзеркально відображає обидві підмережі. Коли вони не збігаються, відповідач відхиляє CHILD_SA з TS_UNACCEPTABLE, тому дочірній SA ніколи не піднімається, хоча IKE_SA піднявся. З обох боків налаштована підмережа має збігатися з тим, що локальне ядро маршрутизує в бік тунелю.
WireGuard несе ту саму інформацію в AllowedIPs, з однією особливістю: AllowedIPs — це фільтр джерела під час приймання та маршрут під час надсилання. Якщо запис peer майданчика B для майданчика A не включає 2001:db8:a1:10::/64, пакети з майданчика A надходять за дійсного handshake і відкидаються як недозволені. Звідси знайомий шаблон: handshake постійно оновлюється, а відповідь так і не виходить. Порівняйте обидві сторони за допомогою wg show wg0 allowed-ips. Перевіряйте цей список щоразу, коли делегування змінюється; застарілий /64 тримає сеанс живим, а новий префікс — недосяжним.
Спочатку виключіть пересилання, міжмережевий екран і MTU
Перш ніж читати наступний рядок журналу, переконайтеся, що шлюзи взагалі пересилають. sysctl net.ipv6.conf.all.forwarding має повернути 1 на обох, застосований також до інтерфейсів тунелю й локальної мережі. Є одна пастка: після ввімкнення пересилання інтерфейс з accept_ra=1 перестає приймати оголошення маршрутизатора від провайдера, тож машина може втратити вищерозташований маршрут за замовчуванням, хоча всередині тунелю маршрутизує бездоганно. Установіть accept_ra=2 там, де оголошення провайдера все ще потрібне.
Далі правила міжмережевого екрана мають дозволяти префікс в обох напрямках, а ICMPv6 має вижити: виявлення сусідів, packet-too-big і destination-unreachable не є необов'язковими. Відкиньте їх, і виявлення MTU шляху зламається, а ви отримаєте з'єднання, які відкриваються й потім завмирають на першій великій відповіді. Мінімальна пара правил виглядає так:
nft add rule inet filter forward ip6 saddr 2001:db8:a1:10::/64 ip6 daddr 2001:db8:b2::/64 accept
nft add rule inet filter forward ip6 saddr 2001:db8:b2::/64 ip6 daddr 2001:db8:a1:10::/64 accept
nft add rule inet filter forward icmpv6 type { packet-too-big, nd-neighbor-solicit, nd-neighbor-advert } acceptMTU стоїть за цим. Тунель зменшує доступний MTU нижче 1500, а IPv6 вимагає, щоб кожна ланка несла щонайменше 1280. Малі ping проходять, сеанс SSH завмирає на великій пачці, а /proc/net/snmp6 показує повідомлення packet-too-big, які так і не повертаються. Задайте MTU тунелю явно або обмежте TCP MSS у таблиці mangle і дозвольте ICMPv6, що повідомляє про менший MTU, повернутися.
Перевіряйте зворотний шлях, а не адресу тунелю
Збій, що забирає найбільше часу, — одностороння маршрутизація. Кожен шлюз маршрутизує віддалений префікс у тунель, але хости відповідають через власний шлюз за замовчуванням, бо саме там живе їхній /64. Довести пакет до призначення — це половина шляху.
| What you see | Likely cause | First check |
|---|---|---|
| Tunnel up, every host silent | remote prefix not routed into the tunnel | ip -6 route get on both gateways |
| Handshake renews, no replies | source prefix missing from selectors or AllowedIPs | ipsec statusall, wg show allowed-ips |
| Small pings pass, transfers stall | MTU or ICMPv6 packet-too-big filtered | /proc/net/snmp6 counters |
| Old prefix still works | stale /64 left in routes or selectors | delegation lease and route table |
Дві команди вирішують більшість. На майданчику A ip -6 route get 2001:db8:b2::53 from 2001:db8:a1:10::5 показує, який інтерфейс використав би відповідь із цього джерела; виконайте дзеркальну перевірку на майданчику B. Потім створіть трафік з хоста, а не зі шлюзу, і порівняйте лічильники на обох кінцях.
Якщо запит сусідів для віддаленого префікса з'являється на тунелі, цей префікс десь є on-link там, де не повинен; виправте це до налаштування маршрутів. Proxy NDP охоплює випадки, коли міст справді потрібен, а не замінює маршрут.
Плануйте зміну префікса під собою
Делегування префікса — це оренда між делегувальним і запитувальним маршрутизатором, і поновлення може повернути інший блок: інший /56 після міграції провайдера або коротшу оренду, ніж час роботи тунелю. Кожне місце, що називає старий префікс, застаріває одразу: маршрути, селектори, AllowedIPs, правила міжмережевого екрана, записи DNS і будь-який моніторинг, у якому зашиті буквальні адреси. Потік повідомлень описано в RFC 8415.
Там, де очікується переміщення префікса, тримайте внутрішній план адресації, що від нього не залежить, і транслюйте на межі. NPTv6 — варіант без стану, він зберігає читабельність внутрішньої політики, але це трансляція префікса, а не чарівний шар: межі /64 мають збігатися, контрольні суми коригуються, а застосунки з буквальними адресами все одно ламаються. Якщо ви зберігаєте адреси провайдера від краю до краю, зафіксуйте поведінку оренди й процедуру змін у плані адресації.
Завершіть тестом, що витримує час: дозволений хост у кожній локальній мережі досягає сервісу в іншій мережі, відповідь повертається через тунель, і та сама пара працює після перезапуску тунелю та поновлення делегування. Якщо остання частина не проходить, проєкт залежить від стану, який не переживе тижня.