Jeg satte net.ipv6.conf.all.forwarding=1 på en Debian-gateway slik at den kunne videresende VPN-klienttrafikk, og omtrent en halvtime senere hadde boksen ingen IPv6-standardrute igjen. Oppstrømsruteren var oppe, den linklokale naboen svarte fortsatt, og uplink hadde fortsatt sin globale adresse. Det som hadde stoppet, var kjernens vilje til å fortsette å ta imot ruterannonser på det grensesnittet. Ruten forsvant ikke da jeg skrev sysctl-kommandoen; den forsvant da levetiden på den RA-lærte standarden gikk ut, og ingenting fornyet den.

Ingenting så ødelagt ut ved første øyekast. Videresendingen virket, klientene kom fortsatt gjennom mens den gamle ruten lå i hurtigbufferen, og feilen kom senere enn endringen som forårsaket den. Den forsinkelsen er grunnen til at dette blir lagt på oppstrømmen eller på en brannmurregel som aldri var involvert.

Les rutetabellen før du rører noen sysctl

Start med ip -6 route show default og les attributtene, ikke bare gatewayen. En RA-lært standard er merket proto ra, bærer en preferanse og viser en expires-nedtelling. En rute du har lagt til for hånd har ingen av delene, og den forskjellen forteller deg hvilken mekanisme som eier ruten.

$ ip -6 route show default
default via fe80::1 dev eth0 proto ra metric 1024 expires 1432sec hoplimit 64 pref medium

Se så på adressen: ip -6 addr show dev eth0. En global adresse med foretrukne og gyldige levetider målt i timer overlever en standardrute der ruterlevetiden måles i minutter. Adresse til stede pluss standard som mangler er signaturen på et annonseproblem. Mangler adressen også, er det lenken, prefiksinformasjonen eller dobbel adressedeteksjon du må jage først.

Hvorfor videresending slår av RA-behandling

En RA er en ICMPv6-pakke av type 134, sendt fra en linklokal kilde med hoppgrense 255. Før kjernen bruker den, konsulterer den grensesnittets accept_ra. Standardverdien er 1, og 1 betyr ikke ja. Det betyr: godta bare mens denne verten ikke videresender. Sett forwarding=1, og den betingelsen feiler, så annonsen forkastes før noe prefiks eller standardruter i den vurderes.

Det finnes tre verdier, og bare den tredje overlever videresending:

accept_raforwarding=0forwarding=1
0ignoredignored
1 (default)acceptedignored
2acceptedaccepted

To andre flagg avgjør hva som faktisk blir installert. accept_ra_defrtr styrer om standardruteren i annonsen blir en rute, og accept_ra_pinfo styrer om prefiksinformasjon brukes til adressekonfigurasjon. Å slå av accept_ra_defrtr er den vanlige måten å beholde SLAAC-adresser på en videresendende vert uten å lære en standard. Det er en annen spak enn accept_ra, og det er den du griper når du vil ha adresser men ikke en rute. Kjernens IP-sysctl-referanse lister alle tre.

Bekreft det med tre kommandoer

Les først de levende verdiene i stedet for filen du tror er lastet:

sysctl net.ipv6.conf.eth0.forwarding net.ipv6.conf.all.forwarding \
       net.ipv6.conf.eth0.accept_ra net.ipv6.conf.eth0.accept_ra_defrtr

Bevis for det andre at annonsene fortsatt kommer inn. Filtrering på ICMPv6-typebyten er nok, og det sparer deg for en vegg med nabo-oppdagelsestrafikk:

tcpdump -ni eth0 'icmp6 and ip6[40] == 134'

Hvis det ikke dukker opp noe i løpet av flere minutter, er accept_ra ikke problemet ditt. Oppstrømmen sluttet å annonsere, noe på veien filtrerer ICMPv6, eller så er ikke det grensesnittet faktisk på segmentet du tror. Be for det tredje selv om en annonse og les feltene:

rdisc6 eth0

rdisc6 ligger i ndisc6-pakken på Debian og Ubuntu. Se på ruterlevetiden og preferansen i utdataene før du endrer noe annet. En annonse med ruterlevetid 0 er en beskjed om å fjerne standardruteren, og ingen accept_ra-verdi gjør det til en brukbar rute. Det er også slik du fanger en oppstrøms CPE i bromodus som deler ut prefikser men aldri tilbyr seg selv som ruter.

Gjør uplink til det eneste tillatende grensesnittet

Hvis oppstrømmen skal være standardruteren, godta annonser der til tross for videresending, og ingen andre steder:

# /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

Avgrenningen betyr noe fordi IPv6-videresending er én global bryter i Linux, ikke én per lenke. Skriv 1 til net.ipv6.conf.wg0.forwarding og les deretter net.ipv6.conf.all.forwarding: den globale verdien vippes, og hvert grensesnitt begynner å videresende. Du kan ikke være ruter på tunnelen og vanlig vert på LAN-et. Det du kan avgrense, er godtakelsen. Hold accept_ra=2 på uplink og la tunne- og LAN-grensesnittene stå på 1 eller 0, slik at en villfaren annonse som kommer over tunnelen ikke kan installere en standard som peker inn i den.

En midlertidig sysctl -w overlever ikke neste omstart, og både systemd-networkd og NetworkManager skriver disse verdiene fra sin egen konfigurasjon. I networkd setter du IPv6Forwarding=yes og IPv6AcceptRA=yes i uplinkets .network-fil; networkd dokumenterer IPv6Forwarding som global av samme kjernegrunn. Med NetworkManager er ipv6.method=auto på uplink det som driver accept_ra-verdien, så les sysctl på nytt etter nmcli connection up i stedet for å stole på den første kontrollen.

Det statiske alternativet, ip -6 route add default via fe80::1 dev eth0, virker faktisk, og det er et rimelig svar når oppstrømsruteren har en stabil linklokal adresse. Vær tydelig på hva du gir opp. En statisk standard blir aldri fornyet og aldri trukket tilbake, så den fortsetter å peke på en død nabo etter at oppstrømmen er byttet. RA-ruten feiler trygt; den statiske feiler stille.

Test en videresendt pakke, ikke gatewayens egen

Gatewayens egne ping kan lykkes på en rute ingen klient kan bruke, og de kan også lykkes fordi gatewayen er kilden. Test fra en tilkoblet klient og spør deretter gatewayen hva den ville gjort for den klientens adresse:

# 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

Vent så én ruterlevetid og se igjen. Den stabile tilstanden du vil ha, er en standard merket proto ra der expires-verdien stadig nullstilles, pluss all.forwarding=1. Hvis expires bare teller ned, blir annonser fortsatt forkastet et sted, og den vanlige skyldige er en nettverksbehandler som overskriver accept_ra etter at sysctl ved oppstart allerede har kjørt.

Før du avslutter dette, bekreft fire ting: standardruten er proto ra og fornyes, accept_ra=2 gjelder bare for uplink, videresending er fortsatt 1 etter en omstart og etter en behandler-omstart, og en klient i stedet for gatewayen fullfører en IPv6-ping. Hvis klienten fortsatt feiler med en sunn rute, er den neste mistenkte returveien eller en brannmur oppstrøms, ikke annonsen.

Relaterte artikler