VPN įjungtas, privati web sąsaja atsako per IPv6 iš nešiojamojo kompiuterio, o Android telefonas tą patį puslapį vis dar atidaro per IPv4 arba visiškai atsisako jį įkelti. AAAA įrašas egzistuoja. Tunelis praneša IPv6 adresą. Kliente niekas neatrodo neteisingai. Rezultatą lemia keturi atskiri sprendimai: kuris resolveris atsakė, ką VpnService deklaravo Android, kurios adresų šeimos naršyklė buvo pasirengusi išbandyti ir ar paketas gali įveikti kelią ten ir atgal. Spręskite juos tokia tvarka, o ne pridėkite numatytąjį maršrutą ir tikėkitės, kad simptomas pasislinks.

1 žingsnis: įrodykite, kuris resolveris atsakė į AAAA užklausą

Android neturi vieno DNS kelio. VPN gali stumti savo tinklo DNS serverį, sistema gali naudoti Private DNS tiems pagrindinio kompiuterio vardams, kuriuos laiko tinkamais, o Chrome gali paleisti savo paties užšifruotą resolverį iš chrome://settings/security. Telefone, kuriame tunelis stumia 10.61.0.1, bet Private DNS rodo į viešą tiekėją, vardas jūsų privačioje zonoje nėra sprendžiamas mašinos, kuri valdo zoną. Naršyklė gauna atsakymą iš resolverio, neturinčio įgaliojimų tam vardui, ir laiko jį trūkstamu, o klaidos tekste DNS niekada neminimas.

Paklauskite tunelio resolverio tiesiogiai, prieš ką nors kita keisdami. Pirmos dvi komandos rodo, kuriuos DNS serverius Android priskyrė aktyviam tinklui ir ar Private DNS yra automatiniame, ar griežtame režime; trečioji vykdoma iš bet kurio kliento tunelio viduje, o ne iš telefono.

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

2 žingsnis: perskaitykite, ką VpnService iš tikrųjų deklaravo

Android pusė yra aiški, o ne numanoma. VpnService.Builder prideda adresus su addAddress, maršrutus su addRoute, DNS serverius su addDnsServer ir gali apriboti visą tunelį viena adresų šeima su allowFamily. Kūrėjas, kuris iškvietė allowFamily(AF_INET) ir vėliau pridėjo IPv6 maršrutą, sistemai pasakė du prieštaringus dalykus, ir sistema išlaiko šeimos apribojimą. Maršrutas, apimantis fd00:61::/64, kartu su sąsajos adresu kitame prefikse, nepavyksta dėl panašios priežasties: adresas egzistuoja, bet jis nėra on-link tam maršrutui.

Skaitykite deklaraciją, o ne pasitikėkite programėlės jungikliu. dumpsys netd išspausdina adresus ir maršrutus, prijungtus prie tun sąsajos, o LinkProperties pagal tinklą dumpsys connectivity viduje rodo DNS sąrašą šalia šeimų, kurias tinklas teigia.

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"

Jei tun sąsaja turi IPv6 adresą, bet joks maršrutas neatitinka paslaugos prefikso, IPv6 pristatymas jau sugedęs dar prieš įsikišant naršyklei. Tai kita klaida nei naršyklė, kuri atsisako bandyti, ir jai reikia kito pataisymo.

3 žingsnis: naršyklė sprendžia, ar apskritai bandyti IPv6

Chromium naudoja ne kiekvieną gautą AAAA įrašą. Jo pagrindinio kompiuterio resolveris turi IPv6 pasiekiamumo patikras ir kandidatų filtravimą, kurie gali atmesti arba sumažinti IPv6 prioritetą, kai tinklas laikomas negalinčiu jo perduoti, o resolverio šaltinis rodo tą patikrą kartu su ją supančiomis sąlygomis. Logika priklauso nuo versijos ir vėliavėlių, ir būtent todėl du telefonai tame pačiame tunelyje gali elgtis skirtingai. Kai kandidatai yra, Happy Eyeballs leidžia šeimoms lenktyniauti kiekvienam ryšiui, todėl lėtai atsakantis IPv6 kelias vis tiek gali pralaimėti greitai atsakančiam IPv4.

Stebėkite sprendimą, o ne spėkite jį. Sesija, įrašyta per chrome://net-export ir atkurta netlog peržiūroje, rodo kiekvieną sprendimą ir pasirinktą šeimą; chrome://net-internals/#dns rodo podėlyje laikomus rezultatus. Sprendimas, kuris vardui su AAAA jūsų pačių resolveryje grąžina tik A įrašus, tiesiogiai nurodo šį etapą.

4 žingsnis: patikrinkite, ar paketas gali įveikti kelią ten ir atgal

Adreso pasirinkimas nėra pristatymas. Android laiko pagal tinklą maršrutavimo lenteles ir politikos taisykles, kurios lentelę renkasi pagal fwmark, todėl pagrindinėje lentelėje matomas maršrutas nebūtinai yra tas, kurį naudoja lizdas. Taisyklių skaitymas ir branduolio prašymas išspręsti paskirties vietą šaltinio adresui atskiria šiuos du dalykus.

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

Būtent route get išvestis atsako į klausimą. Jei ji nurodo tun0, o paketai vis dar žūva, pereikite prie tunelio MTU ir šliuzo IPv6 persiuntimo, o ne atgal prie telefono.

Kodėl ::/0 pridėjimas paprastai viską pablogina

::/0 pridėjimas pakeičia tunelio pretenziją iš vieno prefikso į kiekvieną IPv6 paskirties vietą. Telefone tai gali patenkinti pasiekiamumo patikrą, nes bandomasis adresas už jūsų prefikso dabar atrodo maršrutuojamas. Tačiau tai nesukuria IPv6 aukštupio pajėgumo šliuze, o daugelis namų šliuzų apskritai neturi veikiančios IPv6 aukštupio jungties. Rezultatas yra juoda skylė viešajam IPv6: vardai, kurie anksčiau krisdavo į IPv4, dabar stringa, o privatus puslapis gali atrodyti geriau tik todėl, kad patikra matuoja ką kita.

Yra ir politikos kaina. Kai tunelyje yra ::/0, visas IPv6 srautas išeina per VPN, įskaitant srautą, kurio tinklo savininkas niekada nebuvo sutikęs nešti. Traktuokite tai kaip diegimo sprendimą su įvardytu savininku, o ne kaip derinimo žingsnį, kurį darote 1 valandą nakties.

Darbų tvarka, kuri tai užbaigia

Patvirtinkite, kad AAAA atsakymas ateina iš resolverio, kuris valdo zoną, perskaitykite VpnService ir netd būseną tun sąsajai, užfiksuokite net-export pėdsaką, kad pamatytumėte, ar Chromium atmetė kandidatą, tada patikrinkite kelią ten ir atgal su ip -6 route get. Pataisykite sluoksnį, kuris tikrai nepavyko, ir palikite skaidymo politiką ramybėje. Jei privatiems vardams reikia kitokių atsakymų nei viešiems, tam ir skirtas split tunneling.

Užsirašykite telefono build, naršyklės versiją ir resolverį, kurio klausėte. Šie trys faktai paverčia "IPv6 is broken" kažkuo, ką kitas žmogus gali atkartoti.

Susiję straipsniai