Android VpnService leidžiamųjų sąrašas: kodėl leidžiami puslapiai vis tiek užstringa
Jūsų leidžiamųjų sąrašas greičiausiai tvarkingas. Puslapiai užstringa dėl DNS atsakymo, maršrutų lentelės, resolverio lizdo arba MTU. Štai tikrinimo tvarka.
Įtraukėte domeną į leidžiamųjų sąrašą, užklausa pasiekia jūsų programą, atitikmenų tikrintuvas grąžina leidžiama, o puslapis vis tiek niekada neužsikrauna. Tuo metu dauguma pradeda perrašyti atitikmenų tikrintuvą ir pridėti pakaitos simbolių palyginimus. Mano patirtis rodo, kad tikrintuvas paprastai būna teisingas, o gedimas slypi vienu sluoksniu žemiau: jūsų sugeneruotame DNS atsakyme, jūsų įdiegtame maršrute arba lizde, kurį naudojote užklausai persiųsti. Sąrašas yra lengvoji dalis; paketo kelias yra vieta, kur leidžiamųjų sąrašai lūžta.
Tikrintuvas retai būna kaltas
Pirmiausia reikia atskirti blokuota nuo sulaužyto. Blokuotas vardas turėtų nepavykti greitai ir matomai, nes naršyklė gauna atsakymą, kad vardo nėra, ir sustoja. Sulaužytas vardas užstringa, bando dar kartą per IPv6, persijungia į kitą transportą ir palieka jus su besisukančiu indikatoriumi. Jei matote besisukantį indikatorių, jūsų leidžiamųjų sąrašas tikriausiai atsako kažkuo, su kuo klientas nieko negali padaryti.
Tuščias A įrašas yra klasikinė klaida. Grąžinti NOERROR su nuliu atsakymų atrodo kaip galiojantis atsakymas, todėl stub resolveris jį priima, naršyklė bando dar kartą, bando AAAA, bando kitą resolverį ir pasiduoda daug vėliau. Atsakymo kodas 3, tai yra NXDOMAIN, su pakartota klausimo sekcija ir nukopijuotu transakcijos ID nedelsiant baigia pokalbį. Naudokite jį kiekvienam vardui, kurio sąmoningai atsisakote.
IPv6 taip pat nusipelno to paties sprendimo, o ne numatytosios reikšmės. Jei atsakote NXDOMAIN į A ir praleidžiate AAAA, klientas gali pasiekti blokuotą vardą per IPv6 ir filtras nuteka. Kai kurios implementacijos į blokuotas AAAA užklausas atsako loopback adresu, kad ryšys iš karto nepavyktų, o ne pereitų prie atsarginio varianto. Pasirinkite vieną politiką, taikykite ją abiem įrašų tipams ir registruokite abu.
Maršrutas, kuris pagauna viską, valdo viską
Tik DNS pagrįsta konstrukcija niekada neprideda addRoute("0.0.0.0", 0), todėl į TUN sąsają patenka tik užklausos, o visa kita toliau naudoja pagrindinį tinklą. Tai saugi forma, ir tai taip pat paaiškina, kodėl kai kurie leidžiamųjų sąrašai atrodo veikiantys Wi-Fi tinkle ir nepavyksta mobiliojo ryšio tinkle.
Tą akimirką, kai egzistuoja numatytasis maršrutas, kiekvienas srautas yra jūsų. TCP paketas, kuris atvyksta į sąsają ir nėra nei persiunčiamas, nei atsakomas, sėdi eilėje, kol klientui baigiasi laikas, ir nėra klaidos, kurią būtų galima registruoti, nes niekas nesuveikė neteisingai. Mačiau, kaip žmogus praleido popietę prie sulaužyto leidžiamųjų sąrašo, kuris iš tikrųjų buvo trūkstamas persiuntėjas 443 prievadui. Registruokite kiekvieno paketo, kurį nusprendžiate atmesti, protokolą ir paskirties vietą.
Resolverio lizdas turi išeiti iš tunelio
Persiuntimas yra vieta, kur slypi kita spąstai. Operatoriaus resolveriai dažnai gyvena privačiame adrese, kurio tunelis nepasiekia, todėl persiunčiama užklausa niekur nenueina ir programa praneša apie skaitymo laiko limitą. Siųskite patvirtintas užklausas resolveriui, apie kurį žinote, kad jis pasiekiamas, ir pirmiausia perduokite tą lizdą VpnService.protect(). Neapsaugotas lizdas užklausą grąžina į jūsų pačių tunelį, kur ji vėl pasiekia programą ir sukasi, kol suveikia laiko limitas.
Gedimas atrodo identiškai kaip tinklo sutrikimas, ir todėl jis taip ilgai išlieka klaidų ataskaitose. Turėkite skaitiklius išsiųstoms užklausoms ir gautiems atsakymams: jei pirmas skaičius kyla, o antras lieka nulyje, jūs žiūrite į lizdą, o ne į sąrašą.
Dydis ir kontrolinės sumos nepavyksta be pranešimo
Tylus atmetimas taip pat kyla iš dydžio. DNS atsakymas su dideliu atsakymų rinkiniu arba TCP rankos paspaudimas su gausiomis parinktimis gali viršyti kelio MTU, kurio niekada nebuvote aiškiai nustatę; fragmentas dingsta aukštyn, o klientas arba bando dar kartą mažesniu, arba nustoja bandyti. Sąsajos MTU nustatymas į 1280 yra konservatyvus pasirinkimas, kuris atlaiko daugumą mobiliųjų kelių, ir būti aiškiam yra geriau nei paveldėti numatytąją reikšmę, kurios niekas neišmatavo.
Jei paketus kuriate patys, kontrolinė suma yra kitas tylus žudikas. UDP kontrolinė suma, apskaičiuota per pseudo antraštę, kurioje praleistas UDP ilgis arba protokolo laukas, sukuria paketą, kuris jūsų pusėje atrodo taisyklingas, o gavėjas jį išmeta be pėdsakų. Palyginkite savo pseudo antraštę su specifikacija laukas po lauko ir derindami atspausdinkite apskaičiuotą kontrolinę sumą vienam žinomam srautui.
Ko VpnService nepadarys už jus
Du apribojimus verta žinoti prieš projektuojant aplink juos. Jokia įprasta programa negali įdiegti sisteminio proxy arba PAC failo už Wi-Fi ribų, ir ši dalis nepasikeitė. Kelias pagal programą pasikeitė: iki API 29 VpnService.Builder apskritai negalėjo nešti proxy, o nuo API 29 setHttpProxy(ProxyInfo.buildPacProxy(uri)) perduoda platformai PAC scenarijų, kad ji įvertintų VPN tinklui. Vertinkite taisykles savo kode, kai taikote senesnius API arba kai PAC modelis negali išreikšti taisyklės. UDP taip pat nėra nemokamas: naršyklės per SOCKS proxy siunčia tik TCP, o dauguma SOCKS5 klientų niekada neįgyvendina UDP ASSOCIATE, todėl proxy pagrįsta konstrukcija atmeta arba nutekina UDP, kol TCP atrodo sveikas.
Šis antras apribojimas yra priežastis, kodėl UDP pagrįstas protokolas gali veikti įprastame tinkle ir nepavykti tą akimirką, kai prisijungia jūsų VPN. Jei tikimasi, kad tunelis neš UDP, persiuntėjas turi įgyvendinti persiuntimo kelią tam, o ne tik TCP kelią su kitu lizdo tipu.
Tikrinkite šia tvarka
Pereikite sąrašą iš eilės ir sustokite prie pirmo nepavykusio etapo, nes kiekviena vėlesnė patikra yra triukšmas, kol ankstesnė laikosi.
- Išvardykite įdiegtus maršrutus ir patvirtinkite, ar ne DNS paketai apskritai patenka į TUN sąsają.
- Registruokite užklausos vardą, sprendimą ir atsakymo kodą vienam blokuotam ir vienam patvirtintam vardui.
- Patvirtinkite, kad resolverio lizdas apsaugotas ir pasirinktas resolveris atsako iš tunelio vidaus.
- Patvirtinkite sąsajos MTU ir vieno ranka sukurto atsakymo kontrolinę sumą.
- Pakartokite tą patį puslapį Wi-Fi ir mobiliajame tinkle, nes operatoriaus resolveriai ir kelio MTU skiriasi.
Jei visi penki laikosi, o puslapis vis tiek užstringa, kitas įtariamasis yra pats persiuntėjas: palyginkite užfiksuotą užklausą su užfiksuotu atsakymu ir ieškokite trūkstamo baitų skaičiaus arba pusiau uždaryto lizdo. VpnService.Builder nuoroda apima maršruto, DNS ir MTU sutartis, o protect() yra atskiras VpnService iškvietimas, o ne builder parinktis; prijungta sąsaja reiškia tik tai, kad pirmoji sutartis įvykdyta.