Daemon VPN membutuhkan operasi jaringan berhak istimewa meskipun aplikasi biasa membuka soket keluar tanpa hak istimewa apa pun. Di celah itulah sebagian besar kesalahan kemampuan dimulai: seseorang melihat kesalahan izin, memberikan seluruh set, dan layanan bekerja karena alasan yang tak bisa dijelaskan siapa pun nanti. Penelusuran di bawah dimulai dari operasi yang gagal, memetakannya ke satu otoritas, lalu memeriksa konteks tempat proses benar-benar berjalan. Berjalan sebagai root tanpa batas adalah jawaban yang sah untuk beberapa penerapan, tetapi itu seharusnya menjadi keputusan, bukan nilai bawaan.

Mulailah dari operasi yang gagal

Baca kesalahannya sebelum membaca tutorial. «Operasi tidak diizinkan» pada perubahan antarmuka, penolakan membuka node perangkat, dan kegagalan bind pada port rendah adalah tiga masalah berbeda dengan tiga pemberian izin berbeda. Jika proses mulai dan hanya gagal pada perubahan rute pertama, itu juga berarti pembuatan antarmuka sudah berhasil, yang sangat mempersempit jawabannya.

Reproduksi kegagalan dengan layanan berhenti, lalu jalankan di latar depan di bawah pengguna yang sama jika implementasinya mengizinkan. Kesalahan yang bisa Anda lihat lebih baik daripada baris log yang harus Anda duga, dan itu membuat perbedaan antara masalah kemampuan dan penolakan SELinux atau AppArmor menjadi jelas.

Petakan setiap operasi ke satu otoritas

Tabel ini adalah peta awal, bukan pengganti dokumentasi implementasi:

OperationUsual authorityWatch for
Create or configure tun/tapCAP_NET_ADMIN in the relevant namespaceCreating the device and opening it are separate steps
Add routes, rules, firewall entriesCAP_NET_ADMINSame capability, different namespace than you think
Open /dev/net/tunDevice permissions, not a capabilityGroup membership or a udev rule may be enough
Raw socketsCAP_NET_RAWNeeded by some user-space tunnel implementations
Bind a port below 1024CAP_NET_BIND_SERVICEIrrelevant for most modern tunnel ports

Dua baris dalam tabel itu adalah yang orang sering campur adukkan. Membuka /dev/net/tun adalah soal izin berkas; meminta kernel mengonfigurasi apa yang Anda buka adalah soal kemampuan. Memberikan CAP_NET_ADMIN tidak memperbaiki node perangkat yang tidak bisa dibaca pengguna layanan Anda, dan memperbaiki node itu tidak memberi Anda otoritas rute. Periksa keduanya sebelum Anda mengubah salah satunya.

WireGuard di kernel dan program terowongan di ruang pengguna juga tidak punya persyaratan yang sama. Jalur modul kernel mengonfigurasi antarmuka yang sudah ada melalui netlink, sedangkan implementasi di ruang pengguna mungkin juga membutuhkan perangkat dan, untuk sebagian transport, soket mentah.

Baca konteksnya: layanan, kontainer, atau shell

Kemampuan di ruang nama jaringan host bisa berdampak jauh lebih besar daripada operasi yang sama di dalam tumpukan yang sengaja diisolasi. Lingkungan runtime kontainer biasanya dimulai dengan set batas yang diperkecil; menambahkan NET_ADMIN ke kontainer yang berbagi jaringan host adalah pemberian izin yang jauh lebih besar daripada menambahkannya ke kontainer dengan ruang nama jaringannya sendiri dan tanpa pemasangan dari host.

Untuk unit systemd, bacalah apa yang benar-benar diterapkan, bukan apa yang tampaknya dikatakan berkas unit: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities melaporkan nilai efektif, yang mungkin ditetapkan oleh drop-in yang Anda lupakan. Mintalah nilai efektif, jangan pernah nilai yang dimaksudkan. Kemampuan ambient penting karena layanan non-root kehilangan kemampuan di sepanjang exec tanpanya.

Gunakan penyiapan paket atau image yang didukung sebagai garis dasar. Jangan menambahkan izin soket mentah atau mode berhak istimewa karena tutorial lain mencantumkannya untuk alat lain; penalaran itu tidak memindahkan apa pun dan membuat Anda kehilangan isolasi yang Anda bayar. Jika ragu, jangan berikan apa pun dan bacalah catatan implementasi untuk operasi persis yang Anda butuhkan.

Perhatikan apa yang terjadi setelah hak istimewa turun

Banyak daemon mulai dengan hak istimewa, mengonfigurasi antarmuka, lalu turun ke pengguna tanpa hak istimewa dan mempertahankan terowongan. Sejak titik itu proses tidak lagi dapat menambah rute, menulis ulang aturan firewall, atau membuka perangkat berhak istimewa baru, yang tidak masalah sampai koneksi ulang membutuhkan tepat itu. Pembacaan berkas dan eksekusi hook berikutnya bisa gagal karena alasan yang sama.

Uji seluruh siklus hidup, bukan detik pertama: penyalaan, pembaruan atau koneksi ulang, dan pembersihan saat berhenti. Keberhasilan pertama membuat antarmuka tidak membuktikan bahwa setiap operasi berhak istimewa berikutnya masih berfungsi, dan kegagalan biasanya muncul berjam-jam kemudian di produksi.

Implementasi yang menjaga terowongan tetap terbuka selama pergantian pengguna biasanya memadukannya dengan opsi untuk mempertahankan terowongan dan kunci. Di sisi systemd, pertanyaan yang setara adalah apakah set kemampuan unit bertahan melewati pergantian pengguna yang Anda konfigurasikan.

Catat pemberian izin dan alasannya

Tuliskan izin persisnya, operasi yang dimungkinkannya, dan kesalahan yang diperbaikinya. Satu baris di catatan penerapan — «CAP_NET_ADMIN di ruang nama jaringan unit, diperlukan untuk perubahan rute setelah koneksi ulang» — cukup untuk mencegah orang berikutnya memperlebar izin lagi.

Lalu baca ulang set efektif setelah setiap peningkatan. Vendor menambahkan fitur, image mengubah nilai bawaan, dan kemampuan yang tidak perlu tahun lalu bisa menjadi penopang tanpa ada yang menyadarinya.

Artikel terkait