Chroot : Différence entre versions

De ArchwikiFR
(Ajout de chroot depuis un autre système)
(Cas concret: ssh : utilisation du template {{rc}})
Ligne 128 : Ligne 128 :
 
Redémarrez '''ssh''':
 
Redémarrez '''ssh''':
  
/etc/rc.d/ssh restart
+
{{rc|ssh|restart}}
  
 
Puis:
 
Puis:

Version du 17 mai 2011 à 22:35


Le chroot (abréviation de CHanging ROOT) est un processus qui permet de changer la racine en entrant dans un environnement isolé.

Si vous avez atterri sur cette page en cherchant comment installer en chroot, ça se passe plutôt ici

Chroot depuis un autre système

Quelle qu’en soit la raison, vous pouvez être amené à vouloir utiliser votre système Arch depuis un autre système GNU/Linux (LiveCD, autre installation, ...), pour cela et en supposant que vous utilisez le dossier /etc/mnt, vous devez monter au minimum les dossiers suivants:

mount /dev/sdXY /mnt
mount -t proc proc /mnt/proc
mount -t sysfs sys /mnt/sys
mount -o bind /dev /mnt/dev

/dev/sdXY étant la partition de votre / Puis:

chroot /mnt /bin/bash

Chroot minimal

Préambule

Avant de nous lancer dans la construction d'un environnement chroot, une explication rapide sur le fonctionnement d'un exécutable binaire sous un système GNU/Linux: En dehors des fichiers de configurations, un exécutable binaire est un exécutable liée à une ou plusieurs librairies partagées, pour pouvoir exécuter /bin/bash par exemple, il nous faut:

ldd /bin/bash
	linux-gate.so.1 =>  (0xb7fad000)
	libreadline.so.6 => /lib/libreadline.so.6 (0xb7f62000)
	libhistory.so.6 => /lib/libhistory.so.6 (0xb7f5a000)
	libncursesw.so.5 => /lib/libncursesw.so.5 (0xb7f0d000)
	libdl.so.2 => /lib/libdl.so.2 (0xb7f09000)
	libc.so.6 => /lib/libc.so.6 (0xb7dc3000)
	/lib/ld-linux.so.2 (0xb7fae000)

Note : Dans cette section, le répertoire de base est /home et l'environnement chroot est /home/chroot_env

Construction

Pour créer un environnement, on va utiliser un script qui va rechercher les librairies pour nous et créer l'arborescence des répertoires :

Fichier: chroot.sh
#!/bin/bash
# Utilisation: $0 <chroot_path> <program list>
rep="$1"
shift

# Copie $1 vers $2 en créant les répertoires parents.
copie_dir ()
{
	[ -e "${2}" ] && return
 	rep_base=$(dirname "${2}")
 	[ -d "${rep_base}" ] || {
 		echo "++ mkdir -p ${rep_base}"
 		mkdir -p "${rep_base}"
 	}
 	echo "+ cp -a $1 $2"
 	cp -a "$1" "$2"
}
 
# Copie $1 vers $2 + copie des librairies utilisées.
copie_ldd ()
{
	local src dest file f f_link
 	src="$1"
 	dest="$2"
 	[ -e "${dest}" ] && return
 	file=( $(ldd "$src" | awk '{print $3}' | grep '^/') )
 	file=( "${file[@]}" $(ldd "$src" | grep '/' | grep -v '=>' | awk '{print $1}') )
 	for f in "${file[@]}"
 	do
 		f_link=$(readlink -f "$f")
 		copie_dir "$f_link" "${rep}${f}"
 	done
 	copie_dir "$src" "${dest}"
}
 
for prog in "$@"
do
 	prog=$(which "$prog")
 	prog_real=$(readlink -f "$prog")
 	copie_ldd "$prog_real" "${rep}${prog}"	
done

Créons le répertoire où sera notre environnement chroot, et copions y un minimum d'outils:

# cd /home
# mkdir chroot_env
# ./chroot.sh chroot_env bash ls cp mv rm cat more mkdir touch
++ mkdir -p chroot_env/lib
+ cp -a /lib/libreadline.so.6.0 chroot_env/lib/libreadline.so.6
+ cp -a /lib/libhistory.so.6.0 chroot_env/lib/libhistory.so.6
+ cp -a /lib/libncursesw.so.5.7 chroot_env/lib/libncursesw.so.5
+ cp -a /lib/libdl-2.10.1.so chroot_env/lib/libdl.so.2
+ cp -a /lib/libc-2.10.1.so chroot_env/lib/libc.so.6
+ cp -a /lib/ld-2.10.1.so chroot_env/lib/ld-linux.so.2
++ mkdir -p chroot_env/bin
+ cp -a /bin/bash chroot_env/bin/bash
+ cp -a /lib/librt-2.10.1.so chroot_env/lib/librt.so.1
+ cp -a /lib/libcap.so.2.17 chroot_env/lib/libcap.so.2
+ cp -a /lib/libacl.so.1.1.0 chroot_env/lib/libacl.so.1
+ cp -a /lib/libpthread-2.10.1.so chroot_env/lib/libpthread.so.0
+ cp -a /lib/libattr.so.1.1.0 chroot_env/lib/libattr.so.1
+ cp -a /bin/ls chroot_env/bin/ls
+ cp -a /bin/cp chroot_env/bin/cp
+ cp -a /bin/mv chroot_env/bin/mv
+ cp -a /bin/rm chroot_env/bin/rm
+ cp -a /bin/cat chroot_env/bin/cat
+ cp -a /bin/more chroot_env/bin/more
+ cp -a /bin/mkdir chroot_env/bin/mkdir
+ cp -a /bin/touch chroot_env/bin/touch

Il ne reste plus qu'à lancer le chroot:

# chroot chroot_env
bash-4.2# ls
bin  lib
bash-4.2# exit

Cas concret: ssh

Ce genre d'environnement peut être utilisé moyennement un minimum de modification comme environnement minimal pour un serveur ssh. En supposant que vous avez un serveur ssh fonctionnel, et un utilisateur nommé test, modifiez l'environnement comme suit:

mkdir chroot_env/dev
cp -a /dev/{null,zero,stdin,stdout,stderr,{u,}random,tty} chroot_env/dev
mkdir chroot_env/home/test

Puis, modifiez le fichier /etc/ssh/sshd_config en y rajoutant:

Fichier: /etc/ssh/sshd_config
Match User test
 	ChrootDirectory /home/chroot/

Redémarrez ssh:

/etc/rc.d/ssh restart

Puis:

$ ssh test@localhost
test@localhost's password: 
Last login: Tue Oct 13 01:11:14 2009 from localhost.localdomain
-bash-4.0$ pwd
/home/test
-bash-4.0$ ls /bin   
bash  cat  cp  ls  mkdir  more	mv  rm  touch

Chroot avec mkarchroot

Pour un système complet, il peut être fastidieux d'utiliser le script précédent, recréer la configuration manuellement ainsi de suite; heureusement, on peut utiliser pacman pour installer les paquets de base sous une nouvelle arborescence, et encore mieux, on peut utiliser les outils livrés avec la distribution pour automatiser tout ça:

pacman -S devtools

Ce qui nous fournit l'outil mkarchroot qui permet de créer, mettre à jour et même configurer l'environnement de chroot, pour mener ceci à bien, il nous suffit de lui indiquer un pacman.conf et un répertoire de base.

Pour l'exemple, on va prendre un pacman.conf pointant vers des dépôts en 32bits, ce qui donnera un environnement 32 même pour les utilisateurs de 64bits, créons donc un pacman.conf dans /root:

Fichier: /root/pacman.conf
 [options]
 HoldPkg     = pacman glibc
 SyncFirst   = pacman
 [core]
 Server = http://mir.archlinux.fr/$repo/os/i686
 [extra]
 Server = http://mir.archlinux.fr/$repo/os/i686
 [community]
 Server = http://mir.archlinux.fr/$repo/os/i686

Puis création de l'environnement :

mkarchroot -C /root/pacman.conf /home/chroot_env base

Afin de compléter un environnement, un minimum de données doivent être reprises dans l'environnement chrooté, mkarchroot le fait automatiquement, mais ça ne coûte rien de voir le détail:

Les répertoires devant être repris dans l'environnement chroot:

  • /dev permet d'accéder au périphériques.
  • /proc et /sys représentent l'état du système.
  • /etc/mtab contient la liste des périphériques montés.
  • /etc/resolv.conf permet la résolution dns.

Ce qui donne manuellement:

mount -o bind /dev chroot_env/dev
mount -o bind /proc chroot_env/proc
mount -o bind /sys chroot_env/sys
cp -a /etc/mtab chroot_env/etc/mtab
cp -a /etc/resolv.conf chroot_env/etc/resolv.conf

Et voilà l'environnement est fin près.

Mais pour automatiser tout ça, il suffit de lancer:

# mkarchroot -r bash /home/chroot_env
mounting sysfs : /sys
mounting procfs : /proc
binding device nodes : /dev
binding pacman cache : /var/cache/pacman
copying mtab : /etc/mtab
copying resolv.conf : /etc/resolv.conf
starting chroot (bash)
[root@host /]# 


mkarchroot reprend en plus /var/cache/pacman qui n'est pas nécessaire mais qui permet si vous êtes sur un environnement de même architecture de ne pas télécharger une deuxième fois les paquets lors d'installation dans le chroot.

Avec tout ceci, on peut facilement compiler pour du 32bits par exemple alors qu'on est en 64, tester une application sans pour autant perturber notre machine et bien d'autres utilisations.