Mendeteksi VPN aktif di dalam aplikasi Mac yang di-sandbox
Tidak ada API publik untuk pertanyaan ini, dan trik nama antarmuka hanyalah sebuah heuristik. Enam pemeriksaan untuk memutuskan apa yang sebenarnya harus diandalkan aplikasi Anda.
Anda perlu satu layar berperilaku berbeda saat terowongan aktif, dan tidak ada panggilan yang memberi tahu Anda. Itulah batasan pengiriman: di macOS tidak ada kerangka publik yang melaporkan apakah VPN sembarang terhubung, dan di iOS statusnya milik aplikasi yang memasang konfigurasi. Pemeriksaan di bawah bergerak dari batas itu ke sesuatu yang bisa Anda kirim, dan salah satunya bisa mengakhiri pencarian lebih awal.
Pemeriksaan 1: apakah pertanyaannya bisa dijawab sama sekali?
Sandbox menyelesaikan pertanyaan itu sebelum API mana pun. Proses pihak ketiga tidak dapat menghitung ekstensi vendor lain, dan juga tidak dapat membaca konfigurasi ekstensi itu, jadi tidak ada objek yang didukung untuk ditanyai.
Setiap jalan pintas menabrak dinding yang sama. Daftar antarmuka, scutil --nc list dan pembacaan konfigurasi sistem secara langsung entah membutuhkan hak yang ditahan sandbox atau bergantung pada perilaku yang tidak pernah dijanjikan Apple. Jika rencana membutuhkan salah satunya, masalahnya adalah rencananya. Fitur yang dibangun di atas detail tak terdokumentasi adalah tiket dukungan dengan tanggal pengiriman.
Pemeriksaan 2: apakah aplikasi Anda mengelola terowongan sendiri?
Jika ya, Anda punya jawaban yang didukung untuk konfigurasi Anda sendiri. Muat preferensi, tangani kesalahannya, lalu baca status dan berlangganan perubahan alih-alih melakukan polling:
vpnManager.loadFromPreferences { error in
// handle a load failure before reading status
}
NotificationCenter.default.addObserver(
forName: .NEVPNStatusDidChange,
object: nil,
queue: nil
) { note in
let status = (note.object as? NEVPNConnection)?.status
}Tepatlah tentang apa yang dikembalikan ini: status terowongan yang Anda pasang. Pengguna yang menjalankan klien lain akan tampil sebagai terputus, dan itu bukan bug di kode Anda. Putuskan mana dari dua pertanyaan itu yang sebenarnya diajukan fitur Anda sebelum membangun di atas jawabannya.
Pemeriksaan 3: apa yang sebenarnya diberitahukan heuristik kepada Anda?
Pendekatan yang banyak disalin meminta kamus proxy sistem untuk entri berlingkupnya dan membaca kuncinya, yang kebetulan berupa nama antarmuka:
let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as NSDictionary?
let scoped = settings?["__SCOPED__"] as? [String: Any]
let names = scoped?.keys ?? []Kunci yang diawali dengan tap, tun, ppp, ipsec atau utun menyiratkan ada antarmuka berlingkup terowongan. Mencocokkan seluruh nama langsung gagal, karena iOS 12 hadir dengan utun1 dan utun2 dan sebagian profil muncul sebagai ipsec4, ppp0, atau utun0. Bandingkan awalan saja.
Meski begitu, nama tidak mengidentifikasi pemilik. Fitur sistem dan ekstensi vendor lain juga membuat antarmuka utun, dan satu bisa ada tanpa membawa sedikit pun lalu lintas Anda. Bacalah sebagai petunjuk bahwa ada sesuatu berbentuk terowongan di sekitar, tidak lebih kuat. Positif palsu di sini murah jika Anda hanya membatasi satu fitur, dan mahal jika Anda membatasi layar masuk.
Pemeriksaan 4: bisakah Anda menguji tujuannya saja?
Jika aplikasi hanya perlu tahu apakah layanan internal dapat dijangkau, ujilah layanan itu. Probe singkat dengan batas waktu menjawab pertanyaan yang sebenarnya menjadi dasar fitur, dan tetap berfungsi saat pengguna berganti klien atau terowongan berubah bentuk.
Keterjangkauan adalah pengamatan tentang jalur Anda. Nama antarmuka adalah kesimpulan tentang sesuatu yang berdekatan dengan jalur Anda, itulah sebabnya heuristik menghasilkan perdebatan di laporan bug dan probe menghasilkan bukti. Jika probe gagal sementara pengguna bersikeras VPN menyala, kini Anda punya jalur konkret untuk di-debug: resolusi nama, rute, atau izin layanan.
Pemeriksaan 5: bisakah platform menegakkan yang Anda butuhkan?
Ketika persyaratannya adalah jaminan bahwa tidak ada yang lolos dari terowongan, profil adalah tempatnya, bukan detektor. Mengaktifkan includeAllNetworks dalam konfigurasi terowongan penuh di iOS 14 atau lebih baru mengubah perilaku platform alih-alih meminta aplikasi Anda menyimpulkannya. Flag ini didokumentasikan di referensi NEVPNProtocol.
Itu jenis jawaban yang berbeda: penegakan alih-alih pengamatan. Ini juga hanya berlaku untuk profil yang Anda kendalikan, jadi tidak membantu aplikasi konsumen yang mengawasi terowongan orang lain.
Pemeriksaan 6: buat kegagalan aman dan teramati
Matikan hanya kemampuan yang membutuhkan terowongan dan biarkan sisa aplikasi tetap bisa dipakai. Detektor yang menyembunyikan seluruh antarmuka setiap kali ragu menciptakan gangguan bagi siapa pun yang terowongannya memakai nama yang tidak pernah Anda antisipasi. Kembalilah ke perilaku konservatif: fitur lokal tetap berfungsi dan hanya panggilan jarak jauh yang benar-benar membutuhkan terowongan yang dinonaktifkan. Pilihan itu adalah keputusan produk, dan layak dituliskan di samping heuristik.
Catat apa yang Anda amati: nama antarmuka, versi platform, dan hasil satu probe. Itu mengubah laporan berikutnya dari perdebatan menjadi pemeriksaan. Lalu utamakan deklarasi yang didukung bila Anda memilikinya, karena konfigurasi terkelola dapat membawa niat itu secara eksplisit dan menghapus sebagian besar alasan untuk memeriksa nama sama sekali.
Jika pemeriksaan 1 sampai 5 membuat Anda tanpa jawaban yang didukung, kirimkan probe dan beri label hasilnya dengan jujur. Sinyal upaya terbaik yang terdokumentasi adalah keputusan produk yang lebih baik daripada API privat yang rusak pada rilis berikutnya.