Linux ad alanlarıyla chroot nasıl yapılır?


14

Linux ad alanlarını okuduktan sonra, diğer birçok özellik arasında, chroot'a bir alternatif oldukları izlenimindeydim. Örneğin, bu makalede :

[İsim alanlarının] diğer kullanımları arasında, bir işlemin tek dizin hiyerarşisinin bir kısmına [...] chroot () tarzı izolasyonu dahildir.

Ancak, bağlanma ad alanını klonladığımda, örneğin aşağıdaki komutla, yine de tüm orijinal kök ağacını görüyorum.

unshare --mount -- /bin/bash

Artık yeni ad alanında orijinal ad alanı ile paylaşılmayan ek bağlar gerçekleştirebildiğimi anlıyorum ve bu nedenle yalıtım sağlıyor, ancak yine de aynı kök, örneğin /etcher iki ad alanı için de aynı. Hala chrootkök değiştirmem gerekiyor mu yoksa bir alternatif var mı?

Bu sorunun bir cevap vermesini bekliyordum , ama cevap sadece chroottekrar kullanıyor .

DÜZENLEME # 1

Bahsedilen şimdi silinmiş bir yorum vardı pivot_root. Bu aslında bir parçası linux/fs/namespace.colduğu için, aslında ad alanları uygulamasının bir parçasıdır. Bu, kök dizini yalnızca unshareve ile değiştirmenin mountmümkün olmadığını, ancak ad alanlarının kendi daha akıllı bir sürümünü sağladığını gösterir chroot. Yine de chroot, kaynak kodu okuduktan sonra bile (örneğin güvenlik veya daha iyi izolasyon anlamında) onu temelden farklı kılan bu yaklaşımın ana fikrini alamıyorum .

DÜZENLEME # 2

Bu, bu sorunun bir kopyası değil . Tüm komutları cevaptan yürüttükten sonra ayrı /tmp/tmp.vyM9IwnKuY (veya benzeri) var, ancak kök dizini hala aynı!


Arasındaki fark ile ilgili olarak pivot_rootve chroot: I Docker kaynaklarına bir göz aldı ve yürütme başarısız olduğu bulunmuştur pivot_root, bu geri düşer chroot, yani bu mekanizmalar konteynerleflme amacıyla özelliklerin en azından benzer olduğu kabul edilir.
Danila Kiver

Yanıtlar:


13

Bir kurulum adından önce bir montaj ad alanı girmek chroot, ana bilgisayar ad alanını ek bağlarla, örneğin /proc. Sen kullanabilirsiniz chrootbir bir güzel ve basit bir hack olarak ad monte içeride.

Anlamanın avantajları olduğunu düşünüyorum pivot_root, ancak biraz öğrenme eğrisi var. Belgeler her şeyi açıklamıyor ... man 8 pivot_root(shell komutu için) içinde bir kullanım örneği olmasına rağmen . man 2 pivot_root(sistem çağrısı için) aynısını yaptıysa ve bir örnek C programı içeriyorsa daha net olabilir.

Pivot_root nasıl kullanılır?

Montaj ad alanına girdikten hemen sonra, mount --make-rslave /ya da eşdeğeri gerekir . Aksi takdirde, tüm mount değişiklikleriniz, orijinal ad alanındaki mountlara yayılır pivot_root. Bunu istemiyorsun :).

unshare --mountKomutu kullandıysanız, mount --make-rprivatevarsayılan olarak uygulamak için belgelendiğine dikkat edin . AFAICS bu kötü bir varsayılan değerdir ve bunu üretim kodunda istemezsiniz. Bu noktada, ejectana bilgisayar ad alanında takılı bir DVD veya USB üzerinde çalışmayı durduracaktır . DVD veya USB özel montaj ağacının içinde takılı kalır ve çekirdek DVD'yi çıkarmanıza izin vermez.

Bunu yaptıktan sonra, örneğin /prockullanacağınız dizini bağlayabilirsiniz . Aynı şekilde chroot.

Kullandığınızda aksine chroot, pivot_rootyeni kök dosya sistemi bağlama noktası olmasını gerektirir. Zaten biri değilse, sadece bir bağlama monte uygulayarak bu tatmin edebilir: mount --rbind new_root new_root.

Kullanım pivot_root- sonra umounteski kök dosya sistemi, -l/ MNT_DETACHseçeneğiyle. ( İhtiyacınız yok umount -R, bu daha uzun sürebilir. ).

Teknik olarak, pivot_rootgenellikle kullanmanın chrootda kullanmayı içermesi gerekir ; "ya" ya da "değil.

Buna göre man 2 pivot_root, yalnızca mount ad alanının kökünü değiştirmek olarak tanımlanır. İşlem kökünün işaret ettiği fiziksel dizini değiştirmek için tanımlanmamıştır. Veya geçerli çalışma dizini ( /proc/self/cwd). Bunu yapar , ancak bu çekirdek ipliklerini işlemek için bir hack'tir. Manpage, bunun gelecekte değişebileceğini söylüyor.

Genellikle bu diziyi istersiniz:

chdir(new_root);            // cd new_root
pivot_root(".", put_old);   // pivot_root . put_old
chroot(".");                // chroot .

Arasında postition chrootbu sırayla yine bir başka ince bir detayıdır . Her ne kadar bağlantı noktası pivot_rootad alanını yeniden düzenlemek olsa da , çekirdek kodu, chrootayarlanan işlem başına köke bakarak hareket edecek kök dosya sistemini bulur .

Neden pivot_root kullanılır?

Prensip olarak, pivot_rootgüvenlik ve izolasyon için kullanmak mantıklıdır . Yetenek temelli güvenlik teorisini düşünmeyi seviyorum . Gerekli belirli kaynakların bir listesini iletirsiniz ve işlem başka hiçbir kaynağa erişemez. Bu durumda, bir mount ad alanına aktarılan dosya sistemlerinden bahsediyoruz. Bu fikir genellikle Linux "ad alanları" özelliği için geçerlidir, ancak muhtemelen çok iyi ifade etmiyorum.

chrootyalnızca işlem kökünü ayarlar, ancak işlem yine de tam bağlama ad alanını belirtir. Bir işlem gerçekleştirme ayrıcalığını koruyorsa chroot, dosya sistemi ad alanını geri alabilir. Daha ayrıntılı olarak açıklandığı gibi man 2 chroot, "süper kullanıcı" ... bir hapishane hapishanesinden "kaçabilir."

Geri alma için başka düşündürücü yolu chrootolduğunu nsenter --mount=/proc/self/ns/mnt. Bu belki de ilke için daha güçlü bir argüman. nsenter/ setns()zorunlu olarak, işlem adının kök ad alanının kökünden yeniden yüklenmesine rağmen, ikisi farklı fiziksel dizinlere başvurduğunda bunun çalışması bir çekirdek hatası olarak kabul edilebilir. (Teknik not: kökte üst üste monte edilmiş birden fazla dosya sistemi olabilir; setns()en son monte edilmiş olanı kullanır).

Bu, bir bağlanma ad alanını bir "PID ad alanı" ile birleştirmenin bir avantajını gösterir. Bir PID ad alanının içinde bulunmak, birleştirilmemiş bir işlemin bağlama ad alanına girmenizi önler. Ayrıca, birleştirilmemiş bir işlemin ( /proc/$PID/root) köküne girmenizi de önler . Ve elbette bir PID ad alanı, bunun dışındaki herhangi bir işlemi öldürmenizi de önler :-).


Bu zaten çok yardımcı oluyor. Yine de, "ad alanının üst kısmındaki yuva" ile ne demek istediğinizden emin değilim. Ve bunu değiştirmenin bir yolu var mı?
koalo

1
@koalo düzenledi :-). ps neden "make-rslave" / "make-rprivate" için fstab ihtiyacınız olacağını bilmiyorum. systemd's switch-root.c sadece yaparmount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)
sourcejedi

1
@ koalo ve sonra linux çekirdek geliştiricileri dördüncü bir şey adlandırdıklarında "rootfs" kullandılar: -P. unix.stackexchange.com/questions/152029/…
sourcejedi

1
Bu yanıt ve @sourcejedi tarafından diğerleri son derece yararlı olmuştur, ben "pivot_root: put_old meşgul olarak umount olamaz" sormak isterdim ama cevap zaten buradaydı, kuvvet işe yaramaz gibi tembel olunumount -l ./oldroot
earcam

1
Son zamanlarda pivot_root (2) kılavuz sayfasında birkaç açıklama içeren bir güncelleme yapıldı ve şimdi örnek bir program içeriyor. Cevabınızı bunu yansıtacak şekilde güncellemek isteyebilirsiniz? Man sayfası şimdi de çoğu durumda pivot_root(".", ".")kullanmanın en kolay yolu pivot_root( chrootgerekli değil) olan güzel hileyi açıklıyor .
Philipp Wendler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.