IPv6 link-local не работи преку VPN: зошто fe80 застанува на врската
Адресата fe80:: има значење само на една врска. Дознајте зошто рутиран VPN не може да ја пренесе, како изгледа дефектот и која адреса да се користи наместо неа.
Ја подигате тунелот, правите ping на fe80::1 со тунелот како изворно интерфејс, и ништо не се враќа. Ова не е firewall правило што сте го заборавиле. Link-local адресата има значење само на таа една врска каде што е формирана, а рутиран VPN не е таа врска. fe80::1 на далечниот рутер живее на далечниот LAN сегмент; вие сте еден скок подалеку на различен сегмент, а IPv6 воопшто нема механизам со кој рутерот би пренел link-local пакети.
Префиксот fe80 опишува опфат, а не опсег
Link-local unicast е fe80::/10, а дефинирачкото својство не е бројот туку опфатот. Адресата важи само на една врска, и секој интерфејс формира една од сопствениот идентификатор, затоа две неповрзани машини на две неповрзани мрежи можат двете да одговараат на fe80::1 без најмал конфликт. Префиксот во суштина вели „на некоја врска“; самата врска доаѓа од контекстот.
На хост, тој контекст е зоната, или scope ID, што ја додавате по знакот за процент: fe80::1%eth0 на Linux, fe80::1%3 или fe80::1%12 на Windows и во алатки што откриваат индекси на интерфејси. Јадрото ја решава адресата заедно со индексот на интерфејсот и потоа праќа. Ако ја отстраните зоната, одредиштето е двосмислено, па стекот нема начин да избере сегмент.
Зошто рутиран тунел не може да ја достави
Рутиран VPN е точка-до-точка интерфејс што носи сопствени адреси, обично /64 од unique-local или приватен IPv6 простор внатре во тунелот. Далечниот LAN е одделна врска, до која се доаѓа така што крајот на тунелот рутира и препраќа во ваше име. Тоа се два различни сегменти, па адреса од едниот не е важечко одредиште на другиот.
Правилото за препраќање е изречно во стандардот, а не каприц на вашиот клиент: рутерите не препраќаат пакети со link-local извор или одредиште. Затоа пакетот умира и кога табелата за рутирање изгледа исправна. Додајте рута за fe80::/64 кон тунелот и стекот што е во согласност или ќе ја одбие или ќе ја прифати и ќе го отфрли секој соодветен пакет: опфатот на одредиштето вели „само оваа врска“, а излезниот интерфејс не е таа врска.
Откривањето соседи ја зацврстува истата граница. Хостовите ги решаваат link-local следните скокови со барање за сосед што се праќа на multicast со опфат на врска со ограничување на скок од 255, па рутерите можат да одбијат сето што е препратено. Да се направи тоа да работи преку тунел би значело да се проксира откривањето за далечен сегмент, што е Layer 2 премостување со друга капа.
Има и еден потивок втор дефект, и тој ги фаќа луѓето што сепак се обидуваат да ја наметнат рутата: зоната. Која и зона да ја внесете локално, таа го именува интерфејсот на тунелот, додека адресата што ја сакате е врзана за интерфејсот на далечниот LAN. Двете никогаш не се совпаѓаат, па пакетот не може да се насочи на вистинскиот интерфејс на далечниот крај.
Како изгледа дефектот во пракса
Излезот од алатката за грешка во опфатот се чита како грешка во рутирањето или firewall, и токму затоа луѓето трошат попладне во погрешен слој.
| What you run | What you see | What it means |
|---|---|---|
| ping fe80::1 with no zone | Invalid argument on Linux, or a transmit failure on Windows | The stack cannot pick an interface for an ambiguous destination |
| ping -6 -I tun0 fe80::1 | Destination unreachable, or a silent timeout | The address is not on the tunnel link, so there is nothing on-link to answer |
| ssh user@fe80::1 after the tunnel is up | Hangs, then no route to host | The SYN never left the machine in a deliverable form; the server logs nothing |
| ip -6 neigh show dev tun0 | Empty table | No neighbor entry can exist for a link-local host that is not on this link |
| fe80::/64 inside AllowedIPs or route-ipv6 | Config accepted, traffic still dropped | The tunnel carried the packet; the receiving stack refused to forward it |
Третиот ред троши најмногу време, бидејќи ssh клиент без излез изгледа како проблем со услуга што слуша. Ако имате каков било начин да влезете, проверете ја далечната страна и потврдете дали sshd е врзан за сите адреси или само за една.
Користете адреса што била наменета за рутирање
За сето до што треба да стигнете преку тунелот, користете ја адресата што услугата ја добила токму за таа цел: глобална unicast адреса, или unique-local адреса од fc00::/7, опсегот резервиран токму за овој внатрешен случај. Потврдете дека слушачот навистина ја врзува, и проверете го повратниот пат и секое firewall правило на хостот.
Погледнете го далечниот хост наместо да погодувате. ip -6 addr show ги наведува адресите што постојат, а ss -6 -ltn го наведува она на што демонот слуша. Услуга врзана само за fe80:: е достапна само од сопствениот сегмент, што обично е стандардна вредност што никој не ја избрал намерно и може да се смени со согласност на администраторот.
Кога услугата навистина не може повторно да се врзе, преместете го мостот на апликацискиот слој наместо на мрежниот. Реле на далечниот хост што слуша на рутирачка адреса и се поврзува со link-local ја решава задачата без проширување на кој било сегмент:
socat TCP6-LISTEN:8080,bind=[fd00:1:2::10] TCP6:[fe80::1%eth0]:80Овде зоната седи на вистинската страна, на хостот што навистина има eth0 на таа врска. Вашиот клиент разговара со fd00:1:2::10, што се рутира нормално, а релето го прави link-local скокот локално. Истиот трик работи за веб UI на апарат или стар BMC што рекламира само link-local адреса.
Кога премостувањето навистина е одговорот, и што да се провери
Некои распоредувања навистина бараат еден заеднички сегмент: уред што зборува само link-local откривање, апарат што зависи од multicast, лабораторија што репродуцира рамен LAN. Тоа е Layer 2 проблем и бара Layer 2 одговор, како tap уред премостен на далечниот интерфејс или клиентски производ со изричен премостен режим. Тоа ве чини broadcast и multicast сообраќај што го преминува тунелот, плус откривање соседи што мора да работи од крај до крај.
Не приближувајте го тоа со додавање fe80::/64 во рутиран профил. Тоа ја создава најлошата состојба: конфигурацијата изгледа завршена, табелата за рутирање покажува запис, а секој пакет сето уште се отфрла некаде меѓу два стека што и двата се однесуваат исправно.
Проверете со интерфејсот, а не со ping. ip -6 addr show tun0 ви кажува дали врската на тунелот формирала сопствена link-local адреса, а ip -6 route get fe80::1%tun0 ви кажува што јадрото навистина би направило со одредиште со опфат. Кога јадрото вели дека одредиштето е недостапно на тој интерфејс, ниту една поставка на тунелот нема да го смени тоа, и време е да престанете да го уредувате профилот.
Кратка низа што го решава прашањето:
- Прочитајте ја адресата на далечниот хост и забележете дали е fe80:: или префикс што може да се рутира.
- Ако е fe80::, повторно врзете ја услугата, реле на тој хост или премостете го сегментот; ако е рутирачка, поправете ја рутата, firewall или адресата на врзување.
- Проверете ја зоната повторно секој пат кога повторно тестирате, бидејќи копираната команда обично го задржува погрешниот интерфејс.
Извори: RFC 4291, IPv6 адресна архитектура.