VPN běží, privátní webové rozhraní odpovídá přes IPv6 z notebooku a telefon s Androidem pořád otevírá stejnou stránku přes IPv4, nebo ji odmítá načíst úplně. Záznam AAAA existuje. Tunel hlásí adresu IPv6. V klientovi nic nevypadá špatně. Výsledek určují čtyři samostatná rozhodnutí: který resolver odpověděl, co VpnService deklaroval Androidu, kterou rodinu adres byl prohlížeč ochoten zkusit a zda paket zvládne cestu tam i zpět. Projděte je v tomto pořadí, místo abyste přidali výchozí trasu a doufali, že se symptom posune.

Krok 1: dokažte, který resolver odpověděl na dotaz AAAA

Android nemá jedinou cestu DNS. VPN může protlačit DNS server pro svou síť, systém může použít Private DNS pro názvy hostitelů, které uzná za vhodné, a Chrome může spustit vlastní šifrovaný resolver z chrome://settings/security. Na telefonu, kde tunel protlačí 10.61.0.1, ale Private DNS ukazuje na veřejného poskytovatele, název ve vaší privátní zóně nepřekládá stroj, který zónu vlastní. Prohlížeč dostane odpověď od resolveru bez pravomoci pro tento název a považuje ho za chybějící, a text chyby DNS vůbec nezmiňuje.

Zeptejte se resolveru tunelu přímo, než cokoli jiného změníte. První dva příkazy ukazují, které DNS servery Android připojil k aktivní síti a zda je Private DNS v automatickém, nebo striktním režimu; třetí se spouští z libovolného klienta uvnitř tunelu, ne z telefonu.

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: přečtěte si, co VpnService skutečně deklaroval

Strana Androidu je explicitní, ne odvozená. VpnService.Builder přidává adresy pomocí addAddress, trasy pomocí addRoute, DNS servery pomocí addDnsServer a může omezit celý tunel na jednu rodinu adres pomocí allowFamily. Tvůrce, který zavolal allowFamily(AF_INET) a později přidal trasu IPv6, řekl systému dvě protichůdné věci a systém si ponechá omezení rodiny. Trasa pokrývající fd00:61::/64 v kombinaci s adresou rozhraní v jiném prefixu selhává z podobného důvodu: adresa existuje, ale není on-link pro tuto trasu.

Čtěte deklaraci, místo abyste věřili přepínači v aplikaci. dumpsys netd vypíše adresy a trasy připojené k rozhraní tun a LinkProperties pro každou síť v dumpsys connectivity ukazuje seznam DNS vedle rodin, které síť 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"

Pokud má rozhraní tun adresu IPv6, ale žádná trasa neodpovídá prefixu služby, doručení IPv6 je už rozbité, než se do toho zapojí prohlížeč. To je jiná chyba než prohlížeč, který odmítá zkusit, a potřebuje jinou opravu.

Krok 3: prohlížeč rozhoduje, zda vůbec zkusit IPv6

Chromium nepoužívá každý záznam AAAA, který obdrží. Jeho resolver hostitelů nese kontroly dostupnosti IPv6 a filtrování kandidátů, které mohou IPv6 zahodit nebo snížit jeho prioritu, když je síť vyhodnocena jako neschopná ho přenášet, a zdrojový kód resolveru ukazuje tuto sondu spolu s podmínkami kolem ní. Logika závisí na verzi a přepínačích, což je přesně důvod, proč se dva telefony na stejném tunelu mohou chovat různě. Jakmile kandidáti existují, Happy Eyeballs nechá rodiny závodit pro každé spojení, takže cesta IPv6, která odpovídá pomalu, může stále prohrát s IPv4, které odpovídá rychle.

Sledujte rozhodnutí, místo abyste ho odvozovali. Relace zaznamenaná přes chrome://net-export a přehraná v prohlížeči netlog ukazuje každé překlad a zvolenou rodinu; chrome://net-internals/#dns ukazuje výsledky z mezipaměti. Překlad, který vrací jen záznamy A pro název, jenž má AAAA na vašem vlastním resolveru, ukazuje přímo na tuto fázi.

Krok 4: ověřte, že paket zvládne cestu tam i zpět

Výběr adresy není doručení. Android drží směrovací tabulky a pravidla zásad pro každou síť, která vybírají tabulku podle fwmark, takže trasa viditelná v hlavní tabulce není automaticky trasou, kterou socket používá. Čtení pravidel a požadavek, aby jádro přeložilo cíl pro zdrojovou adresu, odděluje obojí.

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

Právě výstup route get odpovídá na otázku. Pokud uvádí tun0 a pakety stále umírají, přejděte k MTU tunelu a směrování IPv6 na bráně, ne zpět k telefonu.

Proč přidání ::/0 obvykle všechno zhorší

Přidání ::/0 mění nárok tunelu z jednoho prefixu na každý cíl IPv6. V telefonu to může splnit sondu dostupnosti, protože testovací adresa mimo váš prefix teď vypadá směrovatelně. Nevytváří to ale kapacitu IPv6 směrem nahoru na bráně a mnoho domácích bran nemá vůbec funkční vzestupné připojení IPv6. Výsledkem je černá díra pro veřejný IPv6: názvy, které dřív padaly zpět na IPv4, teď visí, a privátní stránka může vypadat lépe jen proto, že sonda měří něco jiného.

Má to i cenu v podobě zásad. S ::/0 v tunelu veškerý provoz IPv6 odchází přes VPN, včetně provozu, který vlastník sítě nikdy nesouhlasil přenášet. Berte to jako rozhodnutí o nasazení s pojmenovaným vlastníkem, ne jako krok ladění, který děláte v 1 hodinu ráno.

Pořadí práce, které to ukončí

Potvrďte, že odpověď AAAA přichází z resolveru, který drží zónu, přečtěte stav VpnService a netd pro rozhraní tun, zachyťte stopu net-export, abyste viděli, zda Chromium kandidáta zahodilo, a pak otestujte cestu tam i zpět pomocí ip -6 route get. Opravte vrstvu, která skutečně selhala, a politiku rozdělení nechte být. Pokud privátní názvy potřebují jiné odpovědi než veřejné, přesně k tomu slouží split tunneling.

Poznamenejte build telefonu, verzi prohlížeče a resolver, na který jste se dotazovali. Tyto tři skutečnosti mění "IPv6 is broken" v něco, co další člověk dokáže reprodukovat.

Související články