Apa itu wadah LXC yang tidak terjangkau?

20

Apa artinya jika sebuah wadah Linux (wadah LXC) disebut "unprivileged"?

0xC0000022L
sumber

Jawaban:

20

Kontainer LXC tanpa hak adalah yang memanfaatkan ruang nama pengguna ( ). Yaitu fitur kernel yang memungkinkan untuk memetakan berbagai UID pada host ke dalam namespace di mana pengguna dengan UID 0 dapat ada lagi.

Berlawanan dengan persepsi awal saya tentang kontainer LXC tidak terprivat untuk sementara waktu, ini tidak berarti bahwa kontainer tersebut harus dimiliki oleh pengguna host yang tidakrivilegasi. Itu hanya satu kemungkinan.

Yang relevan adalah:

  1. bahwa kisaran UID dan GID bawahan didefinisikan untuk pengguna host ( usermod [-v|-w|--add-sub-uids|--add-sub-gids])
  2. ... dan rentang ini dipetakan dalam konfigurasi wadah ( lxc.id_map = ...)

Jadi, bahkan rootdapat memiliki kontainer yang tidak terjangkau, karena UID efektif dari proses kontainer pada host akan berakhir di dalam kisaran yang ditentukan oleh pemetaan.

Namun, untuk itu rootAnda harus menentukan ID bawahan terlebih dahulu. Tidak seperti pengguna yang dibuat melalui adduser, roottidak akan memiliki rentang ID bawahan yang ditentukan secara default.

Ingat juga bahwa jangkauan penuh yang Anda berikan siap membantu Anda, sehingga Anda dapat memiliki 3 kontainer dengan garis konfigurasi berikut (hanya pemetaan UID yang ditampilkan):

  1. lxc.id_map = u 0 100000 100000
  2. lxc.id_map = u 0 200000 100000
  3. lxc.id_map = u 0 300000 100000

dengan asumsi bahwa rootmemiliki UID bawahan antara 100000 dan 400000. Semua dokumentasi yang saya temukan menyarankan untuk menggunakan 65536 ID bawahan per kontainer, beberapa menggunakan 100000 untuk membuatnya lebih dapat dibaca oleh manusia.

Dengan kata lain: Anda tidak harus menetapkan kisaran yang sama untuk setiap wadah.

Dengan lebih dari 4 miliar (~ 2^32) ID bawahan yang memungkinkan, itu berarti Anda bisa bermurah hati saat memberikan rentang bawahan kepada pengguna host Anda.

Wadah tanpa hak milik dimiliki dan dijalankan oleh root

Untuk menggosoknya lagi. Tamu LXC tidakrivil tidak perlu dijalankan oleh pengguna yang tidakrivileg di host.

Konfigurasikan wadah Anda dengan pemetaan UID / GID bawahan seperti ini:

lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000

di mana pengguna rootdi host memiliki rentang ID bawahan yang diberikan, akan memungkinkan Anda untuk membatasi tamu lebih baik.

Namun, ada satu keuntungan tambahan penting dalam skenario seperti itu (dan ya, saya telah memverifikasi bahwa itu berfungsi): Anda dapat memulai wadah secara otomatis saat startup sistem.

Biasanya ketika menjelajahi web untuk informasi tentang LXC Anda akan diberitahu bahwa tidak mungkin untuk melakukan autostart tamu LXC yang tidak memiliki hak. Namun, itu hanya benar secara default untuk kontainer yang tidak ada dalam penyimpanan sistem untuk kontainer (biasanya sekitar seperti /var/lib/lxc). Jika mereka (yang biasanya berarti mereka diciptakan oleh root dan dimulai oleh root), itu cerita yang berbeda.

lxc.start.auto = 1

akan melakukan pekerjaan dengan cukup baik, setelah Anda memasukkannya ke dalam konfigurasi wadah Anda.

Mendapatkan izin dan konfigurasi dengan benar

Saya sedikit kesulitan dengan ini, jadi saya menambahkan bagian di sini.

Selain potongan konfigurasi yang disertakan via lxc.includeyang biasanya menggunakan nama /usr/share/lxc/config/$distro.common.conf(di mana $distronama distro), Anda harus memeriksa apakah ada juga /usr/share/lxc/config/$distro.userns.confdi sistem Anda dan memasukkannya juga. Misalnya:

lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf

Selanjutnya tambahkan pemetaan ID bawahan:

lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535

yang berarti bahwa host UID 100000 berada root di dalam namespace pengguna tamu LXC.

Sekarang pastikan bahwa izin sudah benar. Jika nama tamu Anda akan disimpan dalam variabel lingkungan $lxcguestAnda akan menjalankan yang berikut:

# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs

Ini akan memungkinkan Anda untuk menjalankan wadah setelah upaya pertama Anda mungkin telah memberikan beberapa kesalahan terkait izin.

0xC0000022L
sumber
4
Jawaban yang bagus - tetapi lxcbukan keharusan untuk hal semacam ini. Anda dapat membuat wadah namespace dalam bentuk apa pun menggunakan util-linuxalat ini unshare. Anda dapat memasukkan wadah tersebut menggunakan util-linuxalat nsenter. Alat yang terakhir ini juga memungkinkan Anda untuk menambahkan proses yang berjalan ke wadah yang sudah dibuat dari luarnya. Dukungan namespace diimplementasikan dalam kernel.
mikeserv
4
@mikeserv: Anda berarti Anda tidak perlu LXC untuk memanfaatkan userns ? Saya tahu itu. Saya juga tahu Docker sekarang memiliki perpustakaan sendiri memanfaatkan fasilitas ini. Tetapi bagaimana Anda akan menampung seluruh sistem tanpa bantuan fasilitas yang ditawarkan oleh LXC? Dan mengapa Anda melakukannya? Maksud saya mengandung satu aplikasi dan dikombinasikan dengan chrootini dapat membantu, tetapi LXC menggabungkan berbagai ruang nama (UTS, mount dll ...) untuk membuat kontainer seluruh sistem.
0xC0000022L
2
Yah ... Seperti yang saya katakan, unsharesudah melakukan ini mengagumkan untuk setiap / semua dari berbagai ruang nama - dan bahkan akan memberi Anda /procmount pribadi yang terpisah dengan satu cli-switch. Jika Anda aplikasi tunggal adalah initdan Anda chrootadalah initramfsmaka Anda mendapatkan seluruh kontainer di detik datar.
mikeserv
0

Untuk menindaklanjuti 0xC0000022L, yang solusinya bekerja dengan baik untuk saya, saya menulis skrip perl peningkatan-uid-gid.pl untuk mengotomatiskan perubahan kepemilikan yang diperlukan sehingga file dalam wadah LXC dipetakan dengan benar.

Tanpa itu, dengan pengaturan yang diusulkan ini, file dalam rootfs wadah LXC milik 0 / root pada host utama akan, dalam wadah LXC itu sendiri, dipetakan ke 65534 / tidak ada. Untuk dipetakan ke 0 / root dalam wadah LXC, mereka harus memiliki 100000 pada host.

Ini dijelaskan di sini https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/ dan skrip dapat langsung diperoleh di gitlab https://gitlab.com /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl

kamuupou
sumber