IPv6-standardruta forsvann etter at videresending vart slått på i Linux
Når du slår på IPv6-videresending, overser kjernen ruterannonsar på uplink, og den lærte standardruta går ut. Rett det med accept_ra.
Eg sette net.ipv6.conf.all.forwarding=1 på ein Debian-gateway slik at han kunne videresende VPN-klienttrafikk, og om lag ein halvtime seinare hadde boksen inga IPv6-standardrute att. Oppstraumsrutaren var oppe, den lenkelokale naboen svara framleis, og uplink hadde framleis den globale adressa si. Det som hadde stoppa, var viljen til kjernen til å halde fram med å ta imot ruterannonsar på det grensesnittet. Ruta forsvann ikkje då eg skreiv sysctl-kommandoen; ho forsvann då levetida på den RA-lærte standarden gjekk ut, og ingenting fornya ho.
Ingenting såg øydelagt ut ved første augekast. Videresendinga verka, klientane kom framleis gjennom medan den gamle ruta låg i hurtiglageret, og feilen kom seinare enn endringa som førte til han. Den forseinkinga er grunnen til at dette blir lagt på oppstraumen eller på ei brannmurregel som aldri var involvert.
Les rutetabellen før du rører nokon sysctl
Start med ip -6 route show default og les attributta, ikkje berre gatewayen. Ein RA-lært standard er merkt proto ra, ber ein preferanse og viser ei expires-nedteljing. Ei rute du har lagt til for hand har ingen av delane, og den skilnaden fortel deg kva mekanisme som eig ruta.
$ ip -6 route show default
default via fe80::1 dev eth0 proto ra metric 1024 expires 1432sec hoplimit 64 pref mediumSjå så på adressa: ip -6 addr show dev eth0. Ei global adresse med føretrekte og gyldige levetider målt i timar overlever ei standardrute der ruterlevetida blir målt i minutt. Adresse til stades plus standard som manglar er signaturen på eit annonseproblem. Manglar adressa òg, er det lenka, prefiksinformasjonen eller dobbel adressedeteksjon du må jage først.
Kvifor videresending slår av RA-handsaming
Ein RA er ei ICMPv6-pakke av type 134, send frå ei lenkelokal kjelde med hoppgrens 255. Før kjernen brukar ho, rådfører han seg med accept_ra til grensesnittet. Standardverdien er 1, og 1 tyder ikkje ja. Det tyder: godta berre medan denne verten ikkje videresender. Set forwarding=1, og det vilkåret feilar, så annonsen blir forkasta før noko prefiks eller standardruter i han blir vurdert.
Det finst tre verdiar, og berre den tredje overlever videresending:
accept_ra | forwarding=0 | forwarding=1 |
|---|---|---|
| 0 | ignored | ignored |
| 1 (default) | accepted | ignored |
| 2 | accepted | accepted |
To andre flagg avgjer kva som faktisk blir installert. accept_ra_defrtr styrer om standardrutaren i annonsen blir ei rute, og accept_ra_pinfo styrer om prefiksinformasjon blir brukt til adressekonfigurasjon. Å slå av accept_ra_defrtr er den vanlege måten å behalde SLAAC-adresser på ein videresendande vert utan å lære ein standard. Det er ein annan spak enn accept_ra, og det er den du grip når du vil ha adresser men ikkje ei rute. IP-sysctl-referansen til kjernen listar alle tre.
Stadfest det med tre kommandoar
Les først dei levande verdiane i staden for fila du trur er lasta:
sysctl net.ipv6.conf.eth0.forwarding net.ipv6.conf.all.forwarding \
net.ipv6.conf.eth0.accept_ra net.ipv6.conf.eth0.accept_ra_defrtrProv for det andre at annonsane framleis kjem inn. Filtrering på ICMPv6-typebyten er nok, og det sparer deg for ein vegg med nabo-oppdagingstrafikk:
tcpdump -ni eth0 'icmp6 and ip6[40] == 134'Viss det ikkje dukkar opp noko i løpet av fleire minutt, er accept_ra ikkje problemet ditt. Oppstraumen slutta å annonsere, noko på vegen filtrerer ICMPv6, eller så er ikkje det grensesnittet faktisk på segmentet du trur. Be for det tredje sjølv om ein annonse og les felta:
rdisc6 eth0rdisc6 ligg i ndisc6-pakken på Debian og Ubuntu. Sjå på ruterlevetida og preferansen i utdata før du endrar noko anna. Ein annonse med ruterlevetid 0 er ei melding om å fjerne standardrutaren, og ingen accept_ra-verdi gjer det til ei brukbar rute. Det er òg slik du fangar ein oppstraums CPE i bromodus som deler ut prefiks men aldri tilbyr seg sjølv som ruter.
Gjer uplink til det einaste tillatande grensesnittet
Viss oppstraumen skal vere standardrutaren, godta annonsar der trass i videresending, og ingen andre stader:
# /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 = 1Avgrensinga betyr noko fordi IPv6-videresending er ein global brytar i Linux, ikkje ein per lenke. Skriv 1 til net.ipv6.conf.wg0.forwarding og les deretter net.ipv6.conf.all.forwarding: den globale verdien vippar, og kvart grensesnitt byrjar å videresende. Du kan ikkje vere ruter på tunnelen og vanleg vert på LAN-et. Det du kan avgrense, er godtakinga. Hald accept_ra=2 på uplink og la tunne- og LAN-grensesnitta stå på 1 eller 0, slik at ein villfaren annonse som kjem over tunnelen ikkje kan installere ein standard som peikar inn i han.
Ein mellombels sysctl -w overlever ikkje neste omstart, og både systemd-networkd og NetworkManager skriv desse verdiane frå sin eigen konfigurasjon. I networkd set du IPv6Forwarding=yes og IPv6AcceptRA=yes i .network-fila til uplink; networkd dokumenterer IPv6Forwarding som global av same kjernegrunn. Med NetworkManager er ipv6.method=auto på uplink det som driv accept_ra-verdien, så les sysctl på nytt etter nmcli connection up i staden for å stole på den første kontrollen.
Det statiske alternativet, ip -6 route add default via fe80::1 dev eth0, verkar faktisk, og det er eit rimeleg svar når oppstraumsrutaren har ei stabil lenkelokal adresse. Ver tydeleg på kva du gjev opp. Ein statisk standard blir aldri fornya og aldri trekt tilbake, så han held fram med å peike på ein død nabo etter at oppstraumen er bytt. RA-ruta feilar trygt; den statiske feilar stille.
Test ei videresend pakke, ikkje gatewayen si eiga
Gatewayen sine eigne ping kan lukkast på ei rute ingen klient kan bruke, og dei kan òg lukkast fordi gatewayen er kjelda. Test frå ein tilkopla klient og spør deretter gatewayen kva han ville gjere for adressa til den klienten:
# 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::2Vent så éi ruterlevetid og sjå igjen. Den stabile tilstanden du vil ha, er ein standard merkt proto ra der expires-verdien stadig blir nullstilt, pluss all.forwarding=1. Viss expires berre tel ned, blir annonsar framleis forkasta ein stad, og den vanlege skuldige er ein nettverkshandsamar som skriv over accept_ra etter at sysctl ved oppstart allereie har køyrt.
Før du avsluttar dette, stadfest fire ting: standardruta er proto ra og blir fornya, accept_ra=2 gjeld berre for uplink, videresending er framleis 1 etter ein omstart og etter ein handsamar-omstart, og ein klient i staden for gatewayen fullfører ein IPv6-ping. Viss klienten framleis feilar med ei sunn rute, er den neste mistenkte returvegen eller ein brannmur oppstraums, ikkje annonsen.