Вдигате тунела, пускате ping към fe80::1 с тунела като изходен интерфейс и не получавате нищо. Това не е забравено правило на защитната стена. Адресът за локална връзка означава нещо само на единствената връзка, на която е образуван, а маршрутизираният VPN не е тази връзка. fe80::1 на отдалечения маршрутизатор живее в отдалечения LAN сегмент; вие сте на един хоп разстояние в друг сегмент и IPv6 няма никакъв механизъм маршрутизатор изобщо да препраща пакети за локална връзка.

Префиксът fe80 описва обхват, а не диапазон

Уникаст адресът за локална връзка е fe80::/10 и определящото свойство не е числото, а обхватът. Адресът е валиден само на една връзка и всеки интерфейс образува такъв от собствения си идентификатор; затова две несвързани машини в две несвързани мрежи могат и двете да отговарят на fe80::1 без ни най-малък конфликт. Префиксът по същество казва “на някаква връзка”; самата връзка идва от контекста.

На хост този контекст е зоната, или идентификаторът на обхвата, който добавяте след знак за процент: fe80::1%eth0 в Linux, fe80::1%3 или fe80::1%12 в Windows и в инструменти, които показват индекси на интерфейси. Ядрото разрешава адреса заедно с индекса на интерфейса и после изпраща. Махнете зоната и дестинацията става двусмислена, така че стекът няма как да избере сегмент.

Защо маршрутизиран тунел не може да го достави

Маршрутизираният VPN е интерфейс точка до точка, който носи собствени адреси, обикновено /64 от уникално локално или частно IPv6 пространство вътре в тунела. Отдалеченият LAN е отделна връзка, достигната чрез маршрутизиране и препращане от крайната точка на тунела от ваше име. Това са два различни сегмента, затова адрес от единия не е валидна дестинация в другия.

Правилото за препращане е изрично в стандарта, а не особеност на вашия клиент: маршрутизаторите не препращат пакети с източник или дестинация за локална връзка. Затова пакетът умира дори когато таблицата за маршрутизиране изглежда правилна. Добавете маршрут за fe80::/64 към тунела и съответстващ на стандарта стек или ще го отхвърли, или ще го приеме и ще изхвърли всеки съответстващ пакет: обхватът на дестинацията казва “само тази връзка”, а изходящият интерфейс не е тази връзка.

Откриването на съседи подсилва същата граница. Хостовете разрешават следващи хопове за локална връзка чрез молба към съседи, изпратена до multicast с обхват на връзката с лимит на хоповете 255, така че маршрутизаторите да могат да отхвърлят всичко препратено. Да се направи това през тунел би означавало проксиране на откриването за отдалечен сегмент, което е мост от ниво 2 с друга шапка.

Има и по-тих втори провал, който обърква хората, опитващи се все пак да наложат маршрута: зоната. Каквато зона напишете локално, тя именува интерфейса на тунела, докато адресът, който искате, е вързан към интерфейса на отдалечения LAN. Двете никога не съвпадат, затова пакетът не може да бъде насочен към правилния интерфейс в далечния край.

Как изглежда отказът на практика

Изходът на инструментите при грешка в обхвата изглежда като грешка в маршрутизирането или защитната стена — точно затова хората прекарват следобед в грешния слой.

What you runWhat you seeWhat it means
ping fe80::1 with no zoneInvalid argument on Linux, or a transmit failure on WindowsThe stack cannot pick an interface for an ambiguous destination
ping -6 -I tun0 fe80::1Destination unreachable, or a silent timeoutThe address is not on the tunnel link, so there is nothing on-link to answer
ssh user@fe80::1 after the tunnel is upHangs, then no route to hostThe SYN never left the machine in a deliverable form; the server logs nothing
ip -6 neigh show dev tun0Empty tableNo neighbor entry can exist for a link-local host that is not on this link
fe80::/64 inside AllowedIPs or route-ipv6Config accepted, traffic still droppedThe tunnel carried the packet; the receiving stack refused to forward it

Третият ред губи най-много време, защото ssh клиент без изход изглежда като проблем със слушаща услуга. Ако имате какъвто и да е достъп, проверете далечната страна и потвърдете дали sshd е вързан към всички адреси или само към един.

Използвайте адрес, който е бил предназначен за маршрутизиране

За всичко, до което трябва да стигнете през тунела, използвайте адреса, който услугата е получила за тази цел: глобален уникаст адрес или уникално локален адрес от fc00::/7, диапазонът, запазен точно за този вътрешен случай. Потвърдете, че слушателят наистина го свързва, и проверете обратния път и всяко правило на защитната стена на хоста.

Гледайте отдалечения хост, вместо да гадаете. ip -6 addr show изброява съществуващите адреси, а ss -6 -ltn — на какво слуша демонът. Услуга, вързана само към fe80::, е достижима само от собствения си сегмент; това обикновено е настройка по подразбиране, която никой не е избрал нарочно и може да се промени със съгласието на администратора.

Когато услугата наистина не може да бъде превързана, преместете моста на приложния слой вместо на мрежовия. Ретранслатор на отдалечения хост, който слуша на маршрутизиран адрес и се свързва с адреса за локална връзка, решава проблема, без да разширява който и да е сегмент:

socat TCP6-LISTEN:8080,bind=[fd00:1:2::10] TCP6:[fe80::1%eth0]:80

Тук зоната е от правилната страна, на хоста, който наистина има eth0 на тази връзка. Вашият клиент говори с fd00:1:2::10, който се маршрутизира нормално, а ретранслаторът прави хопа за локална връзка локално. Същият трик работи за уеб интерфейс на устройство или стар BMC, който обявява само адрес за локална връзка.

Кога мостът наистина е отговорът и какво да проверите

Някои внедрявания наистина се нуждаят от един споделен сегмент: устройство, което говори само откриване за локална връзка, устройство, което зависи от multicast, лаборатория, която възпроизвежда плосък LAN. Това е проблем от ниво 2 и изисква отговор от ниво 2, например tap устройство, мостнато към отдалечения интерфейс, или клиентски продукт с явен мостов режим. Това ви струва broadcast и multicast трафик през тунела плюс откриване на съседи, което трябва да работи от край до край.

Не го приближавайте, като добавите fe80::/64 към маршрутизиран профил. Така се получава най-лошото състояние: конфигурацията изглежда завършена, таблицата за маршрутизиране показва запис, а всеки пакет пак се изхвърля някъде между два стека, които и двата се държат правилно.

Проверявайте с интерфейса, а не с ping. ip -6 addr show tun0 ви казва дали връзката на тунела е образувала свой адрес за локална връзка, а ip -6 route get fe80::1%tun0 — какво ядрото наистина би направило с дестинация в обхват. Когато ядрото каже, че дестинацията е недостижима на този интерфейс, никаква настройка на тунела няма да го промени и е време да спрете да редактирате профила.

Кратка последователност, която решава въпроса:

  • Прочетете адреса на отдалечения хост и отбележете дали е fe80:: или маршрутизиран префикс.
  • Ако е fe80::, превържете услугата, направете ретранслация на този хост или мостнете сегмента; ако е маршрутизиран, поправете маршрута, защитната стена или адреса за свързване.
  • Проверявайте зоната при всяко повторно тестване, защото копирана команда обикновено запазва грешния интерфейс.

Източници: RFC 4291, архитектура на IPv6 адресирането.

Подобни статии