IPv6 през тунел OpenVPN: преглед за домашен рутер
IPv6 умира или изтича, когато тунелът раздаде префикс, който рутерът не може да маршрутизира. Мини през клиента, пула, препращането, прокси NDP и обратния път по ред.
Лаптопът има IPv6 адрес, тунелът работи през IPv4, а всеки IPv6 тест се проваля. Или по-лошо: тестът минава и трафикът е излязъл по пътя на доставчика, без изобщо да влезе в тунела. И двата резултата водят до едно липсващо решение: никой не е дал на рутера префикс, който да може да маршрутизира към клиентите. Проследяването на пътя от клиента навън открива кое парче липсва.
Започнете от мястото на клиента
Погледнете клиента, преди да пипате сървъра. ip -6 addr трябва да показва адрес на тунела от пула, а ip -6 route — изпратения префикс, сочещ към тунелното устройство. Когато адресът е налице, а маршрут няма, изпращането липсва или клиентът го е игнорирал. Когато няма нито едно от двете, сървърът изобщо не е задал нищо.
После проверете какво мисли клиентът за външния свят. Маршрут по подразбиране през тунела претендира за целия IPv6 трафик, докато маршрут за 2000::/3 претендира само за глобалния unicast. И двете могат да са правилни и отговарят на различни въпроси за изтичането.
Клиент без никакъв IPv6 маршрут по подразбиране се проваля на всеки публичен тест, макар самият тунел да е напълно здрав. Това е пропуск в политиката, а не счупен тунел.
Проверете пула, който сървърът наистина може да маршрутизира
Сървърът може да задава адреси само от префикс, който наистина контролира. Ако доставчикът делегира /56, запазете един /64 за тунела и оставете другото за LAN. Когато доставчикът дава само един /64 на WAN и не маршрутизира нищо повече, оставете LAN префикса на мира и дайте на тунела уникален локален диапазон, приемайки, че клиентите няма да имат глобален изход.
Пулът и изпращането вървят заедно. server-ipv6 2001:db8:80:10::/64 задава адреси, а push "route-ipv6 2000::/3" казва на клиентите какво да изпращат в тунела. Изпращането на 2000::/3 покрива глобалния unicast и оставя link-local и multicast диапазоните извън тунела.
Запишете избрания префикс в дневника за внедряване. Следващият, който промени предаването от доставчика, трябва да знае кой /64 тунелът вече заема.
Включете препращането за второто семейство
Препращането на IPv4 не означава препращане на IPv6. Задайте net.ipv6.conf.all.forwarding=1 и огледайте всичко, което IPv4 FORWARD политиката вече разрешава. На рутер, чиято FORWARD верига по подразбиране отхвърля, липсващият набор от правила изглежда точно като мъртъв тунел.
Ръкостискането минава, клиентът получава адрес, а обратно не идва нищо. Добавете правила за двете посоки и за WAN рамото, защото тунел, който стига до LAN, но не до интернет, се проваля на третия тест. Проверете броячите на веригата след неуспешен опит, защото правило, което никога не е съвпадало, е различен проблем от такова, което е съвпаднало и е отхвърлило.
ip6tables -A FORWARD -i br0 -o tun0 -j ACCEPT
ip6tables -A FORWARD -i tun0 -o br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -i tun0 -o wan0 -j ACCEPT
Един страничен ефект хваща хората, които накрая обвиняват тунела. Включването на препращане кара ядрото да пропусне конфигурацията на адрес чрез обяви на рутера, освен ако не му кажете друго, и маршрут по подразбиране, научен така, изчезва заедно с нея. Или закрепете явен маршрут по подразбиране на WAN интерфейса, или умишлено задайте accept_ra на 2 там. След всяка от двете промени потвърдете, че рутерът все още има използваем IPv6 път навън, преди да тествате клиентите отново.
Отговаряйте на откриването на съседи, когато горната страна не маршрутизира
Оборудването отгоре понякога смята делегирания /64 за свой собствен канал и отказва да маршрутизира какъвто и да е подпрефикс към VPN кутията. Когато това се случи, нещо трябва да отговаря на заявките за съседи за всеки адрес на клиент поотделно.
OpenVPN предоставя зададения адрес на client-connect hook, така че записите да следват истинския пул вместо списък, поддържан на ръка. Hook-ът добавя ip -6 neigh add proxy $ifconfig_pool_remote_ip6 dev eth0, а съответният client-disconnect hook го премахва. Без премахването таблицата на проксито остарява и по-късен клиент може да наследи запис за адрес, който никога не е получавал. Потвърдете състоянието с ip -6 neigh show proxy.
Третирайте проксирането като заобиколно решение. Статичен маршрут за /64 на тунела, насочен към рутера, оцелява при смяна на клиенти и не изисква никакъв привилегирован shell hook.
Проследете пътя навън, хоп по хоп
Тествайте навън в три стъпки: първо адреса на тунела на рутера, после LAN хост и трето публична дестинация през traceroute6. Пулът се доказва от първата, препращането и LAN защитната стена от втората, а обратният път през горната страна от третата. Всеки провал стеснява търсенето до едно устройство, вместо да отваря наново целия дизайн.
Следете MTU на тунела, защото IPv6 рутерите по пътя няма да фрагментират вместо вас. Прекалено голям MTU се проявява като грешка packet-too-big и заседнал TLS, а не като чист провал. Задайте го изрично и тествайте с полезен товар близо до границата.