IPv6 link-local neveikia per VPN: kodėl fe80 sustoja ties jungtimi
Adresas fe80:: turi prasmę tik vienoje jungtyje. Sužinokite, kodėl maršrutuotas VPN negali jo perduoti, kaip atrodo gedimas ir kokį adresą naudoti vietoj jo.
Jūs pakeliate tunelį, pinginate fe80::1, naudodami tunelį kaip šaltinio sąsają, ir nieko negaunate atgal. Tai ne pamiršta ugniasienės taisyklė. Link-local adresas turi prasmę tik toje vienoje jungtyje, kurioje jis buvo suformuotas, o maršrutuotas VPN nėra ta jungtis. Nuotolinio maršrutizatoriaus fe80::1 gyvena nuotoliniame LAN segmente; jūs esate vienu šuoliu toliau kitame segmente, o IPv6 apskritai neturi mechanizmo, kuriuo maršrutizatorius persiųstų link-local paketus.
fe80 priešdėlis aprašo apimtį, o ne diapazoną
Link-local unicast yra fe80::/10, o apibrėžianti savybė yra ne skaičius, o apimtis. Adresas galioja tik vienoje jungtyje, ir kiekviena sąsaja suformuoja po vieną iš savo identifikatoriaus, todėl du nesusiję kompiuteriai dviejuose nesusijusiuose tinkluose gali abu atsakyti į fe80::1 be menkiausio konflikto. Priešdėlis iš esmės sako „kažkurioje jungtyje“; pati jungtis ateina iš konteksto.
Pagrindiniame kompiuteryje tas kontekstas yra zona, arba scope ID, kurią pridedate po procento ženklo: fe80::1%eth0 Linux, fe80::1%3 arba fe80::1%12 Windows ir įrankiuose, kurie rodo sąsajų indeksus. Branduolys išsprendžia adresą kartu su sąsajos indeksu ir tada siunčia. Jei pašalinsite zoną, paskirties vieta taps dviprasmė, todėl krūva neturi būdo pasirinkti segmento.
Kodėl maršrutuotas tunelis negali jo pristatyti
Maršrutuotas VPN yra taškas-taškas sąsaja, turinti savo adresus, dažniausiai /64 unique-local arba privataus IPv6 ploto tunelyje. Nuotolinis LAN yra atskira jungtis, pasiekiama tunelio pabaigos taškui maršrutizuojant ir persiunčiant jūsų vardu. Tai du skirtingi segmentai, todėl vieno adresas nėra galiojanti paskirties vieta kitame.
Persiuntimo taisyklė yra aiškiai įrašyta standarte, o ne jūsų kliento keistenybė: maršrutizatoriai nepersiunčia paketų su link-local šaltiniu ar paskirtimi. Todėl paketas žūsta net tada, kai maršrutų lentelė atrodo teisinga. Pridėkite maršrutą fe80::/64 link tunelio, ir standartą atitinkanti krūva arba jį atmes, arba priims ir numes kiekvieną atitinkantį paketą: paskirties apimtis sako „tik ši jungtis“, o išeinančioji sąsaja nėra ta jungtis.
Kaimynų paieška sustiprina tą pačią ribą. Pagrindiniai kompiuteriai išsprendžia link-local kitus šuolius kaimyno užklausa, siunčiama į jungties apimties multicast su šuolių riba 255, todėl maršrutizatoriai gali atmesti viską, kas persiunčiama. Padaryti tai veikiant per tunelį reikštų proxinti paiešką nuotoliniam segmentui, o tai yra Layer 2 sujungimas su kita kepure.
Yra tylesnis antrasis gedimas, ir jis pagauna žmones, kurie vis tiek bando priversti maršrutą: zona. Kokią zoną įrašysite vietoje, ji įvardija tunelio sąsają, o norimas adresas yra prisirišęs prie nuotolinio LAN sąsajos. Du niekada nesutampa, todėl paketo negalima nukreipti į tinkamą sąsają kitame gale.
Kaip gedimas atrodo praktiškai
Įrankio išvestis dėl apimties klaidos skaitoma kaip maršrutizavimo ar ugniasienės klaida, ir būtent todėl žmonės praleidžia popietę netinkamame sluoksnyje.
| 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 |
Trečioji eilutė praranda daugiausia laiko, nes ssh klientas be išvesties atrodo kaip klausančios paslaugos problema. Jei turite kokį nors būdą patekti, patikrinkite tolimąją pusę ir patvirtinkite, ar sshd susietas su visais adresais, ar tik su vienu.
Naudokite adresą, kuris buvo skirtas maršrutizavimui
Viskam, ką reikia pasiekti per tunelį, naudokite adresą, kuris paslaugai buvo duotas būtent tam: visuotinį unicast adresą arba unique-local adresą iš fc00::/7, diapazoną, rezervuotą būtent šiam vidiniam atvejui. Patvirtinkite, kad klausytojas tikrai jį susieja, ir patikrinkite grįžimo kelią bei bet kurią pagrindinio kompiuterio ugniasienės taisyklę.
Žiūrėkite į nuotolinį pagrindinį kompiuterį, o ne spėliokite. ip -6 addr show išvardija egzistuojančius adresus, o ss -6 -ltn išvardija, ko demonas klauso. Paslauga, susieta tik su fe80::, pasiekiama tik iš savo segmento, o tai paprastai yra numatytoji reikšmė, kurios niekas sąmoningai nepasirinko ir kurią galima pakeisti administratoriui sutikus.
Kai paslaugos tikrai negalima iš naujo susieti, pakelkite tiltą į taikomųjų programų sluoksnį, o ne į tinklo sluoksnį. Relė nuotoliniame kompiuteryje, kuri klausosi maršrutizuojamo adreso ir jungiasi prie link-local, išsprendžia problemą neišplečiant jokio segmento:
socat TCP6-LISTEN:8080,bind=[fd00:1:2::10] TCP6:[fe80::1%eth0]:80Čia zona yra teisingoje pusėje, tame kompiuteryje, kuris tikrai turi eth0 toje jungtyje. Jūsų klientas kalbasi su fd00:1:2::10, kuris maršrutizuojamas įprastai, o relė atlieka link-local šuolį vietoje. Tas pats triukas veikia įrenginio žiniatinklio sąsajai ar senam BMC, kuris skelbia tik link-local adresą.
Kai sujungimas tikrai yra atsakymas, ir ką tikrinti
Kai kurie diegimai tikrai reikia vieno bendro segmento: įrenginio, kuris kalba tik link-local paieška, prietaiso, kuris priklauso nuo multicast, laboratorijos, kuri atkuria plokščią LAN. Tai Layer 2 problema, ir jai reikia Layer 2 atsakymo, pavyzdžiui, tap įrenginio, sujungto su nuotoline sąsaja, arba kliento produkto su aiškiu sujungimo režimu. Tai kainuoja transliacijos ir multicast srautą, kertantį tunelį, ir kaimynų paiešką, kuri turi veikti nuo galo iki galo.
Nebandykite to apytiksliai spręsti pridėdami fe80::/64 prie maršrutuoto profilio. Tai sukuria blogiausią būseną: konfigūracija atrodo baigta, maršrutų lentelė rodo įrašą, o kiekvienas paketas vis dar numetamas kažkur tarp dviejų krūvų, kurios abi elgiasi teisingai.
Tikrinkite sąsaja, o ne ping. ip -6 addr show tun0 pasako, ar tunelio jungtis suformavo savo link-local adresą, o ip -6 route get fe80::1%tun0 pasako, ką branduolys iš tikrųjų darytų su apimtimi pažymėta paskirtimi. Kai branduolys sako, kad paskirties vieta toje sąsajoje nepasiekiama, jokia tunelio nuostata to nepakeis, ir laikas nustoti redaguoti profilį.
Trumpa seka, kuri išsprendžia klausimą:
- Perskaitykite adresą nuotoliniame kompiuteryje ir atkreipkite dėmesį, ar tai fe80::, ar maršrutizuojamas priešdėlis.
- Jei tai fe80::, iš naujo susiekite paslaugą, darykite relę tame kompiuteryje arba sujunkite segmentą; jei maršrutizuojamas, pataisykite maršrutą, ugniasienę ar susiejimo adresą.
- Kiekvieną kartą kartodami testą iš naujo patikrinkite zoną, nes nukopijuota komanda paprastai išlaiko netinkamą sąsają.
Šaltiniai: RFC 4291, IPv6 adresų architektūra.