Įjungus IPv6 persiuntimą Linux sistemoje dingo numatytasis maršrutas
Įjungus IPv6 persiuntimą, branduolys nepaiso router advertisements uplink kanale, todėl išmoktas numatytasis maršrutas pasibaigia. Sutvarkykite naudodami accept_ra.
Debian šliuzei nustačiau net.ipv6.conf.all.forwarding=1, kad ji galėtų persiųsti VPN klientų srautą, ir po maždaug pusvalandžio mašinoje nebeliko jokio numatytojo IPv6 maršruto. Viršutinis maršrutizatorius veikė, link-local kaimynas vis dar atsakydavo, o uplink kanalas tebeturėjo savo globalų adresą. Tai, kas sustojo, buvo branduolio noras tame sąsajoje toliau priimti router advertisements. Maršrutas dingo ne tada, kai įvedžiau sysctl; jis dingo tada, kai baigėsi iš RA išmokto numatytojo maršruto galiojimas ir niekas jo neatnaujino.
Iš pirmo žvilgsnio niekas neatrodė sugedę. Persiuntimas veikė, klientai vis dar praeidavo, kol senasis maršrutas buvo podėlyje, o gedimas atėjo vėliau nei jį sukėlęs pakeitimas. Būtent dėl šio vėlavimo kaltė suverčiama viršutinei pusei arba ugniasienės taisyklei, kuri niekada nebuvo susijusi.
Perskaitykite maršrutų lentelę prieš liesdami bet kurį sysctl
Pradėkite nuo ip -6 route show default ir skaitykite atributus, o ne vien šliuzą. Iš RA išmoktas numatytasis maršrutas pažymėtas proto ra, turi pirmenybę ir rodo expires atgalinį skaičiavimą. Rankiniu būdu pridėtas maršrutas neturi nė vieno, ir šis skirtumas pasako, kuris mechanizmas valdo maršrutą.
$ ip -6 route show default
default via fe80::1 dev eth0 proto ra metric 1024 expires 1432sec hoplimit 64 pref mediumTada pažiūrėkite į adresą: ip -6 addr show dev eth0. Globalus adresas, kurio pageidaujamas ir galiojantis galiojimas matuojamas valandomis, pergyvens numatytąjį maršrutą, kurio maršrutizatoriaus galiojimas matuojamas minutėmis. Adresas yra, o numatytojo maršruto nėra, tai yra skelbimų problemos požymis. Jei trūksta ir adreso, pirmiausia reikia tirti jungtį, prefikso informaciją arba pasikartojančių adresų aptikimą.
Kodėl persiuntimas išjungia RA apdorojimą
RA yra 134 tipo ICMPv6 paketas, siunčiamas iš link-local šaltinio su 255 šuolio riba. Prieš branduoliui jį naudojant, jis patikrina sąsajos accept_ra reikšmę. Numatytoji reikšmė yra 1, o 1 nereiškia taip. Ji reiškia: priimk tik tol, kol šis mazgas persiunčia. Nustatykite forwarding=1 ir ši sąlyga nebetenkinama, todėl skelbimas atmetamas dar prieš jame esantį prefiksą ar numatytąjį maršrutizatorių.
Yra trys reikšmės, ir persiuntimą pergyvena tik trečioji:
accept_ra | forwarding=0 | forwarding=1 |
|---|---|---|
| 0 | ignored | ignored |
| 1 (default) | accepted | ignored |
| 2 | accepted | accepted |
Dar dvi vėliavėlės nusprendžia, kas iš tikrųjų įdiegiama. accept_ra_defrtr valdo, ar skelbime esantis numatytasis maršrutizatorius taps maršrutu, o accept_ra_pinfo valdo, ar prefikso informacija bus naudojama adreso konfigūracijai. accept_ra_defrtr išjungimas yra įprastas būdas išlaikyti SLAAC adresus persiunčiančiame mazge nesimokant numatytojo maršruto. Tai kita svirtis nei accept_ra, ir jos griebiamasi, kai reikia adresų, bet ne maršruto. Branduolio IP sysctl žinynas išvardija visas tris.
Patvirtinkite trimis komandomis
Pirmiausia perskaitykite gyvas reikšmes, o ne failą, kurį, jūsų manymu, įkėlėte:
sysctl net.ipv6.conf.eth0.forwarding net.ipv6.conf.all.forwarding \
net.ipv6.conf.eth0.accept_ra net.ipv6.conf.eth0.accept_ra_defrtrAntra, įrodykite, kad skelbimai vis dar ateina. Filtravimo pagal ICMPv6 tipo baitą pakanka, ir tai apsaugo nuo kaimynų aptikimo srauto sienos skaitymo:
tcpdump -ni eth0 'icmp6 and ip6[40] == 134'Jei per kelias minutes nieko nepasirodo, accept_ra nėra jūsų problema. Viršutinė pusė nustojo skelbti, kažkas kelyje filtruoja ICMPv6, arba ta sąsaja iš tikrųjų yra ne tame segmente, apie kurį galvojate. Trečia, patys paprašykite skelbimo ir perskaitykite jo laukus:
rdisc6 eth0rdisc6 yra pakete ndisc6 Debian ir Ubuntu sistemose. Išvestyje pažiūrėkite į maršrutizatoriaus galiojimą ir pirmenybę prieš ką nors kita keisdami. Skelbimas, kurio maršrutizatoriaus galiojimas yra 0, yra nurodymas pašalinti numatytąjį maršrutizatorių, ir jokia accept_ra reikšmė to nepaverčia naudojamu maršrutu. Taip pat pagausite viršutinį CPE tiltinėje veikoje, kuris dalija prefiksus, bet niekada nepasiūlo savęs kaip maršrutizatoriaus.
Padarykite uplink vienintele leidžiančia sąsaja
Jei viršutinė pusė turi būti numatytasis maršrutizatorius, priimkite ten skelbimus nepaisydami persiuntimo, ir niekur kitur:
# /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 = 1Apribojimas svarbus, nes IPv6 persiuntimas Linux sistemoje yra vienas globalus jungiklis, o ne po vieną kiekvienai jungčiai. Įrašykite 1 į net.ipv6.conf.wg0.forwarding ir tada perskaitykite net.ipv6.conf.all.forwarding: globali reikšmė apsisuka ir kiekviena sąsaja pradeda persiųsti. Negalite būti maršrutizatorius tunelyje ir paprastas mazgas LAN tinkle. Apriboti galite priėmimą. Laikykite accept_ra=2 uplink kanale, o tunelio ir LAN sąsajas palikite 1 arba 0, kad per tunelį atėjęs paklydęs skelbimas negalėtų įdiegti į jį nukreipiančio numatytojo maršruto.
Laikinas sysctl -w neišgyvens kito paleidimo, o ir systemd-networkd, ir NetworkManager rašo šias reikšmes iš savo konfigūracijos. networkd atveju nustatykite IPv6Forwarding=yes ir IPv6AcceptRA=yes uplink kanalo .network faile; networkd dokumentuoja IPv6Forwarding kaip globalų dėl tos pačios branduolio priežasties. Naudojant NetworkManager, uplink kanale ipv6.method=auto valdo accept_ra reikšmę, todėl po nmcli connection up dar kartą perskaitykite sysctl, o nepasitikėkite pirmuoju patikrinimu.
Statinė alternatyva, ip -6 route add default via fe80::1 dev eth0, tikrai veikia, ir tai yra pagrįstas atsakymas, kai viršutinis maršrutizatorius turi stabilų link-local adresą. Aiškiai žinokite, ko atsisakote. Statinis numatytasis maršrutas niekada neatnaujinamas ir niekada neatšaukiamas, todėl po viršutinės pusės pakeitimo jis toliau rodo į negyvą kaimyną. RA maršrutas sugenda saugiai; statinis sugenda tyliai.
Testuokite persiųstą paketą, o ne paties šliuzo paketą
Paties šliuzo ping gali pavykti maršrutu, kurio joks klientas negali naudoti, ir gali pavykti todėl, kad šliuzas yra šaltinis. Testuokite iš prisijungusio kliento, o tada paklauskite šliuzo, ką jis darytų to kliento adresui:
# 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::2Tada palaukite vieną maršrutizatoriaus galiojimą ir pažiūrėkite dar kartą. Norima stabili būsena yra numatytasis maršrutas, pažymėtas proto ra, kurio expires reikšmė nuolat atsinaujina, plius all.forwarding=1. Jei expires tik skaičiuoja atgal, skelbimai vis dar kažkur atmetami, o įprastas kaltininkas yra tinklo valdytojas, perrašantis accept_ra po to, kai paleidimo metu sysctl jau buvo įvykdytas.
Prieš užbaigdami patvirtinkite keturis dalykus: numatytasis maršrutas yra proto ra ir atsinaujina, accept_ra=2 galioja tik uplink kanalui, persiuntimas po perkrovimo ir po valdytojo perkrovimo vis dar yra 1, o IPv6 ping užbaigia klientas, o ne šliuzas. Jei klientas vis dar nepavyksta su sveiku maršrutu, kitas įtariamasis yra grįžimo kelias arba viršutinė ugniasienė, o ne skelbimas.