Android VpnService lista dozvoljenih: zašto se dozvoljene stranice i dalje zamrzavaju
Vaša lista dozvoljenih je vjerovatno u redu. Stranice se zamrzavaju zbog DNS odgovora, tabele ruta, socketa rezolvera ili MTU. Ovo je redoslijed provjere.
Dodali ste domenu na listu dozvoljenih, upit stigne do vaše aplikacije, poklapač vrati dozvoljeno, a stranica se ipak nikad ne učita. U tom trenutku većina ljudi počne prepisivati poklapač i dodavati poređenja s džokerima. Po mom iskustvu poklapač je obično ispravan, a kvar leži jedan sloj kasnije: u DNS odgovoru koji ste sintetizirali, u ruti koju ste instalirali ili u socketu koji ste koristili za prosljeđivanje upita. Lista je lakši dio; put paketa je mjesto gdje se liste dozvoljenih lome.
Poklapač je rijetko krivac
Prvo što treba razdvojiti je blokirano od pokvarenog. Blokirano ime treba brzo i vidljivo da padne, jer pregledač dobije odgovor da ime ne postoji i zaustavi se. Pokvareno ime se zamrzava, ponavlja pokušaje preko IPv6, prelazi na drugi transport i ostavlja vas s pokretnim indikatorom. Ako vidite pokretni indikator, vaša lista dozvoljenih vjerovatno odgovara nečim na šta klijent ne može da reaguje.
Prazan A zapis je klasična greška. Vraćanje NOERROR s nula odgovora izgleda kao valjan odgovor, pa ga stub rezolver prihvati, pregledač pokuša ponovo, pokuša AAAA, pokuša drugi rezolver i odustane mnogo kasnije. Kod odgovora 3, NXDOMAIN, s ponovljenim odjeljkom pitanja i kopiranim ID-om transakcije završava razgovor odmah. Koristite ga za svako ime koje namjerno odbijate.
IPv6 zaslužuje istu odluku, a ne zadanu vrijednost. Ako na A odgovorite NXDOMAIN a AAAA propustite, klijent može doći do blokiranog imena preko IPv6 i filter propušta. Neke implementacije na blokirane AAAA upite odgovaraju loopback adresom kako bi veza odmah pala umjesto da pređe na rezervu. Izaberite jednu politiku, primijenite je na oba tipa zapisa i bilježite oba.
Ruta koja hvata sve posjeduje sve
Dizajn samo s DNS-om nikad ne dodaje addRoute("0.0.0.0", 0), pa u TUN interfejs ulaze samo upiti, a sve ostalo nastavlja koristiti donju mrežu. To je siguran oblik i objašnjava zašto neke liste dozvoljenih rade na Wi-Fi mreži a padaju na mobilnoj.
U trenutku kada postoji zadana ruta, svaki tok je vaš. TCP paket koji stigne na interfejs i nije ni proslijeđen ni odgovoren stoji u redu dok klijentu ne istekne vrijeme, a greške nema za bilježenje jer ništa nije pogriješilo. Gledao sam kako neko provede poslijepodne na pokvarenoj listi dozvoljenih koja je zapravo bila prosljeđivač koji nedostaje za port 443. Bilježite protokol i odredište svakog paketa koji odlučite odbaciti.
Socket rezolvera mora izaći iz tunela
Prosljeđivanje je mjesto sljedeće zamke. Rezolveri operatera često žive na privatnoj adresi do koje tunel ne doseže, pa upit koji proslijedite ode nikuda i aplikacija prijavi istek vremena čitanja. Šaljite odobrene upite rezolveru za koji znate da je dostupan i prvo predajte taj socket funkciji VpnService.protect(). Nezaštićen socket vraća upit natrag u vaš vlastiti tunel, gdje ponovo stigne do aplikacije i kruži dok ne opali tajmer.
Kvar izgleda identično kao prekid mreže, zato tako dugo preživljava u prijavama grešaka. Držite brojače poslanih upita i primljenih odgovora: ako prvi broj raste a drugi ostaje na nuli, gledate u socket, ne u listu.
Veličina i kontrolne sume padaju bez poruke
Tiho odbacivanje dolazi i od veličine. DNS odgovor s velikim skupom odgovora ili TCP rukovanje s izdašnim opcijama može premašiti MTU puta koji nikad niste izričito postavili; fragment nestaje uzvodno i klijent ili ponovi pokušaj s manjim ili prestane pokušavati. Postavljanje MTU interfejsa na 1280 je konzervativan izbor koji preživljava većinu mobilnih puteva, a izričitost je bolja od nasljeđivanja zadane vrijednosti koju niko nije mjerio.
Ako sami gradite pakete, kontrolna suma je drugi tihi ubica. UDP kontrolna suma izračunata preko pseudozaglavlja koje izostavlja dužinu UDP-a ili polje protokola daje paket koji na vašoj strani izgleda ispravno, a primalac ga odbacuje bez traga. Uporedite svoje pseudo zaglavlje sa specifikacijom polje po polje i ispišite izračunatu kontrolnu sumu za jedan poznati tok dok otklanjate grešku.
Šta VpnService neće uraditi za vas
Dvije granice vrijedi znati prije nego što dizajnirate oko njih. Nijedna obična aplikacija ne može instalirati sistemski proxy ili PAC datoteku izvan Wi-Fi veze, a taj dio se nije promijenio. Put po aplikaciji jeste: prije API 29 VpnService.Builder uopšte nije mogao nositi proxy, a od API 29 setHttpProxy(ProxyInfo.buildPacProxy(uri)) daje platformi PAC skriptu za procjenu za VPN mrežu. Procjenjujte pravila u vlastitom kodu kada ciljate starije API-je ili kada PAC model ne može izraziti pravilo. UDP takođe nije besplatan: pregledači šalju samo TCP kroz SOCKS proxy, a većina SOCKS5 klijenata nikad ne implementira UDP ASSOCIATE, pa dizajn zasnovan na proxyju odbacuje ili propušta UDP dok TCP izgleda zdravo.
Ta druga granica razlog je zašto protokol zasnovan na UDP-u može raditi na običnoj mreži i pasti onog trenutka kad se vaš VPN poveže. Ako se od tunela očekuje da nosi UDP, prosljeđivač mora implementirati put prosljeđivanja za njega, ne samo TCP put s drugim tipom socketa.
Provjeravajte ovim redom
Prođite listu redom i zaustavite se na prvoj fazi koja padne, jer je svaka kasnija provjera šum dok prethodna ne drži.
- Navedite instalirane rute i potvrdite da li paketi koji nisu DNS uopšte ulaze u TUN interfejs.
- Bilježite ime upita, odluku i kod odgovora za jedno blokirano i jedno dozvoljeno ime.
- Potvrdite da je socket rezolvera zaštićen i da izabrani rezolver odgovara iz unutrašnjosti tunela.
- Potvrdite MTU interfejsa i kontrolnu sumu jednog odgovora koji ste sami sastavili.
- Ponovite istu stranicu na Wi-Fi i mobilnoj mreži, jer se rezolveri operatera i MTU puta razlikuju.
Ako svih pet drži a stranica se još zamrzava, sljedeći osumnjičeni je sam prosljeđivač: uporedite snimljeni zahtjev sa snimljenim odgovorom i tražite broj bajtova koji nedostaje ili napola zatvoren socket. Referenca za VpnService.Builder pokriva ugovore o ruti, DNS-u i MTU-u, a protect() je odvojen poziv VpnService, a ne opcija builder-a; povezan interfejs znači samo da je prvi ugovor ispunjen.