Memasuki mount namespace sebelum mengatur a chroot
, memungkinkan Anda menghindari mengacaukan namespace host dengan mount tambahan, misalnya untuk /proc
. Anda dapat menggunakan chroot
di dalam mount namespace sebagai retasan yang bagus dan sederhana.
Saya pikir ada keuntungan untuk memahami pivot_root
, tetapi memiliki sedikit kurva pembelajaran. Dokumentasi tidak menjelaskan semuanya ... meskipun ada contoh penggunaan di man 8 pivot_root
(untuk perintah shell). man 2 pivot_root
(untuk panggilan sistem) mungkin lebih jelas jika melakukan hal yang sama, dan termasuk contoh program C.
Cara menggunakan pivot_root
Segera setelah memasuki mount namespace, Anda juga perlu mount --make-rslave /
atau setara. Jika tidak, semua perubahan mount Anda menyebar ke mount di namespace asli, termasuk pivot_root
. Anda tidak mau itu :).
Jika Anda menggunakan unshare --mount
perintah, catat itu didokumentasikan untuk diterapkan mount --make-rprivate
secara default. AFAICS ini adalah default yang buruk dan Anda tidak ingin ini dalam kode produksi. Misalnya pada titik ini, itu akan berhenti eject
bekerja pada DVD atau USB yang terpasang di host namespace. DVD atau USB akan tetap terpasang di dalam pohon mount pribadi, dan kernel tidak akan membiarkan Anda mengeluarkan DVD.
Setelah Anda selesai melakukannya, Anda dapat memasang mis. /proc
Direktori yang akan Anda gunakan. Cara yang sama Anda lakukan untuk chroot
.
Tidak seperti ketika Anda menggunakan chroot
, pivot_root
mengharuskan sistem file root baru Anda adalah titik pemasangan. Jika tidak satu sudah, Anda dapat memuaskan ini dengan hanya menerapkan mengikat mount: mount --rbind new_root new_root
.
Gunakan pivot_root
- dan kemudian umount
filesystem root lama, dengan opsi -l
/ MNT_DETACH
. ( Anda tidak perlu umount -R
, yang bisa lebih lama. ).
Secara teknis, menggunakan pivot_root
secara umum perlu melibatkan penggunaan chroot
juga; itu bukan "salah satu atau".
Per man 2 pivot_root
, itu hanya didefinisikan sebagai menukar root dari mount namespace. Itu tidak didefinisikan untuk mengubah direktori fisik yang ditunjuk oleh root proses. Atau direktori kerja saat ini ( /proc/self/cwd
). Hal ini terjadi bahwa hal itu tidak melakukannya, tapi ini adalah hack untuk benang menangani kernel. Halaman buku itu mengatakan bahwa itu bisa berubah di masa depan.
Biasanya Anda menginginkan urutan ini:
chdir(new_root); // cd new_root
pivot_root(".", put_old); // pivot_root . put_old
chroot("."); // chroot .
Posisi chroot
dalam urutan ini adalah detail halus lainnya . Walaupun intinya pivot_root
adalah mengatur ulang mount namespace, kode kernel tampaknya menemukan filesystem root untuk dipindahkan dengan melihat root per-proses, yang merupakan apa yang chroot
ditetapkan.
Mengapa menggunakan pivot_root
Pada prinsipnya, masuk akal untuk digunakan pivot_root
untuk keamanan dan isolasi. Saya suka berpikir tentang teori keamanan berbasis kemampuan . Anda memasukkan daftar sumber daya spesifik yang diperlukan, dan proses tidak dapat mengakses sumber daya lain. Dalam hal ini kita berbicara tentang filesystem yang diteruskan ke mount namespace. Ide ini umumnya berlaku untuk fitur "namespaces" Linux, meskipun saya mungkin tidak mengekspresikannya dengan baik.
chroot
hanya menetapkan root proses, tetapi prosesnya masih mengacu pada namespace mount lengkap. Jika suatu proses tetap memiliki hak istimewa untuk melakukan chroot
, maka itu dapat melintasi kembali namespace sistem file. Sebagaimana dirinci dalam man 2 chroot
, "superuser dapat melarikan diri dari 'chroot jail' dengan ...".
Cara lain yang memicu pemikiran untuk membatalkan chroot
adalah nsenter --mount=/proc/self/ns/mnt
. Ini mungkin argumen yang lebih kuat untuk prinsip ini. nsenter
Saya setns()
perlu memuat ulang root proses, dari root mount namespace ... walaupun fakta bahwa ini berfungsi ketika keduanya merujuk ke direktori fisik yang berbeda, dapat dianggap sebagai bug kernel. (Catatan teknis: mungkin ada beberapa sistem file yang dipasang di atas satu sama lain di root; setns()
menggunakan bagian atas, yang terbaru dipasang).
Ini menggambarkan satu keuntungan dari menggabungkan namespace mount dengan "namespace PID". Berada di dalam namespace PID akan mencegah Anda memasuki mount namespace dari proses yang tidak terbatas. Ini juga mencegah Anda memasukkan root dari proses yang tidak dibatasi ( /proc/$PID/root
). Dan tentu saja namespace PID juga mencegah Anda membunuh proses apa pun yang ada di luarnya :-).
pivot_root
danchroot
: Saya melihat sumber-sumber Docker dan menemukan bahwa jika gagal dieksekusipivot_root
, ia kembali kechroot
, yaitu mekanisme ini dianggap setidaknya sama dalam fungsi untuk keperluan kontainerisasi.