Użytkownik:Borzole/chroot

Z Fedora Wiki

Wstęp

Uwaga!
Ta metoda nie jest najłatwiejsza i bardzo nie elegancka. Istnieją różne inne programy bazujące na chroot: febootstrap (od debootstrap), mach, mock, rinse, bind-chroot, fakechroot itp. pozwalające zbudować system lub służące do budowy paczek na fedorę w środowisku chroot

Spis treści

Na początek może mały przykład jak to działa.

su -

dla wygody ustawmy katalog jako parametr

export mychroot=/tmp/test_1
mkdir $mychroot
chroot $mychroot
	chroot: cannot run command `/bin/bash': No such file or directory

Dostaliśmy błąd, bo chroot jest czysty i nawet basha tam nie ma. Najprościej go skopiować z naszego systemu lub jeśli budujemy inny system (jak to za chwilę będziemy robić) ściągnąć paczki.
Sprawdzamy, który plik uruchamia polecenie bash

which bash
	/bin/bash

i jakie ma zależności:

ldd /bin/bash
	linux-vdso.so.1 =>  (0x00007fff6f9ff000)
	libtinfo.so.5 => /lib64/libtinfo.so.5 (0x000000386d400000)
	libdl.so.2 => /lib64/libdl.so.2 (0x000000385e600000)
	libc.so.6 => /lib64/libc.so.6 (0x000000385de00000)
	/lib64/ld-linux-x86-64.so.2 (0x000000385da00000)

tworzymy katalogi w chroot

mkdir $mychroot/{bin,lib64}

i kopiujemy

cp {,$mychroot}/bin/bash
cp {,$mychroot}/lib64/libc.so.6
cp {,$mychroot}/lib64/libdl.so.2
cp {,$mychroot}/lib64/libtinfo.so.5
cp {,$mychroot}/lib64/ld-linux-x86-64.so.2

możemy podejrzeć jak teraz wygląda zawartość naszego chroot'a

tree $mychroot 

rezultat:

/tmp/test_1
├── bin
│   └── bash
└── lib64
    ├── ld-linux-x86-64.so.2
    ├── libc.so.6
    ├── libdl.so.2
    └── libtinfo.so.5
2 directories, 5 files

ponawiamy próbę

chroot $mychroot

i jeśli dostaliśmy

bash-4.0#

tzn. że się udało, a żeby wyjść wystarczy wpisać

exit

Środowisko jest bardzo ubogie i jak naciśniesz 2xtab dostaniesz wszystkie możliwe na razie polecenia. Możesz w ten sposób uruchomić dowolny program.
Usuńmy tego testowego chroota

rm -fR $mychroot

Skrypt FedoraChroot

Jeśli zrobisz kopiuj-wklej całej strony to będziesz miał w skypcie słówka [edytuj] z wiki. Możesz je szybko usunąć tak:

cat TymczasowyFedoraChroot.sh | sed -e 's/\[edytuj\]//g' > FedoraChroot.sh

tylko nie kopiuj źródła wiki, bo będziesz miał jeszcze więcej kszaczków

Uwaga!
Przerwy są dla łatwiejszej edycji na wiki, skrypt jest jednym plikiem. Cała trudność polega na znalezieniu zestawu paczek na minimalny system. Ten zestaw pasuje do Fedora 11, czy do innych nie wiem.
#!/bin/bash
 
### Instalacja Fedora 11 (a może rawhide) do chroota
 
# lista mirrorów http://mirrors.fedoraproject.org/publiclist/
 
mychroot="/home/fedora"
# ten jeden adres decyduje jaki system dostaniesz na końcu, tutaj: rawhide
mirror=http://ftp.icm.edu.pl/pub/Linux/fedora/linux/releases/test/11-Preview/Fedora/i386/os
 
# architektura stosowana w nazwach paczek
arch=i586
#arch=x86_64
 
# reszty nie zmieniaj jeśli nie wiesz co to robi
myrepo="$mychroot/myrepo"	
mkdir  -m 700 -p $myrepo

### START ###

start(){
cd $myrepo
wget $mirror/repodata/repomd.xml
 
cat repomd.xml |grep '<location href="repodata/' |cut -d\" -f2 | \
	grep primary.xml | xargs -i echo "wget "$mirror/'{}' |sh
 
find . -name \*.gz -exec gunzip '{}' \;
 
cat *-primary.xml |grep '<location href="Packages/' |cut -d\" -f2 |grep $arch > lista_server
cat *-primary.xml |grep '<location href="Packages/' |cut -d\" -f2 |grep noarch >> lista_server

### lista pakietów ###

# to lista grupy "Core" wraz zależnościami.
# jak coś dopiszesz/odejmiesz, to licz się z zależnościami
cat > lista_moja <<EOF
acl
attr
audit
audit-libs
authconfig
basesystem
bash
bzip2
bzip2-libs
ca-certificates
checkpolicy
chkconfig
coreutils
cpio
cracklib
cracklib-dicts
cronie
crontabs
curl
cyrus-sasl-lib
db4
db4-utils
device-mapper
device-mapper-libs
dhclient
diffutils
dirmngr
e2fsprogs
e2fsprogs-libs
efibootmgr
elfutils-libelf
ethtool
exim
expat
fedora-logos
fedora-release
file
file-libs
filesystem
findutils
fipscheck
gamin
gawk
gdbm
glib2
glibc
glibc-common
gnupg2
gpgme
grep
grub
info
initscripts
iproute
iptables
iptables-ipv6
iputils
kbd
keyutils-libs
krb5-libs
libacl
libattr
libcap
libcurl
libffi
libgcc
libgcrypt
libgpg-error
libidn
libksba
libselinux
libselinux-utils
libsemanage
libsepol
libssh2
libstdc++
libusb
libuser
libvolume_id
libxml2
linux-atm-libs
logrotate
lua
m4
MAKEDEV
mingetty
module-init-tools
ncurses
ncurses-base
ncurses-libs
net-tools
newt
newt-python
nspr
nss
nss-softokn-freebl
openldap
openssh
openssh-server
openssl
pam
passwd
pciutils-libs
pcre
perl
perl-libs
perl-Module-Pluggable
perl-Pod-Escapes
perl-Pod-Simple
perl-version
pinentry
policycoreutils
popt
procps
psmisc
pth
pygpgme
python
python-iniparse
python-libs
python-urlgrabber
readline
rootfiles
rpm
rpm-libs
rpm-python
rsyslog
sed
selinux-policy
selinux-policy-targeted
setserial
setup
shadow-utils
slang
sqlite
sudo
sysvinit-tools
tcp_wrappers-libs
tzdata
udev
upstart
ustr
util-linux-ng
vim-minimal
yum
yum-metadata-parser
zlib
EOF

### porównanie listy pakietów do ściągnięcia z tym co założyliśmy ###

# porównanie
cat lista_moja | xargs -i echo "cat lista_server |grep" /'{}'-[0-9] |sh |sort -u > lista_install
 
# Czy ilość paczek do zainstalowania się zgadza
if [ $(wc -l lista_install |cut -d' ' -f1) = $(wc -l lista_moja |cut -d' ' -f1) ]
then
  echo -e "\n *** ilość paczek się zgadza ;) "
else
  echo -e "\n *** uuuuups skoryguj ręcznie ilość paczek  w pliku 'lista_install' ;("  
fi
 
echo -e " *** aby ściągnąc paczki i rozpocząć instalację z tą konfiguracją wpisz: \n $0 download"
}

### DOWNLOAD ###

download(){	
	cd $myrepo
	cat lista_install | xargs -i echo "wget " $mirror/'{}' |sh
	echo -e " *** mamy paczki, wpisz: \n $0 insatll"
}

### INSTALL ###

install(){
cd $myrepo
 
for p in *.rpm
do 
	rpm2cpio $p | cpio -idmu
done
 
find . -maxdepth 1 -type d -exec mv {,../}'{}' \; 
chroot $mychroot /bin/rpm
echo "jak wyświetliły się opcje rpm tzn. że działa, ...jupi!!! , wpisz: \n $0 init"
}

### INIT bazy rpm ###

# wchodząc do chroot musisz raz na restart hosta :) ustawić
# mount --bind /proc $mychroot/proc
# mount --bind /sys $mychroot/sys
# chroot $mychroot /sbin/start_udev
 
# tego nie jestem pewien czy potrzebne
# chroot $mychroot /sbin/ldconfig
 
init(){
 
cp {,$mychroot}/etc/hosts
cp {,$mychroot}/etc/resolv.conf
 
mount --bind /proc $mychroot/proc
mount --bind /sys $mychroot/sys
 
chroot $mychroot /sbin/start_udev
chroot $mychroot /sbin/ldconfig
 
#inicjujemy bazę rpm
chroot $mychroot /bin/rpm --root / --initdb
#instalujemy to co teraz jest tylko rozpakowane
chroot $mychroot /bin/rpm -ivh /myrepo/*.rpm
# przy problemach z bazą rpm:
# chroot $mychroot 
# cd /var/lib/rpm
# mv Packages Packages_stary
# rm -f __db*
# rpm --rebuilddb
chroot $mychroot /bin/rpm -qa
echo " Jeśli wyświetliły się paczki to jest miodzio = BAZA RPM działa"
 
chroot $mychroot yum clean all
chroot $mychroot yum check-update
 
echo "...i poszło ;) 
 Nim wykonasz 'yum update' ustaw właściwe repozytoria i architekturę
 w katalogu $mychroot/etc/yum.repos.d/ są konfigi repozytoriów
 w plikach  fedora.repo i fedora-updates.repo
	ustaw 'enabled=1' pod [fedora] i [fedora-updates]
	reszta wpisów ma mieć 'enabled=0'
 jak chcesz mieć rawhide to włącz je w pliku fedora-rawhide.repo 
 	ustaw 'enabled=1' pod [rawhide] a wszystko inne wyłącz
 Mając 64bit host i 32bit chroot musisz w konfigach zmienić parametr '\$basearch' na  'i386' 
 możliwe że parametr '\$release' też trzeba skorygować na '11'"
}

### CZYSZCZENIE ###

clean(){
	cd $myrepo
	echo "na razie robisz to z palca ;P"
	# musisz odmontować jeśli chcesz usunąć katalogi chroota
	umount $mychroot/proc
	umount $mychroot/sys
	# nie bardzo, bo rpm trochę ważą 
	# rm -fR $myrepo
}

### WYKONAJ CAŁY SKRYPT ###

all(){
	$0 start
	$0 download
	$0 install
	$0 init
	#$0 clean
	}

### MENU ###

case "$1" in
  start)
        start
        ;;
  download)
  		download
		;;
  install)
		install
        ;;
  init)
        init)
        ;;
 
  clean)
        clean
        ;;
  all)
        all
        ;;
  *)
        echo -e "Tak się tego misiu używa: \t $0 {start|download|install|init|clean|all}"
esac
to jest koniec skryptu

After Party

Tak powstały system można pielęgnować w katalogu, ale nie ma to jak uruchomienie z grub.
Mała uwaga. Dla wygody można dopisać do /etc/fstab montowanie /proc i /sys żeby nie robić tego za każdym razem ręcznie. Jeśli ścieżka do system jest /mnt/rawhide to wpis wygląda tak:

proc  	/mnt/rawhide/proc 	proc 		none 0 0
sysfs  /mnt/rawhide/sys 	sysfs 		none 0 0

W przeciwnym wypadku za każdym razem trzeba montować z palca:

mount --bind /proc $mychroot/proc
mount --bind /sys $mychroot/sys

po wejściu do chroot zawsze robię też:

start_udev

można również na początku pliku /etc/profile dopisać parametr

export mychroot=/mnt/rawhide

żeby już zawsze się "logować" do chroot po prostu przez chroot $mychroot
lub wykonywać polecenia z zewnątrz przez chroot $mychroot yum install kernel
a skoro mowa o kernelu - jeszcze go nie masz ;)
Jeśli myślisz o bootowaniu tego systemu przejdź do chroot

chroot $mychroot

Skoryguj repozytoria jeśli trzeba - zmienna $basearch ustawia się tak jak na hoście więc mając 64bit host i 32bit chroot masz problem taki jak ja. Możesz ustawić architekturę na sztywno:

find $mychroot/yum.repos.d -name \*.repo -exec sed 's/\$basearch/i386/g' '{}' -i.kopia \;

Pamiętaj o tej samej operacji gdy dodasz repo RPMFusion.

Bootowanie systemu

Zrób update i zainstaluj

yum install kernel

w katalogu $mychroot/boot pojawią się pliki initrd-2.6.29.4-167.fc11.i586.img i vmlinuz-2.6.29.4-167.fc11.i586. Przenieś je do głównego /boot i zrób stosowny wpis w grub.conf.
Jeśli jesteś równie nie ogarnięty co ja to całą operację wykonałeś w katalogu a nie na jakiejś partycji i nie wiesz co wpisać w grub ;) Możesz bezpiecznie przerzucić cały system m.in. tak:
zamontuj docelowy dysk

mount /dev/sdaX /mnt/rawhide -t TYP

przejdź do katalogu z systemem (musi być "find .", "find /katalog/" coś mi nie działa)

cd /home/fedora
find . -print0 | cpio -p0vumd /mnt/rawhide
gdzie:
/home/fedora - katalog, w którym zbudowaliśmy chroot
/mnt/rawhide - katalog, w którym zamontowaliśmy docelowy dysk

skopiuj teraz plik /etc/fstab do chroot i skoryguj "/" reszta może zostać. A skoro już masz fstab to możesz zrobić w środku mount -a i tym samym podmontować wszystko jak na hoście
System możesz już uruchomić z poziomu GRUB, pamiętaj jednak że instalowałeś go z najmniejszą możliwą ilością paczek, więc zalogujesz się na root ale mnóstwo rzeczy na razie nie będzie działać.
A pro po logowania na root.

chroot $mychroot passwd
exit
reboot
Przenieś system skąd chcesz i dokąd chcesz
Przeniesienie systemu wychodowanego na VirtualBox / VMware / KVM itp. niczym się nie różni od przenosin z chroot. Również miejsce docelowe nie musi znajdować się pod biurkiem jeśli zamontujesz dysk sieciowy przez NFS lub sambę i masz minimalne pojęcie o instalacji GRUB

Pewnie po restarcie wiele nie ujrzałeś i poza logowaniem na konto root za wiele zrobić nie mogłeś. Możesz pielęgnować system w chroot. Zainstaluj podstawowe paczki:

yum install setuptool firstboot

albo całą grupę

yum groupinstall Base "Administration Tools" "System Tools" "Polish Support" "X Window System"

zresztą sam wybierz

yum grouplist

Co zrobić, żeby korzystać z tych samych użytkowników?

Wystarczy prosta operacja dla każdego usera, a może nawet skrypt do przenosin:

#!/bin/bash
mychroot=/mnt/rawhide
szkodnik=borzole
cat /etc/passwd  |grep $szkodnik >> $mychroot/etc/passwd
cat /etc/shadow  |grep $szkodnik >> $mychroot/etc/shadow 
cat /etc/group   |grep $szkodnik >> $mychroot/etc/group
cat /etc/gshadow |grep $szkodnik >> $mychroot/etc/gshadow

Uruchamianie graficznych aplikacji z chroot

Wystarczy, że aplikacja będzie wiedzieć gdzie ma wylądować w normalnym systemie. Jeśli chcesz (nie musisz, no chyba że coś się nie będzie zgadzało) możesz to sprawdzić przez serwer ssh logując się na localhost.

ssh -Y localhost

lub mając zabronione logowanie na root i ustawiony serwer na porcie np. 2222

ssh -Y user@localhost -p 2222

sprawdzamy teraz $DISPLAY

echo $DISPLAY
localhost:10.0

zapamiętujemy ten wynik i możemy wyjść.
Teraz eksportujemy te dane do chroot

chroot $mychroot export DISPLAY=localhost:10.0

i już możemy wyświetlić program z chroot np. yumex

chroot $mychroot yumex

Jeśli aplikacja wygląda brzydko, to tylko kwestia ustawień motywu.
Niezbyt elegancko uruchamiać program z prawami root. Zróbmy to jako użytkownik. Możesz stworzyć nowego użytkownika lub podłączyć /home w chroot. Jeśli masz już poprawny plik fstab to poprostu wpisz:

chroot $mychroot mount -a

wszystkie partycje z fstab zostaną zamontowane w chroot.
Możesz tę długą operację złożyć w skrypt chrust

#!/bin/bash
mychroot=/mnt/rawhide
szkodnik=borzole
#chroot $mychroot export DISPLAY=localhost:10.0
chroot $mychroot su -$szkodnik -c"$@"

i uruchamiać aplikacje tak

su -c'chrust gedit'

Do uruchamiania aplikacji jako root zrobić drugi skrypt skrypt chrust-root

#!/bin/bash
mychroot=/mnt/rawhide
#chroot $mychroot export DISPLAY=localhost:10.0
chroot $mychroot "$@"

i uruchamiać aplikacje tak

su -c'chrust-root yumex'

Bolączką jest, że uruchomienie aplikacji jako user w chroot może uruchomić tylko root.

...w budowie

Spróbujmy temu zaradzić ustawiając Guid oraz grupę dla programu chroot.
Oczywiście kwestie bezpieczeństwa pomijamy ;)

chgrp wheel /usr/sbin/chroot
chmod 4550  /usr/sbin/chroot
usermod -G wheel -a $szkodnik

w wyniku tej operacji pozbyliśmy się konieczności posiadania praw root żeby uruchomić programy z chroot.
Niestety teraz wymaga podania hasła bezpośredniego usera na chroot, nawet jeśli user to my.

Co gorsza teraz nawet z root na root logować trzeba się tak:

chroot $mychroot su -

zawsze można uruchomić w tym chroocie server ssh i dorobić kluczyki na localhost :) ...jeszcze nad tym pomyślę

Uruchamianie przy użyciu dchroot, schroot
niby [jest paczka SRPM] ale coś mi nie wychodzi jej skompilowanie ;( może później

Źródła

programy

systemy

(english)

XEN