Hozzáadtál egy domaint az engedélyezési listához, a lekérdezés eléri az alkalmazásodat, az egyeztető engedélyezettet ad vissza, és az oldal mégsem töltődik be soha. Ezen a ponton a legtöbb ember elkezdi átírni az egyeztetőt és helyettesítő karakteres összehasonlításokat ad hozzá. Tapasztalatom szerint az egyeztető általában helyes, és a hiba egy réteggel lejjebb van: az általad szintetizált DNS-válaszban, a telepített útvonalban vagy a socketben, amellyel a lekérdezést továbbítottad. A lista a könnyű rész; a csomag útja az, ahol az engedélyezési listák eltörnek.

Az egyeztető ritkán a hibás

Először a tiltottat kell elválasztani a törttől. A tiltott névnek gyorsan és láthatóan kell meghiúsulnia, mert a böngésző választ kap arról, hogy a név nem létezik, és megáll. A tört név akad, újrapróbál IPv6 felett, átvált egy másik átvitelre, és egy pörgő jelzővel hagy magadra. Ha pörgő jelzőt látsz, az engedélyezési listád valószínűleg olyasmit válaszol, amivel a kliens nem tud mit kezdeni.

Az üres A rekord a klasszikus hiba. A NOERROR visszaadása nulla válasszal érvényes válasznak tűnik, ezért a stub feloldó elfogadja, a böngésző újrapróbálja, kipróbálja az AAAA-t, kipróbál egy másik feloldót, és sokkal később feladja. A 3-as válaszkód, azaz az NXDOMAIN, a kérdés szakasz megismétlésével és a tranzakcióazonosító másolásával azonnal lezárja a beszélgetést. Használd minden névnél, amelyet szándékosan elutasítasz.

Az IPv6 ugyanezt a döntést érdemli, nem egy alapértéket. Ha az A-ra NXDOMAIN-t válaszolsz és az AAAA-t átengeded, a kliens IPv6-on elérheti a tiltott nevet, és a szűrő szivárog. Egyes implementációk a tiltott AAAA lekérdezésekre loopback-címmel válaszolnak, hogy a kapcsolat azonnal meghiúsuljon ahelyett, hogy tartalékra váltana. Válassz egy szabályzatot, alkalmazd mindkét rekordtípusra, és naplózd mindkettőt.

Az útvonal, amely mindent elkap, mindent birtokol

A csak DNS-re épülő kialakítás soha nem ad hozzá addRoute("0.0.0.0", 0)-t, így csak a lekérdezések lépnek be a TUN interfészre, és minden más továbbra is az alatta lévő hálózatot használja. Ez a biztonságos forma, és ez magyarázza azt is, hogy egyes engedélyezési listák miért tűnnek működőnek Wi-Fi-n és miért hibásodnak meg a mobilhálózaton.

Abban a pillanatban, amikor létezik alapértelmezett útvonal, minden folyam a tiéd. Az interfészre érkező TCP-csomag, amelyet sem továbbítanak, sem nem válaszolnak meg, a sorban ül, amíg a kliens ideje le nem jár, és nincs naplózható hiba, mert semmi nem hibázott. Láttam valakit egy délutánt eltölteni egy törött engedélyezési listán, amely valójában egy hiányzó továbbító volt a 443-as porthoz. Naplózd minden csomag protokollját és célját, amelyet eldobni döntesz.

A feloldó socketjének el kell hagynia az alagutat

A továbbítás az, ahol a következő csapda van. A szolgáltató feloldói gyakran olyan privát címen élnek, amelyet az alagút nem ér el, ezért a továbbított lekérdezés sehová nem megy, és az alkalmazás olvasási időtúllépést jelent. A jóváhagyott lekérdezéseket olyan feloldóhoz küldd, amelyről tudod, hogy elérhető, és ezt a socketet először add át a VpnService.protect()-nek. A védelem nélküli socket visszaküldi a lekérdezést a saját alagutadba, ahol újra eléri az alkalmazást, és addig köröz, amíg az időtúllépés be nem indul.

A hiba pontosan úgy néz ki, mint egy hálózatkimaradás, és ezért él túl olyan sokáig a hibajelentésekben. Vezess számlálókat a küldött lekérdezésekhez és a fogadott válaszokhoz: ha az első szám nő és a második nullán marad, akkor a socketet nézed, nem a listát.

A méret és az ellenőrzőösszegek üzenet nélkül hibáznak

A csendes eldobások a méretből is jönnek. Egy nagy válaszkészletű DNS-válasz vagy egy bőkezű opciókkal induló TCP-kézfogás meghaladhat egy olyan útvonal-MTU-t, amelyet soha nem állítottál be kifejezetten; a töredék felfelé eltűnik, és a kliens vagy kisebbel próbálkozik újra, vagy abbahagyja a próbálkozást. Az interfész MTU-ját 1280-ra állítani konzervatív választás, amely túléli a legtöbb mobil útvonalat, és a kifejezett beállítás jobb, mint olyan alapértéket örökölni, amelyet senki nem mért.

Ha magad építed a csomagokat, az ellenőrzőösszeg a másik csendes gyilkos. Az UDP ellenőrzőösszeg olyan pszeudo-fejlécen számolva, amely kihagyja az UDP hosszát vagy a protokoll mezőt, olyan csomagot ad, amely a te oldaladon jól formáltnak tűnik, és a fogadó nyom nélkül eldobja. Hasonlítsd össze a pszeudo-fejlécet a specifikációval mezőről mezőre, és hibakeresés közben írd ki a kiszámított ellenőrzőösszeget egy ismert folyamhoz.

Amit a VpnService nem tesz meg helyetted

Két korlátot érdemes ismerni, mielőtt köréjük terveznél. Egyetlen közönséges alkalmazás sem telepíthet rendszerszintű proxyt vagy PAC-fájlt Wi-Fi-n kívül, és ez a rész nem változott. Az alkalmazásonkénti útvonal viszont igen: az API 29 előtt a VpnService.Builder egyáltalán nem tudott proxyt hordozni, és az API 29-től a setHttpProxy(ProxyInfo.buildPacProxy(uri)) PAC-szkriptet ad a platformnak értékelésre a VPN-hálózathoz. Értékeld a szabályokat a saját kódodban, ha régebbi API-kat célozol, vagy ha a PAC-modell nem tudja kifejezni a szabályt. Az UDP sem ingyen van: a böngészők csak TCP-t küldenek SOCKS-proxyn keresztül, és a legtöbb SOCKS5 kliens soha nem valósítja meg az UDP ASSOCIATE-et, így a proxyalapú kialakítás eldobja vagy szivárogtatja az UDP-t, miközben a TCP egészségesnek látszik.

Ez a második korlát az oka annak, hogy egy UDP-alapú protokoll működhet egy közönséges hálózaton, és meghiúsulhat abban a pillanatban, amikor a VPN-ed csatlakozik. Ha az alagútnak UDP-t kell szállítania, a továbbítónak meg kell valósítania a továbbítási útvonalat ehhez, nem csak a TCP-útvonalat más socket-típussal.

Ebben a sorrendben ellenőrizd

Dolgozd fel a listát sorrendben, és állj meg az első hibás szakasznál, mert minden későbbi ellenőrzés zaj, amíg az előző nem áll.

  1. Listázd a telepített útvonalakat, és erősítsd meg, hogy a nem DNS-csomagok egyáltalán belépnek-e a TUN interfészre.
  2. Naplózd a lekérdezés nevét, a döntést és a válaszkódot egy tiltott és egy jóváhagyott névhez.
  3. Erősítsd meg, hogy a feloldó socketje védett, és a választott feloldó az alagúton belülről válaszol.
  4. Erősítsd meg az interfész MTU-ját és egy kézzel épített válasz ellenőrzőösszegét.
  5. Ismételd meg ugyanazt az oldalt Wi-Fi-n és mobilhálózaton, mert a szolgáltató feloldói és az útvonal-MTU eltérnek.

Ha mind az öt áll, és az oldal még mindig akad, a következő gyanúsított maga a továbbító: hasonlíts össze egy rögzített kérést egy rögzített válasszal, és keress hiányzó bájtszámot vagy félig lezárt socketet. A VpnService.Builder-referencia lefedi az útvonalra, a DNS-re és az MTU-ra vonatkozó szerződéseket, és a protect() külön VpnService-hívás, nem builder-opció; a csatlakoztatott interfész csak azt jelenti, hogy az első szerződés teljesült.

Kapcsolódó cikkek