VPN'et er oppe, den private webgrænseflade svarer over IPv6 fra en bærbar computer, og Android-telefonen åbner stadig den samme side over IPv4 eller nægter at indlæse den helt. AAAA-posten findes. Tunnelen rapporterer en IPv6-adresse. Intet i klienten ser forkert ud. Fire separate beslutninger afgør resultatet: hvilken resolver der svarede, hvad VpnService erklærede over for Android, hvilken adressefamilie browseren var villig til at prøve, og om en pakke kan klare turen frem og tilbage. Tag dem i den rækkefølge i stedet for at tilføje en standardrute og håbe på, at symptomet flytter sig.

Trin 1: bevis hvilken resolver der svarede på AAAA-forespørgslen

Android har ikke kun én DNS-vej. Et VPN kan skubbe en DNS-server til sit netværk, systemet kan bruge Private DNS til værtsnavne, det anser for kvalificerede, og Chrome kan køre sin egen krypterede resolver fra chrome://settings/security. På en telefon, hvor tunnelen skubber 10.61.0.1, men Private DNS peger på en offentlig udbyder, bliver navnet i din private zone ikke opløst af den maskine, der ejer zonen. Browseren får et svar fra en resolver uden myndighed over det navn og behandler det som manglende, og fejlteksten nævner aldrig DNS.

Spørg tunnelens resolver direkte, før du ændrer noget andet. De to første kommandoer viser, hvilke DNS-servere Android har tilknyttet det aktive netværk, og om Private DNS er i automatisk eller streng tilstand; den tredje køres fra enhver klient inde i tunnelen, ikke fra telefonen.

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

Trin 2: læs, hvad VpnService faktisk erklærede

Android-siden er eksplicit og ikke udledt. En VpnService.Builder tilføjer adresser med addAddress, ruter med addRoute, DNS-servere med addDnsServer og kan begrænse hele tunnelen til én adressefamilie med allowFamily. En builder, der kaldte allowFamily(AF_INET) og senere tilføjede en IPv6-rute, har fortalt systemet to modstridende ting, og det er familierestriktionen, systemet beholder. En rute, der dækker fd00:61::/64, kombineret med en grænsefladeadresse i et andet præfiks, fejler af en lignende grund: adressen findes, men den er ikke on-link for den rute.

Læs erklæringen i stedet for at stole på kontakten i appen. dumpsys netd udskriver de adresser og ruter, der er knyttet til tun-grænsefladen, og LinkProperties pr. netværk i dumpsys connectivity viser DNS-listen ved siden af de familier, netværket hævder.

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"

Hvis tun-grænsefladen har en IPv6-adresse, men ingen rute matcher tjenestens præfiks, er IPv6-leveringen allerede brudt, før en browser er involveret. Det er en anden fejl end en browser, der nægter at prøve, og den kræver en anden løsning.

Trin 3: browseren afgør, om den overhovedet vil prøve IPv6

Chromium bruger ikke enhver AAAA-post, den modtager. Dens værtsresolver har IPv6-rækkeviddetjek og kandidatfiltrering, som kan droppe eller nedprioritere IPv6, når netværket vurderes ude af stand til at bære det, og resolverens kildekode viser den prøve sammen med betingelserne omkring den. Logikken afhænger af version og flag, og det er netop derfor, to telefoner på samme tunnel kan opføre sig forskelligt. Når kandidaterne findes, lader Happy Eyeballs familierne køre om kap pr. forbindelse, så en IPv6-vej, der svarer langsomt, stadig kan tabe til IPv4, der svarer hurtigt.

Observer beslutningen i stedet for at udlede den. En session optaget via chrome://net-export og afspillet i netlog-fremviseren viser hver opløsning og den valgte familie; chrome://net-internals/#dns viser de cachelagrede resultater. En opløsning, der kun returnerer A-poster for et navn, som har AAAA hos din egen resolver, peger direkte på dette trin.

Trin 4: verificér, at en pakke kan klare turen frem og tilbage

Adressevalg er ikke levering. Android holder rutingtabeller og politikregler pr. netværk, som vælger en tabel efter fwmark, så en rute, der er synlig i hovedtabellen, er ikke automatisk den rute, en socket bruger. At læse regler og bede kernen opløse en destination for en kildeadresse skiller de to ting.

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

Det er outputtet fra route get, der svarer på spørgsmålet. Hvis det nævner tun0, og pakkerne stadig dør, så gå til tunnelens MTU og gatewayens IPv6-videresendelse i stedet for tilbage til telefonen.

Hvorfor tilføjelse af ::/0 som regel gør det værre

Tilføjelse af ::/0 ændrer tunnelens krav fra ét præfiks til hver IPv6-destination. På telefonen kan det opfylde en rækkeviddeprøve, fordi en testadresse uden for dit præfiks nu ser rutbar ud. Det skaber ikke IPv6-opstrømskapacitet på gatewayen, og mange hjemmegateways har slet ingen fungerende IPv6-opstrømsforbindelse. Resultatet er et sort hul for offentlig IPv6: navne, der før faldt tilbage til IPv4, hænger nu, og den private side kan se bedre ud, blot fordi prøven måler noget andet.

Der er også en politikpris. Med ::/0 i tunnelen forlader al IPv6-trafik netværket gennem VPN'et, inklusive trafik, som netværksejeren aldrig har accepteret at bære. Behandl det som en udrulningsbeslutning med en navngivet ejer, ikke som et fejlsøgningstrin, du tager klokken 1 om natten.

Den arbejdsrækkefølge, der afslutter det

Bekræft, at AAAA-svaret kommer fra den resolver, der ejer zonen, læs VpnService- og netd-tilstand for tun-grænsefladen, optag et net-export-spor for at se, om Chromium droppede kandidaten, og test derefter turen frem og tilbage med ip -6 route get. Ret det lag, der faktisk fejlede, og lad splitpolitikken være. Hvis private navne har brug for andre svar end offentlige, er det netop, hvad split tunneling er til.

Notér telefonens build, browserens version og den resolver, du spurgte. De tre fakta gør "IPv6 is broken" til noget, den næste person kan genskabe.

Relaterede artikler