Ada dua cara untuk mengekalkan paket terowong itu sendiri di luar terowong: lindungi soket pengangkutan, atau keluarkan seluruh aplikasi daripada VPN. Kedua-duanya menyelesaikan masalah yang berbeza, dan memilih skop yang lebih luas kerana lebih mudah disambung ialah cara aplikasi kehilangan akses rangkaian setempat dan DNS berpecah tanpa menyedarinya. Mulakan dengan apa yang mesti kekal di luar terowong, kemudian pilih skop terkecil yang mencapainya.

Apa yang protect() buang daripada terowong

VpnService.protect() ialah panggilan bagi setiap soket. Anda berikan soket atau deskriptor yang membawa terowong, dan Android menandakan soket itu supaya trafiknya menggunakan rangkaian di bawahnya dan bukan antara muka VPN. Semua yang lain dihantar oleh aplikasi masih mengikut laluan VPN biasa.

Skop yang sempit itulah intinya. Soket yang dilindungi tidak mengubah cara klien HTTP anda menyelesaikan nama, antara muka yang digunakan oleh panggilan analitik anda atau apa yang berlaku pada sambungan kedua yang dibuka kemudian.

Tiga syarat yang menentukan skop

Syarat pertama ialah sama ada hanya pengangkutan terowong perlu keluar. Jika trafik lain aplikasi masih perlu melalui VPN, perlindungan soket ialah skop yang betul. Syarat kedua ialah sama ada anda mengawal penciptaan soket. Pustaka yang membuka soketnya sendiri jauh di dalam tidak meninggalkan tempat untuk anda memanggil protect() melainkan ia mendedahkan cangkuk atau menerima soket yang telah siap. Syarat ketiga ialah sama ada aplikasi mesti mencapai rangkaian setempat atau captive portal secara terus, yang merupakan keperluan berbeza daripada mengekalkan terowong hidup.

Mengecualikan aplikasi dengan addDisallowedApplication() ialah alat kasar. Ia mengeluarkan setiap sambungan yang dibuat aplikasi daripada VPN, termasuk yang anda mahu periksa, dan pada sesetengah peranti ia juga mengubah tingkah laku penemuan setempat.

Pilihan ketiga ialah mengikat pengangkutan kepada rangkaian terpilih dengan bindProcessToNetwork() atau pemegang rangkaian pada peringkat soket. Itu berguna apabila peranti mempunyai Wi-Fi dan selular serentak dan anda mahu terowong melalui pautan naik tertentu.

Panggilnya semasa pengangkutan sedang dicipta

Panggil protect() dalam blok yang sama yang mencipta pengangkutan, sebelum connect() atau send(). Jika panggilan mengembalikan false, tutup soket dan gagalkan persediaan; meneruskan meninggalkan anda dengan pengangkutan yang paketnya mungkin masuk semula ke antara muka anda sendiri.

Bentuknya cukup kecil untuk disimpan di satu tempat:

DatagramSocket transport = new DatagramSocket();
if (!protect(transport)) {
    transport.close();
    throw new IOException("transport not protected");
}
transport.connect(serverAddress);

Tiga perincian menggigit di sini. Pertama,boolean ialah satu-satunya isyarat yang anda dapat, jadi catat kegagalan dengan konteks yang cukup untuk membezakan persetujuan yang ditarik balik daripada panggilan yang ditolak. Kedua,protect() meliputi soket, bukan nombor deskriptor: jika anda menutup soket dan kemudian menggunakan semula integer yang sama untuk soket lain, soket baru itu tidak dilindungi. Ketiga, apabila pustaka asli membuka pengangkutan, lindungi deskriptor sebelum kod asli bersambung, jika tidak laluan itu mungkin sudah dipilih.Rujukan VpnService ialah tempat untuk mengesahkan lebihan beban mana yang benar-benar disediakan oleh tahap API sasaran anda.

Uji laluan yang disekat, bukan hanya laluan bahagia

Sahkan dengan terowong aktif, kerana hanya dalam keadaan itu kedua-dua laluan boleh berbeza. Hantar satu permintaan melalui pengangkutan yang dilindungi dan satu daripada laluan kod yang tidak pernah memanggil protect(), kemudian bandingkan apa yang dilihat oleh hujung jauh: sambungan yang dilindungi sepatutnya tiba dengan rangkaian di bawahnya sebagai sumber, manakala yang tidak dilindungi menunjukkan alamat terowong itu sendiri dan menggerakkan pembilang bait terowong. Pada peranti,ss atau netstat menunjukkan pembahagian yang sama sebelum apa-apa meninggalkan radio.

Uji penarikan balik secara berasingan, kerana perubahan persetujuan meruntuhkan antara muka tanpa menyentuh kod soket anda. Tarik balik persetujuan VPN atau hentikan perkhidmatan, bina semula pengangkutan, dan sahkan bahawa protect() masih mengembalikan true dan pengangkutan bersambung semula sebaik sahaja persetujuan diberikan semula.

Jika permintaan yang dilindungi masih mengikut terowong, panggilan perlindungan mungkin berlaku selepas soket sudah dihalakan. Pindahkannya lebih awal dan uji semula.

Simpan keputusan itu bertulis di sebelah persediaan pengangkutan: soket mana yang dilindungi, trafik aplikasi mana yang dikecualikan, dan apa yang aplikasi lakukan apabila perlindungan gagal. Baris itulah yang menghalang pemfaktoran semula kemudian daripada meluaskan pengecualian kepada seluruh aplikasi kerana satu ujian gagal. Ia juga memberi orang seterusnya cara menyemak niat tanpa kejuruteraan songsang manifes.

Artikel berkaitan