VPN Android berjalan di IPv6, tetapi browser tetap memilih IPv4
Telusuri empat tahap tempat alamat IPv6 privat hilang: resolver, deklarasi VpnService, pemeriksaan kandidat browser, dan pengiriman rute.
VPN aktif, antarmuka web privat menjawab lewat IPv6 dari laptop, dan ponsel Android tetap membuka halaman yang sama lewat IPv4 atau menolak memuatnya sama sekali. Catatan AAAA ada. Terowongan melaporkan alamat IPv6. Tidak ada yang tampak salah di klien. Empat keputusan terpisah menentukan hasilnya: resolver mana yang menjawab, apa yang dideklarasikan VpnService ke Android, keluarga alamat mana yang bersedia dicoba browser, dan apakah sebuah paket dapat melakukan perjalanan pulang pergi. Kerjakan dalam urutan itu alih-alih menambahkan rute default dan berharap gejalanya berpindah.
Langkah 1: buktikan resolver mana yang menjawab kueri AAAA
Android tidak punya satu jalur DNS. VPN dapat mendorong server DNS untuk jaringannya, sistem dapat memakai Private DNS untuk nama host yang dianggapnya memenuhi syarat, dan Chrome dapat menjalankan resolver terenkripsinya sendiri dari chrome://settings/security. Pada ponsel di mana terowongan mendorong 10.61.0.1 tetapi Private DNS menunjuk ke penyedia publik, nama di dalam zona privat Anda tidak diresolusikan oleh mesin yang memiliki zona itu. Browser mendapat jawaban dari resolver tanpa otoritas atas nama tersebut dan menganggapnya tidak ada, dan teks galat tidak pernah menyebut DNS.
Tanyakan langsung ke resolver terowongan sebelum mengubah apa pun. Dua perintah pertama menunjukkan server DNS mana yang dipasang Android ke jaringan aktif dan apakah Private DNS dalam mode otomatis atau ketat; perintah ketiga dijalankan dari klien mana pun di dalam terowongan, bukan dari ponsel.
adb shell dumpsys connectivity | grep -A3 "DnsAddresses"
adb shell settings get global private_dns_mode
nslookup -type=AAAA nas.lan 10.61.0.1
Langkah 2: baca apa yang sebenarnya dideklarasikan VpnService
Sisi Android bersifat eksplisit, bukan disimpulkan. VpnService.Builder menambahkan alamat dengan addAddress, rute dengan addRoute, server DNS dengan addDnsServer, dan dapat membatasi seluruh terowongan ke satu keluarga alamat dengan allowFamily. Builder yang memanggil allowFamily(AF_INET) lalu menambahkan rute IPv6 telah memberi tahu sistem dua hal yang bertentangan, dan pembatasan keluarga itulah yang dipertahankan sistem. Rute yang mencakup fd00:61::/64 digabung dengan alamat antarmuka di prefiks lain gagal karena alasan serupa: alamatnya ada, tetapi bukan on-link untuk rute itu.
Baca deklarasinya alih-alih memercayai tombol di aplikasi. dumpsys netd mencetak alamat dan rute yang terpasang pada antarmuka tun, dan LinkProperties per jaringan di dalam dumpsys connectivity menampilkan daftar DNS di samping keluarga yang diklaim jaringan.
adb shell ip -6 addr show tun0
adb shell ip -6 route show table all | grep tun0
adb shell dumpsys connectivity | grep -E "LinkAddresses|Routes"
Jika antarmuka tun memiliki alamat IPv6 tetapi tidak ada rute yang cocok dengan prefiks layanan, pengiriman IPv6 sudah rusak sebelum browser terlibat. Itu bug yang berbeda dari browser yang menolak mencoba, dan perlu perbaikan yang berbeda.
Langkah 3: browser yang memutuskan apakah akan mencoba IPv6
Chromium tidak memakai setiap catatan AAAA yang diterimanya. Resolver host-nya membawa pemeriksaan keterjangkauan IPv6 dan penyaringan kandidat yang dapat membuang atau menurunkan prioritas IPv6 ketika jaringan dinilai tidak mampu membawanya, dan kode sumber resolver memperlihatkan pemeriksaan itu beserta kondisi di sekitarnya. Logikanya bergantung pada versi dan flag, dan itulah sebabnya dua ponsel pada terowongan yang sama dapat berperilaku berbeda. Setelah kandidat ada, Happy Eyeballs mengadu keluarga per koneksi, sehingga jalur IPv6 yang menjawab lambat masih bisa kalah dari IPv4 yang menjawab cepat.
Amati keputusannya alih-alih menyimpulkannya. Sesi yang direkam melalui chrome://net-export dan diputar ulang di penampil netlog menunjukkan setiap resolusi dan keluarga yang dipilih; chrome://net-internals/#dns menunjukkan hasil yang di-cache. Resolusi yang hanya mengembalikan catatan A untuk nama yang punya AAAA di resolver Anda sendiri menunjuk langsung ke tahap ini.
Langkah 4: pastikan paket dapat melakukan perjalanan pulang pergi
Pemilihan alamat bukan pengiriman. Android menyimpan tabel perutean dan aturan kebijakan per jaringan yang memilih tabel berdasarkan fwmark, jadi rute yang terlihat di tabel utama tidak otomatis rute yang dipakai soket. Membaca aturan dan meminta kernel meresolusikan tujuan untuk alamat sumber memisahkan keduanya.
adb shell ip -6 rule show
adb shell ip -6 route get fd00:61::20 from fd00:61::10
Keluaran route get adalah yang menjawab pertanyaan itu. Jika ia menyebut tun0 dan paket masih mati, beralihlah ke MTU terowongan dan penerusan IPv6 gateway, bukan kembali ke ponsel.
Mengapa menambahkan ::/0 biasanya memperburuk keadaan
Menambahkan ::/0 mengubah klaim terowongan dari satu prefiks menjadi setiap tujuan IPv6. Di ponsel itu dapat memenuhi pemeriksaan keterjangkauan, karena alamat uji di luar prefiks Anda kini tampak dapat dirutekan. Itu tidak menciptakan kapasitas hulu IPv6 di gateway, dan banyak gateway rumah tidak memiliki uplink IPv6 yang berfungsi sama sekali. Hasilnya adalah lubang hitam bagi IPv6 publik: nama yang dulu mundur ke IPv4 kini menggantung, dan halaman privat mungkin tampak lebih baik hanya karena pemeriksaan mengukur hal lain.
Ada juga biaya kebijakan. Dengan ::/0 di terowongan, semua lalu lintas IPv6 keluar melalui VPN, termasuk lalu lintas yang tidak pernah disetujui pemilik jaringan untuk dibawa. Perlakukan itu sebagai keputusan penerapan dengan pemilik bernama, bukan langkah debug yang Anda ambil pada pukul 1 pagi.
Urutan kerja yang mengakhirinya
Pastikan jawaban AAAA datang dari resolver yang memegang zona, baca status VpnService dan netd untuk antarmuka tun, ambil jejak net-export untuk melihat apakah Chromium membuang kandidatnya, lalu uji perjalanan pulang pergi dengan ip -6 route get. Perbaiki lapisan yang benar-benar gagal dan biarkan kebijakan pemisahan apa adanya. Jika nama privat memerlukan jawaban berbeda dari nama publik, itulah gunanya split tunneling.
Catat build ponsel, versi browser, dan resolver yang Anda tanyai. Ketiga fakta itu mengubah "IPv6 is broken" menjadi sesuatu yang dapat direproduksi orang berikutnya.