Androidi VpnService'i lubatud loend: miks lubatud lehed ikka veel hanguma jäävad
Sinu lubatud loend on tõenäoliselt korras. Lehed hanguvad DNS-vastuse, marsruuditabeli, resolveri soketi või MTU tõttu. Siin on kontrollimise järjekord.
Lisasid domeeni lubatud loendisse, päring jõuab sinu rakendusse, sobitaja tagastab lubatud, ja leht ei laadi ikkagi kunagi. Sel hetkel hakkab enamik inimesi sobitajat ümber kirjutama ja metamärkidega võrdlusi lisama. Minu kogemuse järgi on sobitaja tavaliselt õige ja rike asub ühe kihi võrra allpool: sinu sünteesitud DNS-vastuses, paigaldatud marsruudis või soketis, millega päringut edasi saatsid. Loend on lihtne osa; paketi tee on see, kus lubatud loendid katki lähevad.
Sobitaja on harva süüdlane
Esimene asi, mida eraldada, on blokeeritud ja katki. Blokeeritud nimi peaks kiiresti ja nähtavalt ebaõnnestuma, sest brauser saab vastuse, et sellist nime ei ole, ja peatub. Katki nimi hangub, proovib uuesti üle IPv6, langeb teisele transpordile ja jätab sind keerleva indikaatoriga. Kui näed keerlevat indikaatorit, vastab sinu lubatud loend tõenäoliselt millegagi, millega klient ei saa midagi teha.
Tühi A-kirje on klassikaline viga. NOERRORi tagastamine nulli vastusega näeb välja nagu korrektne vastus, seega stub-resolver võtab selle vastu, brauser proovib uuesti, proovib AAAAd, proovib teist resolverit ja annab palju hiljem alla. Vastusekood 3, NXDOMAIN, koos korratud küsimuse osaga ja kopeeritud tehingu ID-ga lõpetab vestluse kohe. Kasuta seda iga nime puhul, mille sa teadlikult tagasi lükkad.
IPv6 väärib sama otsust, mitte vaikeväärtust. Kui vastad A kohta NXDOMAINiga ja lased AAAA läbi, võib klient jõuda blokeeritud nimeni üle IPv6 ja filter lekib. Mõned teostused vastavad blokeeritud AAAA-päringutele loopback-aadressiga, et ühendus ebaõnnestuks kohe, selle asemel et varuvariandile langeda. Vali üks poliitika, rakenda seda mõlemale kirjetüübile ja logi mõlemat.
Marsruut, mis püüab kõik, omab kõike
Ainult DNS-il põhinev lahendus ei lisa kunagi addRoute("0.0.0.0", 0), seega sisenevad TUN-liidesese ainult päringud ja kõik muu kasutab edasi alusvõrku. See on turvaline vorm, ja see selgitab ka, miks mõned lubatud loendid näivad Wi-Fi korral töötavat ja mobiilivõrgus ebaõnnestuvat.
Hetkest, mil vaikemarsruut on olemas, on iga voog sinu. TCP-pakett, mis saabub liidesesse ja mida ei edastata ega vastata, istub järjekorras, kuni kliendil Aegub, ja logida pole ühtegi viga, sest miski ei ebaõnnestunud. Nägin, kuidas keegi veetis pool päeva katkise lubatud loendi kallal, mis oli tegelikult puuduv edastaja pordile 443. Logi iga paketi protokoll ja sihtkoht, mille otsustad ära visata.
Resolveri sokett peab tunnelist väljuma
Edastamine on koht, kus asub järgmine lõks. Operaatori resolverid elavad sageli privaataadressil, kuhu tunnel ei ulatu, seega edastatav päring läheb eikuhugi ja rakendus teatab lugemise ajalõpust. Saada kinnitatud päringud resolverile, mille kohta tead, et see on kättesaadav, ja anna see sokett kõigepealt VpnService.protect()-le. Kaitsmata sokett saadab päringu tagasi sinu enda tunnelisse, kus see jõuab uuesti rakendusse ja ringleb, kuni ajalõpp rakendub.
Rike näeb välja täpselt nagu võrgu katkestus, ja seetõttu püsib see vigade aruannetes nii kaua. Pea loendureid saadetud päringute ja saadud vastuste jaoks: kui esimene arv kasvab ja teine jääb nulli, vaatad sa soketti, mitte loendit.
Suurus ja kontrollsummad ebaõnnestuvad ilma teateta
Vaiksed äraviskamised tulevad ka suurusest. Suure vastusehulgaga DNS-vastus või heldete valikutega TCP-kätlus võib ületada tee MTUd, mida sa kunagi selgesõnaliselt ei seadnud; fragment kaob ülesvoolu ja klient kas proovib väiksemana uuesti või lõpetab proovimise. Liidese MTU seadmine 1280 peale on konservatiivne valik, mis peab vastu enamikule mobiiliteedele, ja selgesõnalisus on parem kui pärida vaikeväärtus, mida keegi ei mõõtnud.
Kui ehitad pakette ise, on kontrollsumma teine vaikne tapja. UDP kontrollsumma, mis arvutatakse pseudopäise peal, mis jätab välja UDP pikkuse või protokolli välja, annab paketi, mis sinu pool näeb korrektselt vormitud välja ja mille vastuvõtja jäljetult kõrvale heidab. Võrdle oma pseudopäist spetsifikatsiooniga väli välja haaval ja trüki silumise ajal ühe tuntud voo arvutatud kontrollsumma.
Mida VpnService sinu eest ei tee
Kaks piiri tasub teada enne, kui nende ümber projekteerid. Ükski tavaline rakendus ei saa paigaldada süsteemset puhverserverit ega PAC-faili väljaspool Wi-Fit, ja see osa ei ole muutunud. Rakendusepõhine tee on muutunud: enne API 29 ei saanud VpnService.Builder üldse puhverserverit kanda, ja alates API 29 annab setHttpProxy(ProxyInfo.buildPacProxy(uri)) platvormile PAC-skripti hindamiseks VPN-võrgu jaoks. Hinda reegleid oma koodis, kui sihid vanemaid API-sid või kui PAC-mudel ei suuda reeglit väljendada. Ka UDP ei ole tasuta: brauserid saadavad SOCKS-puhverserveri kaudu ainult TCPd ja enamik SOCKS5 kliente ei juuruta kunagi UDP ASSOCIATE'i, seega puhverserveril põhinev lahendus viskab UDP ära või lekib seda, samal ajal kui TCP näeb terve välja.
See teine piir on põhjus, miks UDP-l põhinev protokoll võib tavalises võrgus töötada ja ebaõnnestuda hetkel, mil sinu VPN ühendub. Kui tunnelilt oodatakse UDP kandmist, peab edastaja juurutama selle jaoks edastustee, mitte ainult TCP tee teist tüüpi soketiga.
Kontrolli selles järjekorras
Käi loend järjekorras läbi ja peatu esimesel etapil, mis ebaõnnestub, sest iga järgnev kontroll on müra, kuni eelmine peab.
- Loetle paigaldatud marsruudid ja kinnita, kas mitte-DNS-paketid üldse TUN-liidesesse sisenevad.
- Logi päringu nimi, otsus ja vastusekood ühe blokeeritud ja ühe kinnitatud nime jaoks.
- Kinnita, et resolveri sokett on kaitstud ja valitud resolver vastab tunneli seest.
- Kinnita liidese MTU ja ühe käsitsi ehitatud vastuse kontrollsumma.
- Korda sama lehte Wi-Fi ja mobiilivõrgu korral, sest operaatori resolverid ja tee MTU erinevad.
Kui kõik viis peavad ja leht hangub endiselt, on järgmine kahtlusalune edastaja ise: võrdle püütud päringut püütud vastusega ja otsi puuduvat baitide arvu või pooleldi suletud soketti. VpnService.Builderi viide katab marsruudi, DNSi ja MTU lepingud, ja protect() on eraldi VpnService kutse, mitte builderi valik; ühendatud liides tähendab ainult seda, et esimene leping täitus.