Nastavil som net.ipv6.conf.all.forwarding=1 na bráne Debian, aby mohla preposielať prevádzku VPN klientov, a asi o pol hodiny nemal stroj žiadnu predvolenú trasu IPv6. Nadradený smerovač bol v poriadku, link-local sused stále odpovedal a uplink si držal svoju globálnu adresu. To, čo sa zastavilo, bola ochota jadra naďalej prijímať router advertisements na tom rozhraní. Trasa nezmizla v okamihu, keď som sysctl zadal; zmizla, keď vypršala platnosť predvolenej trasy naučenej z RA a nič ju neobnovilo.

Na prvý pohľad nič nevyzeralo pokazené. Preposielanie fungovalo, klienti prechádzali, kým bola stará trasa v cache, a porucha prišla neskôr než zmena, ktorá ju spôsobila. Práve pre toto oneskorenie sa to zvaľuje na nadradenú stranu alebo na pravidlo firewallu, ktoré s tým nikdy nesúviselo.

Prečítajte si smerovaciu tabuľku, skôr než sa dotknete akéhokoľvek sysctl

Začnite príkazom ip -6 route show default a čítajte atribúty, nielen bránu. Predvolená trasa naučená z RA je označená proto ra, nesie preferenciu a ukazuje odpočet expires. Trasa pridaná ručne nemá ani jedno, a ten rozdiel vám povie, ktorý mechanizmus trasu vlastní.

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

Potom sa pozrite na adresu: ip -6 addr show dev eth0. Globálna adresa s preferovanou a platnou životnosťou v hodinách prežije predvolenú trasu, ktorej životnosť smerovača sa meria v minútach. Adresa existuje a predvolená trasa chýba, to je podpis problému s ohlásmi. Ak chýba aj adresa, treba najprv riešiť link, informácie o prefixe alebo detekciu duplicitných adries.

Prečo preposielanie vypína spracovanie RA

RA je paket ICMPv6 typu 134, odoslaný z link-local zdroja s limitom skoku 255. Skôr než ho jadro použije, pozrie sa na accept_ra rozhrania. Predvolená hodnota je 1 a 1 neznamená áno. Znamená: prijímaj len dovtedy, kým tento hostiteľ nepreposiela. Nastavte forwarding=1 a táto podmienka prestane platiť, takže sa ohlás zahodí skôr, než sa v ňom zváži akýkoľvek prefix alebo predvolený smerovač.

Existujú tri hodnoty a preposielanie prežije len tá tretia:

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

Dva ďalšie príznaky rozhodujú, čo sa skutočne nainštaluje. accept_ra_defrtr riadi, či sa predvolený smerovač z ohlásu stane trasou, a accept_ra_pinfo riadi, či sa informácie o prefixe použijú na konfiguráciu adresy. Vypnutie accept_ra_defrtr je obvyklý spôsob, ako na preposielajúcom hostiteľovi udržať adresy SLAAC bez učenia sa predvolenej trasy. Je to iná páka než accept_ra a siaha sa po nej, keď chcete adresy, ale nie trasu. Referencia jadra k IP sysctl uvádza všetky tri.

Overte to tromi príkazmi

Najprv si prečítajte živé hodnoty namiesto súboru, o ktorom si myslíte, že je načítaný:

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

Zadruhé dokážte, že ohlásy stále prichádzajú. Filtrovanie podľa bajtu typu ICMPv6 stačí a ušetrí vám čítanie steny prevádzky objavovania susedov:

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

Ak sa počas niekoľkých minút nič neobjaví, accept_ra nie je váš problém. Nadradená strana prestala ohlasovať, niečo na ceste filtruje ICMPv6 alebo to rozhranie v skutočnosti nie je na segmente, ktorý si myslíte. Po tretie si vyžiadajte ohlás sami a prečítajte jeho polia:

rdisc6 eth0

rdisc6 je v balíku ndisc6 na Debiane a Ubuntu. Vo výstupe sa pozrite na životnosť smerovača a preferenciu, skôr než čokoľvek iné zmeníte. Ohlás so životnosťou smerovača 0 je pokyn na odstránenie predvoleného smerovača a žiadna hodnota accept_ra z toho neurobí použiteľnú trasu. Takto tiež zachytíte nadradené CPE v režime mosta, ktoré rozdáva prefixy, ale nikdy sa neponúkne ako smerovač.

Urobte z uplinku jediné povoľujúce rozhranie

Ak má byť nadradená strana predvoleným smerovačom, prijímajte tam ohlásy aj napriek preposielaniu, a nikde inde:

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

Obmedzenie je dôležité, pretože preposielanie IPv6 je v Linuxe jeden globálny prepínač, nie jeden na link. Zapíšte 1 do net.ipv6.conf.wg0.forwarding a potom prečítajte net.ipv6.conf.all.forwarding: globálna hodnota sa preklopí a každé rozhranie začne preposielať. Nemôžete byť smerovač na tuneli a obyčajný hostiteľ v sieti LAN. Obmedziť môžete prijímanie. Držte accept_ra=2 na uplinku a rozhrania tunela a LAN nechajte na 1 alebo 0, aby zblúdený ohlás, ktorý dorazí tunelom, nemohol nainštalovať predvolenú trasu ukazujúcu doň.

Dočasné sysctl -w neprežije ďalší reštart a ako systemd-networkd, tak NetworkManager zapisujú tieto hodnoty zo svojej vlastnej konfigurácie. V networkd nastavte IPv6Forwarding=yes a IPv6AcceptRA=yes v súbore .network uplinku; networkd dokumentuje IPv6Forwarding ako globálne z rovnakého dôvodu v jadre. Pri NetworkManageri je ipv6.method=auto na uplinku to, čo riadi hodnotu accept_ra, takže po nmcli connection up čítajte sysctl znova, namiesto toho aby ste verili prvej kontrole.

Statická alternatíva, ip -6 route add default via fe80::1 dev eth0, naozaj funguje a je rozumnou odpoveďou, keď má nadradený smerovač stabilnú link-local adresu. Buďte si jasní v tom, čo obetujete. Statická predvolená trasa sa nikdy neobnovuje a nikdy neodvoláva, takže po výmene nadradenej strany ďalej ukazuje na mŕtveho suseda. Trasa z RA zlyháva bezpečne; statická zlyháva ticho.

Testujte preposielaný paket, nie ten z brány

Vlastné pingy brány môžu uspieť na trase, ktorú žiadny klient nemôže použiť, a môžu uspieť aj preto, že brána je zdrojom. Testujte z pripojeného klienta a potom sa brány opýtajte, čo by urobila pre adresu toho klienta:

# 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

Potom počkajte jednu životnosť smerovača a pozrite sa znova. Stabilný stav, ktorý chcete, je predvolená trasa označená proto ra, ktorej hodnota expires sa stále obnovuje, plus all.forwarding=1. Ak expires len odpočítava, ohlásy sa niekde stále zahadzujú a obvyklým vinníkom je správca siete, ktorý prepíše accept_ra potom, ako sysctl pri štarte už prebehol.

Skôr než to uzavriete, overte štyri veci: predvolená trasa je proto ra a obnovuje sa, accept_ra=2 platí len pre uplink, preposielanie je po reštarte a po reštarte správcu stále 1 a ping IPv6 dokončí klient, nie brána. Ak klient so zdravou trasou stále zlyháva, ďalším podozrivým je spiatočná cesta alebo nadradený firewall, nie ohlás.

Súvisiace články