NET_ADMIN adalah kemampuan Linux yang memungkinkan sebuah proses melakukan administrasi jaringan, dan di dalam kontainer ia melakukan tepat itu di dalam ruang nama jaringan tempat proses berjalan. Ini bukan lisensi untuk membuka soket, dan bukan pengganti perangkat atau rute. Pertanyaan yang menarik bukanlah apakah kemampuan itu diberikan, melainkan ruang nama mana yang menerima perubahan.

Apa yang dicakup kemampuan ini

Di dalam ruang namanya, proses yang memegang NET_ADMIN dapat menaikkan dan menurunkan antarmuka, menetapkan alamat, menambah dan menghapus rute, serta menulis aturan firewall, yaitu kelompok operasi yang dikumpulkan capabilities(7) di bawah kemampuan ini. Ia juga dapat menyesuaikan pengaturan tingkat antarmuka yang mengendalikan cara kernel mengantrekan dan memfilter lalu lintas. Klien VPN biasanya membutuhkan beberapa di antaranya saat mulai dan tidak membutuhkan apa pun lagi setelahnya. Karena itu sebagian besar image meminta jangkauan lebih besar daripada yang dipakai.

Operasi di luar ruang nama itu tidak dicakup, dan hak istimewa yang berdekatan terpisah. Membaca dan menulis paket mentah termasuk NET_RAW, dan membuat perangkat tun membutuhkan kemampuan itu sekaligus akses ke node perangkat. Proses tanpa perangkat mendapat galat izin yang tampak seperti masalah jaringan padahal bukan.

Ruang nama menentukan radius kerusakan

Kontainer pada jaringan jembatannya sendiri menjangkau loopback-nya sendiri, antarmukanya sendiri, dan tabel ruteknya sendiri. Memberi NET_ADMIN di sana memungkinkan klien VPN membangun terowongan tanpa menyentuh keputusan rutek host, yang merupakan susunan yang diasumsikan sebagian besar image kontainer.

Alihkan kontainer itu ke jaringan host dan pemberian yang sama kini menyunting rute host dan firewall host, karena tidak ada lagi ruang nama terpisah yang tersisa. Klien yang seharusnya mengelola satu terowongan lalu dapat mengalihkan lalu lintas seluruh mesin, dan kesalahan pada skrip pembongkarannya meninggalkan aturan di host yang tidak ditulis siapa pun. Tidak ada yang berubah pada kemampuannya sendiri; konteksnya yang berubah. Itulah sebabnya berkas compose yang sama berperilaku berbeda pada dua host.

Tiga prasyarat yang dilebur menjadi satu

Kegagalan awal di kontainer VPN biasanya melibatkan salah satu dari tiga hal terpisah: kemampuan, perangkat terowongan, dan dukungan kernel untuk protokol. Memberikan ketiganya sekaligus berhasil, dan itu juga membuat kegagalan berikutnya mustahil diatribusikan. Potongan compose minimal memberikan kemampuan dan meneruskan node perangkat secara eksplisit:

services:
  vpn:
    image: example/vpn-client:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

Baca dokumentasi image itu sendiri untuk mengetahui sysctl mana yang dibutuhkannya, karena sysctl di dalam kontainer mungkin memerlukan hak istimewa tambahan atau pengaturan tingkat host. Di tempat image hanya mendukung mode ruang pengguna, perangkat tidak diperlukan sama sekali dan daftar kemampuannya menyusut sesuai itu.

Berikan operasi yang sempit, bukan modenya

Mode istimewa menyerahkan setiap kemampuan dan sekaligus memperluas akses perangkat, sehingga menyembunyikan prasyarat mana dari ketiganya yang hilang. Mode itu juga membuat cara gagal kontainer tidak dapat dibedakan dari perubahan host. Utamakan daftar eksplisit meskipun lebih panjang untuk ditulis.

Penerapan rootless dan ruang nama pengguna mengubah arti kemampuan dalam praktik, karena proses mungkin hanya memegangnya di dalam ruang nama yang dipetakan. Menyalin daftar kemampuan dari contoh rootful ke runtime rootless dan mengharapkan jangkauan yang sama adalah cara umum kehilangan satu sore.

Rahasia termasuk keputusan terpisah. Memegang NET_ADMIN tidak mengatakan apa pun tentang identitas rekan yang ditampilkan klien, kredensial yang dimuatnya, atau cara kredensial itu dirotasi. Administrasi jaringan tidak menyediakan kepercayaan.

Verifikasi perubahan dan catat mengapa pemberian itu ada

Pastikan apa yang benar-benar diterima kontainer sebelum men-debug terowongan. Pemeriksaan di bawah melaporkan kemampuan yang ditambahkan dan mode jaringan, lalu menunjukkan seperti apa daftar antarmuka dari dalam:

docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip route

Jika kemampuannya ada dan daftar antarmuka masih kosong, klien gagal sebelum dapat membuat apa pun, dan log kontainer adalah tempat berikutnya untuk dilihat. Jika terowongannya ada tetapi lalu lintas tidak mengalir, tabel rutek di dalam kontainer menjawab pertanyaan berikutnya.

Uji juga jalur pembongkaran, karena klien yang menulis aturan firewall dapat meninggalkannya. Hentikan kontainer dan periksa ulang himpunan aturan host jika jaringan host digunakan. Pemberian yang hanya dibutuhkan dua detik saat mulai tidak boleh dijelaskan di berkas compose sebagai persyaratan permanen tanpa catatan yang menjelaskannya.

Tuliskan alasannya di samping setiap kemampuan: operasi mana yang membutuhkannya dan apa yang gagal tanpanya. Catatan itu bertahan melewati pembaruan image, dan itulah bedanya antara daftar hak istimewa yang ditinjau dan daftar yang tumbuh karena salin-tempel.

Artikel terkait