Chroot ile çalıştığımı nasıl söylerim?


46

Hem chroot hem de bağımsız bir sistem olarak kullanılabilecek bir unix kurulumum var. Chroot olarak çalışıyorsa, herhangi bir hizmeti çalıştırmak istemiyorum (cron, inetd vb.), Çünkü ana bilgisayar sistemiyle çakışırlar veya gereksiz olurlar.

Chroot'ta çalışıp çalışmadığına bağlı olarak farklı davranış gösteren bir kabuk betiğini nasıl yazarım? Acil ihtiyacım /procchroot'a monte edilmiş modern bir Linux sistemi ve senaryo root olarak çalışıyor, ancak daha taşınabilir cevaplar da memnuniyetle karşılanıyor. (Bkz Ben proc monte edilmediği takdirde / I? Chroot içinde koşuyorum anlatmak nasıl olmadan Linux durumunda için /proc.)

Daha genel olarak, diğer tutma yöntemleri için çalışan öneriler ilginç olacaktır. Pratik soru şu ki, bu sistemin herhangi bir hizmeti çalıştırması gerekiyor mu? (Cevabım chroot'ta değil, tam teşekküllü sanal makinelerde evet; hapishaneler veya konteynırlar gibi ara durumlar hakkında bilgim yok.)

Yanıtlar:


45

Burada yaptığım şey, initişlemin kökünün (PID 1) geçerli işlemin kökü ile aynı olup olmadığını sınamaktır . Her /proc/1/rootzaman bir bağlantı olmasına rağmen /( initkendisi chrooted olmadıkça , ama umurumda olan bir durum değildir), ardından “master” kök dizinine yönlendirilir. Bu teknik Debian'daki birkaç bakım betiğinde, örneğin chroot'a yüklendikten sonra udev'i atlamak için kullanılır.

if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
  echo "We are chrooted!"
else
  echo "Business as usual"
fi

(Bu arada, bu, chrootchrooted işlem root erişimine sahipse güvenlik için neden işe yaramaz olduğunun bir başka örneği. Rootif olmayan işlemler okunamıyor /proc/1/root, ancak /proc/1234/rootPID 1234 ile aynı şekilde çalışan bir işlem varsa takip edebilirler. kullanıcı.)

Kök izniniz yoksa, şunlara bakabilirsiniz /proc/1/mountinfove /proc/$$/mountinfo( filesystems/proc.txtLinux çekirdek belgelerinde kısaca belgelenmiştir ). Bu dosya dünyaca okunur ve işlemin dosya sistemi görünümündeki her bağlama noktası hakkında birçok bilgi içerir. Bu dosyadaki yollar, varsa okuyucu işlemini etkileyen chroot tarafından sınırlandırılır. İşlem okuması /proc/1/mountinfo, genel kökünden farklı bir dosya sistemine bölünürse (Pid 1'in kökünün genel kök olduğu varsayılarak), içinde hiçbir girdi /görünmez /proc/1/mountinfo. İşlem okuması /proc/1/mountinfogenel kök dosya sistemindeki bir dizine chroot edilirse, bunun için bir giriş /görünür /proc/1/mountinfo, ancak farklı bir mount kimliği ile. Bu arada, kök alanı ($4) chroot'un ana dosya sistemindeki yerini gösterir.

[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]

Bu saf bir Linux çözümüdür. Yeterli derecede benzer olan diğer Unix varyantlarına genellenebilir /proc(Solaris benzer /proc/1/root, sanırım değil mountinfo).


1
Bu, OpenBSD'de çalışmayacaktır çünkü rastgele PID'lere sahiptir ; Kök süreci temelde asla PID 1 değildir. Şimdi nedenini biliyorsunuz!
Adam Katz

@AdamKatz "... birkaç açık istisna dışında, örneğin, init (8)." Peki hangisi?
muru,

@muru: aw, shucks. Beni vurdun. Bunu init(8)gerektiren bir tür zor kodlanmış doğa olmadığı sürece neden kesinlikle 1 numaraya ihtiyaç duyacağından emin değilim (ki neden hala emin olamadım ). Elbette, BSD'lerin sadece chroot'tan çok daha gelişmiş hapishaneler var, bu yüzden bunun ne kadar sorunlu olduğundan bile emin değilim.
Adam Katz

4
@AdamKatz Tam tersi: pid 1'in özel bir rolü var (zombileri biçmeli ve SIGKILL'e karşı bağışık olmalı). Init programı bu rolün bir uygulamasıdır. Cevabımın OpenBSD’de çalışmamasının sebebi bununla hiçbir ilgisi yok: OpenBSD’nin Solaris / Linux’lar gibi bir şeyi olmadığı için /proc. Cevabım zaten Linux dışında hiçbir şeyi ele almak değildi.
Gilles 'SO- kötülük olmayı bırak'

@ Gilles, OpenBSD'nin bunu bir şekilde veya başka şekilde yeneceğini düşündüm. Yine de, bu özel rol öğelerinin hepsinin keyfi bir PID'e (sonuçsuz) uygulanamayacağına şaşırdım, bu daha önce italikleştirdiğim "neden" dediğim şeydi.
Adam Katz

22

Belirtildiği gibi taşınabilir inode numarasını bulmak için yol ve içinden bir chroot hapis algılama , sen düğümü sayısı olup olmadığını kontrol edebilirsiniz /ise 2:

$ ls -di /
2 /

2'den farklı bir inode numarası, görünen kökün bir dosya sisteminin gerçek kökü olmadığını gösterir. Bu, bir bağlama noktasında veya rasgele kök inode numaralarına sahip işletim sistemlerinde köklenen chroot'ları algılamaz .


Bu buluşsal yöntem hangi dosya sistemlerinde çalışır?
Gilles 'SO- kötülük'

Ext3 ve hfs üzerinde test edilmiştir.
l0b0

Bu yüzden dalga geçiyordum ve sanırım root izinleri gerektirmeyen daha güvenilir bir yöntem buldum (sadece Linux). Hala karşı örneklere veya daha fazla taşınabilir yönteme açığım.
Gilles 'SO- kötülük'

6
Bu, ext [234] için de geçerlidir, ancak tüm dosya sistemlerinde değildir. Aynı zamanda sadece sizin kökünüzün, gerçek kök olarak bağlanamayan dosya sisteminin kökü olduğunu test eder. Başka bir deyişle, / hapishaneye başka bir bölüm eklerseniz chroot /jail, o zaman bu test için gerçek kök gibi görünecektir.
psusi

1
@AdamKatz Görünüşe göre değil. Openbsd 6.0-stabil'de test edildiğinde, inode numarası, gerçek kök yolu için hala 2 iken, chroot için rastgele bir sayıdır.
Dmitri DB

5

Burada listelenen birçok seçenek kadar taşınabilir olmasa da, Debian tabanlı bir sistem kullanıyorsanız, deneyin ischroot.

Bkz .: https://manpages.debian.org/jessie/debianutils/ischroot.1.en.html

Konsoldaki durumu doğrudan almak için, ischroot'u kullanarak:

ischroot;echo $?

Çıkış kodları:

0 if currently running in a chroot
1 if currently not running in a chroot
2 if the detection is not possible (On GNU/Linux this happens if the script is not run as root).
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.