IPv6 link-local-ը չի աշխատում VPN-ի վրայով. ինչու է fe80-ը կանգ առնում հղումում
fe80:: հասցեն իմաստ ունի միայն մեկ հղումում։ Տեսեք, թե ինչու երթուղվող VPN-ը չի կարող այն տանել, ինչպիսին է խափանումը և որ հասցեն օգտագործել փոխարենը։
Դուք բարձրացնում եք թունելը, ping եք անում fe80::1-ին՝ թունելը որպես աղբյուր ինտերֆեյս, և ոչինչ չի վերադառնում։ Սա ֆայրվոլի կանոն չէ, որ մոռացել եք։ 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-ը կետ-կետ ինտերֆեյս է, որը կրում է իր սեփական հասցեները, սովորաբար թունելի ներսում unique-local կամ մասնավոր IPv6 տարածության /64։ Հեռավոր LAN-ը առանձին հղում է, որին հասնում են թունելի վերջնակետի երթուղումն ու փոխանցումը ձեր փոխարեն։ Դրանք երկու տարբեր սեգմենտներ են, ուստի մեկից վերցված հասցեն վավեր նպատակակետ չէ մյուսում։
Փոխանցման կանոնը հստակ գրված է ստանդարտում, ոչ թե ձեր կլիենտի քմահաճույքն է՝ երթուղիչները չեն փոխանցում link-local աղբյուր կամ նպատակակետ ունեցող փաթեթներ։ Այդ պատճառով փաթեթը մահանում է նույնիսկ այն ժամանակ, երբ երթուղային աղյուսակը ճիշտ է թվում։ Ավելացրեք երթուղի fe80::/64-ի համար դեպի թունելը, և ստանդարտին համապատասխան ստեկը կա՛մ կմերժի այն, կա՛մ կընդունի ու կթափի յուրաքանչյուր համապատասխան փաթեթ՝ նպատակակետի շրջանակն ասում է «միայն այս հղումը», և ելքային ինտերֆեյսը այդ հղումը չէ։
Հարեւանների հայտնաբերումն ամրապնդում է նույն սահմանը։ Հոսթերը լուծում են link-local հաջորդ ցատկերը հարեւանի հարցումով, որն ուղարկվում է հղման շրջանակի multicast-ին 255 ցատկի սահմանաչափով, ուստի երթուղիչները կարող են մերժել ամեն փոխանցված բան։ Դա թունելի միջով աշխատեցնելը կնշանակեր վստահված հայտնաբերում հեռավոր սեգմենտի համար, ինչը Layer 2 կամրջում է՝ այլ գլխարկով։
Կա ավելի լուռ երկրորդ խափանում, և այն բռնում է նրանց, ովքեր ամեն գնով փորձում են պարտադրել երթուղին՝ զոնան։ Ինչ զոնա էլ մուտքագրեք տեղում, այն անվանում է թունելի ինտերֆեյսը, մինչդեռ ձեր ուզած հասցեն կապված է հեռավոր LAN ինտերֆեյսին։ Երկուսը երբեք չեն համընկնի, ուստի փաթեթը չի կարող ուղղվել ճիշտ ինտերֆեյսին հեռավոր ծայրում։
Ինչպիսին է խափանումը գործնականում
Շրջանակի սխալի գործիքային ելքը կարդացվում է որպես երթուղման կամ ֆայրվոլի սխալ, և հենց դա է պատճառը, որ մարդիկ կես օր անցկացնում են սխալ շերտում։
| 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 հասցե, կամ fc00::/7-ից unique-local հասցե, այն միջակայքը, որը վերապահված է հենց այս ներքին դեպքի համար։ Հաստատեք, որ լսողը իսկապես կապում է այն, և ստուգեք վերադարձի ուղին ու հոսթի ցանկացած ֆայրվոլի կանոն։
Նայեք հեռավոր հոսթին՝ գուշակելու փոխարեն։ 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 ցատկը կատարում է տեղում։ Նույն հնարքը աշխատում է սարքի վեբ ինտերֆեյսի կամ հին 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:: է, վերակապեք ծառայությունը, ռելե արեք այդ հոսթում կամ կամրջեք սեգմենտը՝ եթե երթուղվող է, ուղղեք երթուղին, ֆայրվոլը կամ կապակցման հասցեն։
- Ամեն անգամ նորից ստուգելիս վերստուգեք զոնան, քանի որ պատճենված հրամանը սովորաբար պահում է սխալ ինտերֆեյսը։
Աղբյուրներ՝ RFC 4291, IPv6 հասցեավորման ճարտարապետությունը.