Android menyediakan API bagi developer untuk membuat solusi virtual private network (VPN). Setelah membaca panduan ini, Anda akan mengetahui cara mengembangkan dan menguji klien VPN Anda sendiri untuk perangkat yang didukung Android.
Ringkasan
VPN memungkinkan perangkat yang secara fisik tidak berada di jaringan untuk mengakses jaringan dengan aman.
Android menyertakan klien VPN (PPTP dan L2TP/IPSec) bawaan, yang terkadang disebut VPN lama. Android 4.0 (API Level 14) memperkenalkan API agar developer aplikasi dapat menyediakan solusi VPN mereka sendiri. Anda mengemas solusi VPN ke dalam aplikasi yang diinstal pengguna ke perangkat. Developer biasanya membuat aplikasi VPN karena salah satu alasan berikut:
- Untuk menawarkan protokol VPN yang tidak didukung oleh klien bawaan.
- Untuk membantu orang terhubung ke layanan VPN tanpa konfigurasi yang rumit.
Bagian selanjutnya dari panduan ini menjelaskan cara mengembangkan aplikasi VPN (termasuk VPN selalu aktif dan per aplikasi) dan tidak membahas klien VPN bawaan.
Pengalaman pengguna
Android menyediakan antarmuka pengguna (UI) untuk membantu seseorang mengonfigurasi, memulai, dan menghentikan solusi VPN Anda. UI sistem juga membuat orang yang menggunakan perangkat mengetahui koneksi VPN yang aktif. Android menampilkan komponen UI berikut untuk koneksi VPN:
- Sebelum aplikasi VPN dapat aktif untuk pertama kalinya, sistem akan menampilkan dialog permintaan koneksi. Dialog akan meminta orang yang menggunakan perangkat untuk mengonfirmasi bahwa mereka memercayai VPN dan menerima permintaan.
- Layar setelan VPN (Setelan > Jaringan & Internet > VPN) menampilkan aplikasi VPN tempat seseorang menerima permintaan koneksi. Ada tombol untuk mengonfigurasi opsi sistem atau melupakan VPN.
- Baki Setelan Cepat menampilkan panel informasi saat koneksi aktif. Mengetuk label akan menampilkan dialog dengan informasi selengkapnya dan link ke Setelan.
- Status bar berisi ikon (kunci) VPN, menunjukkan bahwa koneksi sedang aktif.
Aplikasi Anda juga perlu menyediakan UI agar orang yang menggunakan perangkat dapat mengonfigurasi opsi layanan Anda. Misalnya, solusi Anda mungkin perlu mengambil setelan autentikasi akun. Aplikasi akan menampilkan UI berikut:
- Kontrol untuk memulai dan menghentikan koneksi secara manual. VPN Selalu Aktif dapat terhubung saat diperlukan, tetapi memungkinkan pengguna mengonfigurasi koneksi saat pertama kali menggunakan VPN Anda.
- Notifikasi yang tidak dapat ditutup saat layanan aktif. Notifikasi dapat menampilkan status koneksi atau memberikan informasi selengkapnya—seperti statistik jaringan. Mengetuk notifikasi akan membawa aplikasi ke latar depan. Hapus notifikasi setelah layanan menjadi tidak aktif.
Layanan VPN
Aplikasi Anda menghubungkan jaringan sistem untuk pengguna (atau profil
kerja) ke gateway VPN. Setiap pengguna (atau profil kerja) dapat menjalankan
aplikasi VPN yang berbeda. Anda membuat layanan VPN yang digunakan sistem untuk memulai dan
menghentikan VPN, serta melacak status koneksi. Layanan VPN Anda diwarisi dari
VpnService.
Layanan ini juga berfungsi sebagai container untuk koneksi gateway VPN dan
antarmuka perangkat lokalnya. Instance layanan Anda memanggil metode VpnService.Builder untuk membuat antarmuka lokal baru.
VpnService menghubungkan jaringan Android
ke gateway VPNAplikasi Anda mentransfer data berikut untuk menghubungkan perangkat ke gateway VPN:
- Membaca paket IP keluar dari deskriptor file antarmuka lokal, mengenkripsinya, dan mengirimkannya ke gateway VPN.
- Menulis paket masuk (diterima dan didekripsi dari gateway VPN) ke deskriptor file antarmuka lokal.
Hanya ada satu layanan aktif per pengguna atau profil. Memulai layanan baru akan otomatis menghentikan layanan yang ada.
Menambahkan layanan
Untuk menambahkan layanan VPN ke aplikasi Anda, buat layanan Android yang diwarisi dari
VpnService. Deklarasikan layanan VPN dalam file manifes aplikasi Anda dengan penambahan berikut:
- Lindungi layanan dengan izin
BIND_VPN_SERVICEsehingga hanya sistem yang dapat mengikat ke layanan Anda. - Beritahukan layanan dengan filter intent
"android.net.VpnService"agar sistem dapat menemukan layanan Anda.
Contoh ini menunjukkan cara mendeklarasikan layanan di file manifes aplikasi Anda:
<service android:name=".MyVpnService"
android:permission="android.permission.BIND_VPN_SERVICE">
<intent-filter>
<action android:name="android.net.VpnService"/>
</intent-filter>
</service>
Setelah aplikasi Anda mendeklarasikan layanan, sistem dapat otomatis memulai dan menghentikan layanan VPN aplikasi Anda saat diperlukan. Misalnya, sistem mengontrol layanan Anda saat menjalankan VPN selalu aktif.
Menyiapkan layanan
Untuk menyiapkan aplikasi agar menjadi layanan VPN pengguna saat ini, panggil
VpnService.prepare(). Jika orang yang menggunakan perangkat belum
memberikan izin untuk aplikasi Anda, metode ini akan menampilkan intent aktivitas.
Gunakan intent ini untuk memulai aktivitas sistem yang meminta izin. Sistem
akan menampilkan dialog yang mirip dengan dialog izin lainnya, seperti
akses kamera atau kontak. Jika aplikasi Anda sudah disiapkan, metode ini akan menampilkan
null.
Hanya satu aplikasi yang dapat menjadi layanan VPN yang disiapkan saat ini. Selalu panggil
VpnService.prepare() karena seseorang mungkin telah menetapkan aplikasi
lain sebagai layanan VPN sejak aplikasi Anda terakhir kali memanggil metode tersebut. Untuk mempelajari lebih lanjut, lihat
bagian Siklus proses layanan.
Menghubungkan layanan
Setelah layanan berjalan, Anda dapat membuat antarmuka lokal baru yang terhubung ke gateway VPN. Untuk meminta izin dan menghubungkan layanan Anda ke gateway VPN, Anda harus menyelesaikan langkah-langkah dalam urutan berikut:
- Panggil
VpnService.prepare()untuk meminta izin (jika diperlukan). - Panggil
VpnService.protect()untuk menjaga soket tunnel aplikasi Anda di luar VPN sistem dan menghindari koneksi sirkular. - Panggil
DatagramSocket.connect()untuk menghubungkan soket tunnel aplikasi Anda ke gateway VPN. - Panggil metode
VpnService.Builderuntuk mengonfigurasi antarmuka TUN lokal baru di perangkat untuk traffic VPN. - Panggil
VpnService.Builder.establish()agar sistem membuat antarmuka TUN lokal dan mulai merutekan traffic melalui antarmuka.
Gateway VPN biasanya menyarankan setelan untuk antarmuka TUN lokal selama
handshake. Aplikasi Anda memanggil metode VpnService.Builder untuk mengonfigurasi
layanan seperti yang ditunjukkan dalam contoh berikut:
// Configure a new interface from our VpnService instance. This must be done // from inside a VpnService. val builder = Builder() // Create a local TUN interface using predetermined addresses. In your app, // you typically use values returned from the VPN gateway during handshaking. val localTunnel = builder .addAddress("192.168.2.2", 24) .addRoute("0.0.0.0", 0) .addDnsServer("192.168.1.1") .establish()
Contoh di bagian VPN per aplikasi menunjukkan konfigurasi IPv6 yang menyertakan
lebih banyak opsi. Anda harus menambahkan nilai VpnService.Builder berikut
sebelum dapat membuat antarmuka baru:
addAddress()- Tambahkan setidaknya satu alamat IPv4 atau IPv6 beserta subnet mask yang ditetapkan sistem sebagai alamat antarmuka TUN lokal. Aplikasi Anda biasanya menerima alamat IP dan subnet mask dari gateway VPN selama handshake.
addRoute()- Tambahkan setidaknya satu rute jika Anda ingin sistem mengirim traffic melalui antarmuka VPN. Merutekan filter berdasarkan alamat tujuan. Untuk menerima semua traffic, tetapkan rute terbuka seperti
0.0.0.0/0atau::/0.
Metode establish() menampilkan instance ParcelFileDescriptor yang digunakan aplikasi Anda untuk membaca dan menulis paket ke dan dari buffer antarmuka. Metode establish()
menampilkan null jika aplikasi Anda tidak disiapkan atau seseorang mencabut
izin.
Siklus proses layanan
Aplikasi Anda harus melacak status VPN yang dipilih sistem dan koneksi aktif apa pun. Perbarui antarmuka pengguna (UI) aplikasi Anda agar orang yang menggunakan perangkat mengetahui setiap perubahan.
Memulai layanan
Layanan VPN Anda dapat dimulai dengan cara berikut:
- Aplikasi Anda memulai layanan—biasanya karena pengguna mengetuk tombol sambungkan.
- Sistem memulai layanan karena VPN selalu aktif diaktifkan.
Aplikasi Anda memulai layanan VPN dengan meneruskan intent ke
startService(). Untuk mempelajari lebih lanjut, baca Memulai
layanan.
Sistem memulai layanan Anda di latar belakang dengan memanggil
onStartCommand(). Namun, Android menerapkan batasan pada aplikasi latar belakang di versi 8.0 (level API 26) atau yang lebih tinggi. Jika Anda mendukung Level API ini, Anda harus mentransisikan layanan ke latar depan dengan memanggil Service.startForeground(). Untuk mempelajari lebih lanjut, baca Menjalankan
layanan di latar depan.
Menghentikan layanan
Pengguna perangkat dapat menghentikan layanan Anda dengan menggunakan UI aplikasi Anda. Hentikan layanan, bukan hanya menutup koneksi. Sistem juga menghentikan koneksi aktif saat orang yang menggunakan perangkat melakukan hal berikut di layar VPN aplikasi Setelan:
- memutus atau melupakan aplikasi VPN
- menonaktifkan VPN selalu aktif untuk koneksi yang aktif
Sistem akan memanggil metode onRevoke() layanan Anda, tetapi panggilan ini
mungkin tidak terjadi di thread utama. Saat sistem memanggil metode ini, antarmuka jaringan alternatif sudah merutekan traffic. Anda dapat membuang resource berikut dengan aman:
- Tutup soket tunnel yang dilindungi ke gateway VPN dengan memanggil
DatagramSocket.close(). - Tutup deskriptor file paket (Anda tidak perlu mengosongkannya) dengan memanggil
ParcelFileDescriptor.close().
VPN selalu aktif
Android dapat memulai layanan VPN saat perangkat melakukan booting dan terus menjalankannya saat perangkat diaktifkan. Fitur ini disebut VPN selalu aktif dan tersedia di Android 7.0 (API Level 24) atau yang lebih tinggi. Meskipun Android mempertahankan siklus proses layanan, layanan VPN Anda bertanggung jawab atas koneksi gateway VPN. VPN selalu aktif juga dapat memblokir koneksi yang tidak menggunakan VPN.
Pengalaman pengguna
Di Android 8.0 atau yang lebih tinggi, sistem menampilkan dialog berikut untuk membuat pengguna perangkat mengetahui VPN selalu aktif:
- Saat koneksi VPN selalu aktif terputus atau tidak dapat terhubung, pengguna akan melihat notifikasi yang tidak dapat ditutup. Mengetuk notifikasi akan menampilkan dialog yang menjelaskan lebih lanjut. Notifikasi akan hilang saat VPN terhubung kembali atau seseorang menonaktifkan opsi VPN selalu aktif.
- VPN selalu aktif memungkinkan orang yang menggunakan perangkat untuk memblokir koneksi jaringan apa pun yang tidak menggunakan VPN. Saat mengaktifkan opsi ini, aplikasi Setelan akan memperingatkan pengguna bahwa mereka tidak memiliki koneksi internet sebelum VPN terhubung. Aplikasi Setelan akan meminta pengguna yang menggunakan perangkat untuk melanjutkan atau membatalkan.
Karena sistem (dan bukan orang) memulai dan menghentikan koneksi selalu aktif, Anda perlu menyesuaikan perilaku dan antarmuka pengguna aplikasi:
- Nonaktifkan UI apa pun yang memutuskan koneksi karena sistem dan aplikasi Setelan mengontrol koneksi.
- Simpan konfigurasi apa pun di antara setiap startup aplikasi dan konfigurasikan koneksi dengan setelan terbaru. Karena sistem memulai aplikasi Anda sesuai permintaan, pengguna perangkat mungkin tidak selalu ingin mengonfigurasi koneksi.
Anda juga dapat menggunakan konfigurasi terkelola untuk mengonfigurasi koneksi. Konfigurasi terkelola membantu admin IT mengonfigurasi VPN dari jarak jauh.
Mendeteksi selalu aktif
Android tidak menyertakan API untuk mengonfirmasi apakah sistem memulai layanan VPN Anda. Namun, saat aplikasi Anda menandai instance layanan apa pun yang dimulai, Anda dapat berasumsi bahwa sistem memulai layanan yang tidak ditandai untuk VPN selalu aktif. Berikut contohnya:
- Buat instance
Intentuntuk memulai layanan VPN. - Tandai layanan VPN dengan menempatkan tambahan ke intent.
- Dalam metode
onStartCommand()layanan, cari flag di tambahan argumenintent.
Koneksi diblokir
Pengguna perangkat (atau admin IT) dapat memaksa semua traffic untuk menggunakan VPN. Sistem memblokir semua traffic jaringan yang tidak menggunakan VPN. Orang yang menggunakan perangkat dapat menemukan tombol Blokir koneksi tanpa VPN di panel opsi VPN di Setelan.
Menghentikan penggunaan selalu aktif
Jika aplikasi Anda saat ini tidak dapat mendukung VPN selalu aktif, Anda dapat memilih tidak ikut (di Android
8.1 atau yang lebih tinggi) dengan menetapkan
metadata layanan
SERVICE_META_DATA_SUPPORTS_ALWAYS_ON
ke false. Contoh manifes aplikasi berikut menunjukkan cara menambahkan
elemen metadata:
<service android:name=".MyVpnService"
android:permission="android.permission.BIND_VPN_SERVICE">
<intent-filter>
<action android:name="android.net.VpnService"/>
</intent-filter>
<meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
android:value=false/>
</service>
Jika aplikasi Anda memilih tidak ikut VPN selalu aktif, sistem akan menonaktifkan kontrol UI opsi di Setelan.
VPN per aplikasi
Aplikasi VPN dapat memfilter aplikasi terinstal mana yang diizinkan untuk mengirim traffic melalui koneksi VPN. Anda dapat membuat daftar yang diizinkan, atau, daftar yang tidak diizinkan, namun tidak keduanya. Jika Anda tidak membuat daftar yang diizinkan atau tidak diizinkan, sistem akan mengirim semua traffic jaringan melalui VPN.
Aplikasi VPN Anda harus menetapkan daftar sebelum koneksi dibuat. Jika Anda perlu mengubah daftar, buat koneksi VPN baru. Aplikasi harus diinstal di perangkat saat Anda menambahkannya ke daftar.
// The apps that will have access to the VPN. val appPackages = arrayOf( "com.android.chrome", "com.google.android.youtube", "com.example.a.missing.app" ) // Loop through the app packages in the array and confirm that the app is // installed before adding the app to the allowed list. val builder = Builder() for (appPackage in appPackages) { try { packageManager.getPackageInfo(appPackage, 0) builder.addAllowedApplication(appPackage) } catch (e: PackageManager.NameNotFoundException) { // The app isn't installed. } } // Complete the VPN interface config. val localTunnel = builder .addAddress("2001:db8::1", 64) .addRoute("::", 0) .establish()
Aplikasi yang diizinkan
Untuk menambahkan aplikasi ke daftar yang diizinkan, panggil
VpnService.Builder.addAllowedApplication(). Jika
daftar menyertakan satu atau beberapa aplikasi, hanya aplikasi dalam daftar tersebut yang dapat menggunakan VPN.
Semua aplikasi lain (yang tidak ada dalam daftar) akan menggunakan jaringan sistem seolah-olah VPN
tidak berjalan. Jika daftar yang diizinkan kosong, semua aplikasi dapat menggunakan VPN.
Aplikasi yang tidak diizinkan
Untuk menambahkan aplikasi ke daftar yang tidak diizinkan, panggil
VpnService.Builder.addDisallowedApplication().
Aplikasi yang tidak diizinkan akan menggunakan jaringan sistem seakan-akan VPN tidak berjalan—semua aplikasi
lainnya menggunakan VPN.
Mem-bypass VPN
VPN dapat mengizinkan aplikasi untuk mem-bypass VPN dan memilih jaringannya sendiri. Untuk
mengabaikan VPN, panggil VpnService.Builder.allowBypass() saat
membuat antarmuka VPN. Anda tidak dapat mengubah nilai ini setelah memulai layanan VPN. Jika aplikasi tidak mengikat proses atau soketnya ke jaringan tertentu, traffic jaringan aplikasi akan terus melalui VPN.
Aplikasi yang terikat ke jaringan tertentu tidak memiliki koneksi saat seseorang
memblokir traffic yang tidak melalui VPN. Untuk mengirim traffic melalui jaringan tertentu, aplikasi memanggil metode, seperti ConnectivityManager.bindProcessToNetwork() atau Network.bindSocket() sebelum menghubungkan soket.
Kode contoh
Proyek Open Source Android mencakup aplikasi contoh yang disebut ToyVPN. Aplikasi ini menunjukkan cara menyiapkan dan menghubungkan layanan VPN.