Android-VPN IPv6 werk, maar die blaaier kies steeds IPv4
Volg die vier fases waar 'n private IPv6-adres verdwyn: resolver, VpnService-verklaring, blaaier-kandidaattoets en roete-aflewering.
Die VPN is op, die private webkoppelvlak antwoord oor IPv6 vanaf 'n skootrekenaar, en die Android-foon maak steeds dieselfde bladsy oor IPv4 oop of weier om dit glad nie te laai nie. Die AAAA-rekord bestaan. Die tonnel rapporteer 'n IPv6-adres. Niks in die kliënt lyk verkeerd nie. Vier afsonderlike besluite bepaal die uitkoms: watter resolver geantwoord het, wat die VpnService aan Android verklaar het, watter adresfamilie die blaaier bereid was om te probeer, en of 'n pakkie die heen-en-weer reis kan maak. Werk hulle in daardie volgorde af eerder as om 'n verstekroete by te voeg en te hoop die simptoom skuif.
Stap 1: bewys watter resolver die AAAA-navraag beantwoord het
Android het nie 'n enkele DNS-pad nie. 'n VPN kan 'n DNS-bediener vir sy netwerk stoot, die stelsel kan Private DNS gebruik vir gasheername wat dit kwalifiseer, en Chrome kan sy eie geënkripteerde resolver van chrome://settings/security af laat loop. Op 'n foon waar die tonnel 10.61.0.1 stoot maar Private DNS na 'n openbare verskaffer wys, word die naam in jou private sone nie deur die masjien wat die sone besit, opgelos nie. Die blaaier kry 'n antwoord van 'n resolver sonder gesag vir daardie naam en behandel dit as ontbrekend, en die foutteks noem nooit DNS nie.
Vra die tonnel se resolver direk voordat jy iets anders verander. Die eerste twee opdragte wys watter DNS-bedieners Android aan die aktiewe netwerk gekoppel het en of Private DNS in outomatiese of streng modus is; die derde loop van enige kliënt binne die tonnel, nie van die foon nie.
adb shell dumpsys connectivity | grep -A3 "DnsAddresses"
adb shell settings get global private_dns_mode
nslookup -type=AAAA nas.lan 10.61.0.1
Stap 2: lees wat die VpnService werklik verklaar het
Die Android-kant is eksplisiet eerder as afgelei. 'n VpnService.Builder voeg adresse by met addAddress, roetes met addRoute, DNS-bedieners met addDnsServer, en kan die hele tonnel tot een adresfamilie beperk met allowFamily. 'n Bouer wat allowFamily(AF_INET) geroep het en later 'n IPv6-roete bygevoeg het, het die stelsel twee teenstrydige dinge vertel, en die familiebeperking is wat die stelsel behou. 'n Roete wat fd00:61::/64 dek, saam met 'n koppelvlakadres in 'n ander voorvoegsel, misluk om 'n soortgelyke rede: die adres bestaan, maar dit is nie on-link vir daardie roete nie.
Lees die verklaring eerder as om die skakelaar in die app te vertrou. dumpsys netd druk die adresse en roetes wat aan die tun-koppelvlak gekoppel is, en die per-netwerk LinkProperties in dumpsys connectivity wys die DNS-lys langs die families wat die netwerk beweer.
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"
As die tun-koppelvlak 'n IPv6-adres hou maar geen roete pas by die diensvoorvoegsel nie, is IPv6-aflewering reeds stukkend voordat 'n blaaier betrokke is. Dit is 'n ander fout as 'n blaaier wat weier om te probeer, en dit het 'n ander oplossing nodig.
Stap 3: die blaaier besluit of dit hoegenaamd IPv6 moet probeer
Chromium gebruik nie elke AAAA-rekord wat dit ontvang nie. Sy gasheerrevolver dra IPv6-bereikbaarheidstoetse en kandidaatfiltering wat IPv6 kan laat val of deprioritiseer wanneer die netwerk as onvermoënd beskou word om dit te dra, en die resolver-bron wys daardie ondersoek saam met die voorwaardes daaromheen. Die logika is weergawe- en vlagafhanklik, wat juis is hoekom twee telefone op dieselfde tonnel anders kan optree. Sodra kandidate bestaan, jaag Happy Eyeballs die families per verbinding, so 'n IPv6-pad wat stadig antwoord kan steeds verloor teen IPv4 wat vinnig antwoord.
Kyk na die besluit eerder as om dit af te lei. 'n Sessie wat deur chrome://net-export opgeneem is en in die netlog-kijker herspeel word, wys elke resolusion en die familie wat gekies is; chrome://net-internals/#dns wys die gekaste resultate. 'n Resolusie wat slegs A-rekords teruggee vir 'n naam wat AAAA by jou eie resolver het, wys reguit na hierdie fase.
Stap 4: verifieer dat 'n pakkie die heen-en-weer reis kan maak
Adreskeuse is nie aflewering nie. Android hou per-netwerk roetetabelle en beleidsreëls wat 'n tabel per fwmark kies, so 'n roete wat in die hoof-tabel sigbaar is, is nie outomaties die roete wat 'n sokket gebruik nie. Om reëls te lees en die kernel te vra om 'n bestemming vir 'n bronadres op te los, skei die twee.
adb shell ip -6 rule show
adb shell ip -6 route get fd00:61::20 from fd00:61::10
Die route get-uitset is die een wat die vraag beantwoord. As dit tun0 noem en pakkies sterf steeds, skuif na die tonnel-MTU en die gateway se IPv6-aanstuur eerder as terug na die foon.
Waarom die byvoeging van ::/0 dit gewoonlik erger maak
Om ::/0 by te voeg, verander die tonnel se aanspraak van een voorvoegsel na elke IPv6-bestemming. Op die foon kan dit 'n bereikbaarheidstoets bevredig, want 'n toetsadres buite jou voorvoegsel lyk nou roeteerbaar. Dit skep nie IPv6-opstroomkapasiteit op die gateway nie, en baie huisgateways het glad geen werkende IPv6-opstroom nie. Die resultaat is 'n swart gat vir openbare IPv6: name wat vroeër na IPv4 teruggeval het, hang nou, en die private bladsy lyk miskien beter net omdat die toets iets anders meet.
Daar is ook 'n beleidskoste. Met ::/0 in die tonnel verlaat alle IPv6-verkeer die netwerk deur die VPN, insluitend verkeer wat die netwerkeienaar nooit toegestem het om te dra nie. Behandel dit as 'n ontplooiingsbesluit met 'n genoemde eienaar, nie as 'n ontfoutstap wat jy om 1 vm. neem nie.
Die werkorde wat dit beëindig
Bevestig dat die AAAA-antwoord van die resolver kom wat die sone hou, lees VpnService- en netd-toestand vir die tun-koppelvlak, neem 'n net-export-spoor op om te sien of Chromium die kandidaat laat val het, en toets dan die heen-en-weer reis met ip -6 route get. Maak die laag reg wat werklik gefaal het en laat die splitbeleid alleen. As private name ander antwoorde as openbare name nodig het, is dit waarvoor split tunneling is.
Noteer die foonbou, die blaaierweergawe en die resolver wat jy bevraag het. Daardie drie feite verander "IPv6 is broken" in iets wat die volgende persoon kan reproduseer.