Linux-ում վերահասցեավորումը միացնելուց հետո IPv6-ի լռելյայն երթուղին անհետացավ
Երբ միացված է IPv6 վերահասցեավորումը, միջուկը անտեսում է router advertisements-ները uplink-ում, և սովորած լռելյայն երթուղին սպառվում է։ Ուղղեք accept_ra-ով։
Ես net.ipv6.conf.all.forwarding=1 դրեցի Debian դարպասի վրա, որպեսզի այն կարողանա փոխանցել VPN հաճախորդների տրաֆիկը, և մոտ կես ժամ անց մեքենան այլևս չուներ IPv6 լռելյայն երթուղի։ Վերին երթուղիչը աշխատում էր, link-local հարևանը դեռ պատասխանում էր, և uplink-ը դեռ պահպանում էր իր գլոբալ հասցեն։ Դադարել էր միջուկի պատրաստակամությունը շարունակել ընդունել router advertisements այդ ինտերֆեյսում։ Երթուղին չանհետացավ այն պահին, երբ ես մուտքագրեցի sysctl-ը, այն անհետացավ, երբ սպառվեց RA-ից սովորած լռելյայն երթուղու ժամկետը, և ոչինչ այն չթարմացրեց։
Առաջին հայացքից ոչինչ կոտրված չէր թվում։ Փոխանցումը աշխատում էր, հաճախորդները դեռ անցնում էին, քանի դեռ հին երթուղին քեշում էր, և խափանումը եկավ ավելի ուշ, քան այն առաջացրած փոփոխությունը։ Հենց այդ ուշացման պատճառով է, որ մեղքը դրվում է վերին կողմի կամ այն firewall կանոնի վրա, որը երբեք չի մասնակցել։
Կարդացեք երթուղիների աղյուսակը, նախքան որևէ sysctl-ի դիպչելը
Սկսեք ip -6 route show default-ով և կարդացեք հատկանիշները, ոչ միայն դարպասը։ RA-ից սովորած լռելյայն երթուղին նշված է proto ra-ով, կրում է նախապատվություն և ցուցադրում է expires հակահաշիվ։ Ձեռքով ավելացված երթուղին չունի ոչ մեկը, ոչ մյուսը, և այդ տարբերությունը ձեզ ասում է, թե որ մեխանիզմն է տիրում երթուղուն։
$ ip -6 route show default
default via fe80::1 dev eth0 proto ra metric 1024 expires 1432sec hoplimit 64 pref mediumԱյնուհետև նայեք հասցեին՝ ip -6 addr show dev eth0։ Գլոբալ հասցեն, որի նախընտրելի և վավեր ժամկետները ժամերով են չափվում, կապրի ավելի երկար, քան լռելյայն երթուղին, որի երթուղիչի ժամկետը րոպեներով է չափվում։ Հասցեն կա, իսկ լռելյայն երթուղին բացակայում է, սա հայտարարությունների խնդրի ստորագրությունն է։ Եթե հասցեն նույնպես բացակայում է, նախ պետք է զբաղվել կապով, նախածանցի տեղեկությամբ կամ կրկնակի հասցեների հայտնաբերմամբ։
Ինչու է փոխանցումը անջատում RA-ի մշակումը
RA-ն ICMPv6 134 տիպի փաթեթ է, ուղարկված link-local աղբյուրից՝ 255 ցատկի սահմանով։ Նախքան միջուկը կօգտագործի այն, այն ստուգում է ինտերֆեյսի accept_ra արժեքը։ Լռելյայն արժեքը 1 է, և 1-ը չի նշանակում այո։ Այն նշանակում է՝ ընդունիր միայն այնքան ժամանակ, քանի դեռ այս հոսթը չի փոխանցում։ Սահմանեք forwarding=1, և այդ պայմանը չի կատարվում, ուստի հայտարարությունը մերժվում է, նախքան դրանում եղած որևէ նախածանց կամ լռելյայն երթուղիչ դիտարկելը։
Գոյություն ունեն երեք արժեք, և փոխանցումը հաղթահարում է միայն երրորդը՝
accept_ra | forwarding=0 | forwarding=1 |
|---|---|---|
| 0 | ignored | ignored |
| 1 (default) | accepted | ignored |
| 2 | accepted | accepted |
Եվս երկու դրոշ որոշում են, թե ինչ է իրականում տեղադրվում։ accept_ra_defrtr-ը կառավարում է, թե արդյոք հայտարարության մեջ եղած լռելյայն երթուղիչը դառնում է երթուղի, իսկ accept_ra_pinfo-ը՝ թե արդյոք նախածանցի տեղեկությունը օգտագործվում է հասցեի կարգավորման համար։ accept_ra_defrtr-ը անջատելը սովորական միջոց է՝ SLAAC հասցեները փոխանցող հոսթի վրա պահելու առանց լռելյայն երթուղի սովորելու։ Սա այլ լծակ է, քան accept_ra-ը, և դրան դիմում են, երբ հասցեներ են պետք, բայց ոչ երթուղի։ Միջուկի IP sysctl տեղեկատուն թվարկում է բոլոր երեքը։
Հաստատեք երեք հրամանով
Նախ կարդացեք կենդանի արժեքները՝ ձեր կարծիքով բեռնված ֆայլի փոխարեն՝
sysctl net.ipv6.conf.eth0.forwarding net.ipv6.conf.all.forwarding \
net.ipv6.conf.eth0.accept_ra net.ipv6.conf.eth0.accept_ra_defrtrԵրկրորդ՝ ապացուցեք, որ հայտարարությունները դեռ գալիս են։ ICMPv6 տիպի բայթով զտելը բավարար է և փրկում է ձեզ հարևանների հայտնաբերման տրաֆիկի պատը կարդալուց՝
tcpdump -ni eth0 'icmp6 and ip6[40] == 134'Եթե մի քանի րոպե ոչինչ չհայտնվի, accept_ra-ը ձեր խնդիրը չէ։ Վերին կողմը դադարեց հայտարարել, ուղու վրա ինչ-որ բան զտում է ICMPv6-ը, կամ այդ ինտերֆեյսը իսկապես այն սեգմենտում չէ, ինչ դուք մտածում եք։ Երրորդ՝ ինքներդ հայցեք հայտարարություն և կարդացեք դրա դաշտերը՝
rdisc6 eth0rdisc6-ը գալիս է ndisc6 փաթեթում Debian-ում և Ubuntu-ում։ Արդյունքում նայեք երթուղիչի ժամկետին և նախապատվությանը, նախքան այլ բան փոխելը։ 0 երթուղիչի ժամկետով հայտարարությունը հրահանգ է հեռացնել լռելյայն երթուղիչը, և ոչ մի accept_ra արժեք դա չի դարձնի օգտագործելի երթուղի։ Այսպես նաև բռնում եք կամրջի ռեժիմում գտնվող վերին CPE-ն, որը բաժանում է նախածանցներ, բայց երբեք իրեն չի առաջարկում որպես երթուղիչ։
Դարձրեք uplink-ը միակ թույլատրող ինտերֆեյսը
Եթե վերին կողմը պետք է լինի լռելյայն երթուղիչը, ընդունեք հայտարարություններն այնտեղ՝ չնայած փոխանցմանը, և ուրիշ ոչ մի տեղ՝
# /etc/sysctl.d/60-ipv6-router.conf
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.eth0.accept_ra = 2
net.ipv6.conf.eth0.accept_ra_defrtr = 1Սահմանափակումը կարևոր է, որովհետև Linux-ում IPv6 փոխանցումը մեկ գլոբալ անջատիչ է, ոչ թե մեկը յուրաքանչյուր կապի համար։ Գրեք 1 net.ipv6.conf.wg0.forwarding-ի մեջ և ապա կարդացեք net.ipv6.conf.all.forwarding-ը՝ գլոբալ արժեքը շրջվում է, և յուրաքանչյուր ինտերֆեյս սկսում է փոխանցել։ Դուք չեք կարող լինել երթուղիչ թունելում և սովորական հոսթ LAN-ում։ Սահմանափակել կարող եք ընդունումը։ Պահեք accept_ra=2-ը uplink-ում, իսկ թունելի և LAN-ի ինտերֆեյսները թողեք 1 կամ 0-ի վրա, որպեսզի թունելով եկած մոլորված հայտարարությունը չկարողանա տեղադրել դրա մեջ ուղղված լռելյայն երթուղի։
Ժամանակավոր sysctl -w-ը չի վերապրի հաջորդ վերագործարկումը, և ինչպես systemd-networkd-ը, այնպես էլ NetworkManager-ը գրում են այս արժեքները իրենց սեփական կարգավորումից։ networkd-ում սահմանեք IPv6Forwarding=yes-ը և IPv6AcceptRA=yes-ը uplink-ի .network ֆայլում, networkd-ը IPv6Forwarding-ը նկարագրում է որպես գլոբալ նույն միջուկային պատճառով։ NetworkManager-ի դեպքում uplink-ի ipv6.method=auto-ն է ղեկավարում accept_ra արժեքը, ուստի nmcli connection up-ից հետո նորից կարդացեք sysctl-ը՝ փոխարենը չվստահելով առաջին ստուգմանը։
Ստատիկ այլընտրանքը՝ ip -6 route add default via fe80::1 dev eth0-ը, իսկապես աշխատում է, և խելամիտ պատասխան է, երբ վերին երթուղիչն ունի կայուն link-local հասցե։ Հստակ իմացեք, թե ինչից եք հրաժարվում։ Ստատիկ լռելյայն երթուղին երբեք չի թարմացվում և երբեք չի հետ կանչվում, ուստի վերին կողմը փոխելուց հետո այն շարունակում է ցույց տալ մեռած հարևանի վրա։ RA երթուղին ձախողվում է ապահով, ստատիկը՝ լուռ։
Փորձարկեք փոխանցված փաթեթ, ոչ թե հենց դարպասի փաթեթը
Դարպասի սեփական ping-երը կարող են հաջողվել մի երթուղով, որ ոչ մի հաճախորդ չի կարող օգտագործել, և կարող են հաջողվել նաև այն պատճառով, որ դարպասը աղբյուրն է։ Փորձարկեք միացված հաճախորդից, ապա հարցրեք դարպասին, թե ինչ կանի այդ հաճախորդի հասցեի համար՝
# on the VPN client
ping -6 -c 3 2001:4860:4860::8888
# on the gateway, using a client address
ip -6 route get 2001:4860:4860::8888 from fd42:20::2Այնուհետև սպասեք մեկ երթուղիչի ժամկետ և նորից նայեք։ Ցանկալի կայուն վիճակը proto ra-ով նշված լռելյայն երթուղին է, որի expires արժեքը անընդհատ վերականգնվում է, գումարած all.forwarding=1-ը։ Եթե expires-ը միայն հակահաշվում է, հայտարարությունները դեռ ինչ-որ տեղ մերժվում են, և սովորական մեղավորն այն ցանցի կառավարիչն է, որը վերագրում է accept_ra-ը այն բանից հետո, երբ բեռնման ժամանակ sysctl-ը արդեն կատարվել է։
Նախքան սա փակելը, հաստատեք չորս բան՝ լռելյայն երթուղին proto ra է և թարմանում է, accept_ra=2-ը վերաբերում է միայն uplink-ին, փոխանցումը դեռ 1 է վերագործարկումից հետո և կառավարիչը վերագործարկելուց հետո, և IPv6 ping-ը ավարտում է հաճախորդը, ոչ թե դարպասը։ Եթե հաճախորդը առողջ երթուղով դեռ ձախողվում է, հաջորդ կասկածյալը վերադարձի ուղին կամ վերին firewall-ն է, ոչ թե հայտարարությունը։