VPN beží, privátne webové rozhranie odpovedá cez IPv6 z notebooku a telefón s Androidom stále otvára tú istú stránku cez IPv4 alebo ju odmieta úplne načítať. Záznam AAAA existuje. Tunel hlási adresu IPv6. V klientovi nič nevyzerá zle. Výsledok určujú štyri samostatné rozhodnutia: ktorý resolver odpovedal, čo VpnService deklaroval Androidu, ktorú rodinu adries bol prehliadač ochotný vyskúšať a či paket zvládne cestu tam aj späť. Prejdite ich v tomto poradí, namiesto toho, aby ste pridali predvolenú trasu a dúfali, že sa symptóm posunie.

Krok 1: dokážte, ktorý resolver odpovedal na dopyt AAAA

Android nemá jedinú cestu DNS. VPN môže pretlačiť DNS server pre svoju sieť, systém môže použiť Private DNS pre názvy hostiteľov, ktoré uzná za vhodné, a Chrome môže spustiť vlastný šifrovaný resolver z chrome://settings/security. Na telefóne, kde tunel pretlačí 10.61.0.1, ale Private DNS ukazuje na verejného poskytovateľa, názov vo vašej privátnej zóne nerozlišuje stroj, ktorý zónu vlastní. Prehliadač dostane odpoveď od resolvera bez právomoci na tento názov a považuje ho za chýbajúci, a text chyby DNS vôbec nespomína.

Opýtajte sa resolvera tunela priamo, skôr než čokoľvek iné zmeníte. Prvé dva príkazy ukazujú, ktoré DNS servery Android pripojil k aktívnej sieti a či je Private DNS v automatickom alebo striktnom režime; tretí sa spúšťa z ľubovoľného klienta vnútri tunela, nie z telefónu.

adb shell dumpsys connectivity | grep -A3 "DnsAddresses"
adb shell settings get global private_dns_mode
nslookup -type=AAAA nas.lan 10.61.0.1

Krok 2: prečítajte si, čo VpnService skutočne deklaroval

Strana Androidu je explicitná, nie odvodená. VpnService.Builder pridáva adresy pomocou addAddress, trasy pomocou addRoute, DNS servery pomocou addDnsServer a môže obmedziť celý tunel na jednu rodinu adries pomocou allowFamily. Tvorca, ktorý zavolal allowFamily(AF_INET) a neskôr pridal trasu IPv6, povedal systému dve protichodné veci a systém si ponechá obmedzenie rodiny. Trasa pokrývajúca fd00:61::/64 v kombinácii s adresou rozhrania v inom prefixe zlyháva z podobného dôvodu: adresa existuje, ale nie je on-link pre túto trasu.

Čítajte deklaráciu, namiesto toho, aby ste verili prepínaču v aplikácii. dumpsys netd vypíše adresy a trasy pripojené k rozhraniu tun a LinkProperties pre každú sieť v dumpsys connectivity zobrazuje zoznam DNS vedľa rodín, ktoré sieť tvrdí.

adb shell ip -6 addr show tun0
adb shell ip -6 route show table all | grep tun0
adb shell dumpsys connectivity | grep -E "LinkAddresses|Routes"

Ak má rozhranie tun adresu IPv6, ale žiadna trasa nezodpovedá prefixu služby, doručenie IPv6 je už pokazené predtým, než sa do toho zapojí prehliadač. Je to iná chyba než prehliadač, ktorý odmieta vyskúšať, a vyžaduje inú opravu.

Krok 3: prehliadač rozhoduje, či vôbec skúsiť IPv6

Chromium nepoužíva každý záznam AAAA, ktorý dostane. Jeho resolver hostiteľov nesie kontroly dostupnosti IPv6 a filtrovanie kandidátov, ktoré môžu IPv6 zahodiť alebo znížiť jeho prioritu, keď je sieť vyhodnotená ako neschopná ho prenášať, a zdrojový kód resolvera ukazuje túto sondu spolu s podmienkami okolo nej. Logika závisí od verzie a prepínačov, a práve preto sa dva telefóny na tom istom tuneli môžu správať odlišne. Keď kandidáti existujú, Happy Eyeballs necháva rodiny pretekať pre každé spojenie, takže cesta IPv6, ktorá odpovedá pomaly, môže stále prehrať s IPv4, ktoré odpovedá rýchlo.

Sledujte rozhodnutie, namiesto toho, aby ste ho odvodzovali. Relácia zaznamenaná cez chrome://net-export a prehraná v prehliadači netlog ukazuje každé rozlíšenie a zvolenú rodinu; chrome://net-internals/#dns ukazuje výsledky z vyrovnávacej pamäte. Rozlíšenie, ktoré vracia len záznamy A pre názov, ktorý má AAAA na vašom vlastnom resolveri, ukazuje priamo na túto fázu.

Krok 4: overte, že paket zvládne cestu tam aj späť

Výber adresy nie je doručenie. Android drží smerovacie tabuľky a pravidlá politiky pre každú sieť, ktoré vyberajú tabuľku podľa fwmark, takže trasa viditeľná v hlavnej tabuľke nie je automaticky tou trasou, ktorú používa socket. Čítanie pravidiel a požiadavka, aby jadro vyriešilo cieľ pre zdrojovú adresu, oddeľuje to dvoje.

adb shell ip -6 rule show
adb shell ip -6 route get fd00:61::20 from fd00:61::10

Práve výstup route get odpovedá na otázku. Ak uvádza tun0 a pakety stále zlyhávajú, prejdite k MTU tunela a k smerovaniu IPv6 na bráne, nie späť k telefónu.

Prečo pridanie ::/0 zvyčajne všetko zhorší

Pridanie ::/0 mení nárok tunela z jedného prefixu na každý cieľ IPv6. V telefóne to môže splniť sondu dostupnosti, pretože testovacia adresa mimo vášho prefixu teraz vyzerá smerovateľne. Nevytvára to však kapacitu IPv6 smerom nahor na bráne a mnohé domáce brány nemajú vôbec funkčné vzostupné pripojenie IPv6. Výsledkom je čierna diera pre verejný IPv6: názvy, ktoré predtým padali späť na IPv4, teraz visia, a privátna stránka môže vyzerať lepšie len preto, že sonda meria niečo iné.

Má to aj cenu pre politiku. S ::/0 v tuneli odchádza všetka prevádzka IPv6 cez VPN, vrátane prevádzky, ktorú vlastník siete nikdy nesúhlasil prenášať. Berte to ako rozhodnutie o nasadení s menovaným vlastníkom, nie ako krok ladenia, ktorý robíte o 1 hodine ráno.

Poradie práce, ktoré to ukončí

Potvrďte, že odpoveď AAAA prichádza z resolvera, ktorý drží zónu, prečítajte stav VpnService a netd pre rozhranie tun, zachyťte stopu net-export, aby ste videli, či Chromium kandidáta zahodilo, a potom otestujte cestu tam aj späť pomocou ip -6 route get. Opravte vrstvu, ktorá skutočne zlyhala, a politiku rozdelenia nechajte na pokoji. Ak privátne názvy potrebujú iné odpovede než verejné, presne na to slúži split tunneling.

Poznamenajte build telefónu, verziu prehliadača a resolver, na ktorý ste sa pýtali. Tieto tri skutočnosti menia "IPv6 is broken" na niečo, čo ďalší človek dokáže reprodukovať.

Súvisiace články