Copyright © 2003 Yves Mettier
L'article original se trouve sur http://ymettier.free.fr/articles_lmag/.
Article publié dans le numéro 54 (octobre 2003) de GNU/Linux France Magazine
Table des matières
Installer un environnement chrooté, cela veut tout dire et rien du tout. Concrètement, il s'agit d'installer le nécessaire pour qu'un programme puisse se lancer avec chroot. Qu'est-ce que chroot ? C'est un programme qui change la racine du système de fichiers pour y exécuter un programme spécifié. En réalité, chroot est un appel système, que vous pouvez faire en appelant la fonction chroot() en C par exemple. Et le programme chroot effectue cet appel système. Mais nous ne somme pas ici pour programmer, donc nous utiliserons le programme chroot.
Essayons un peu...
# mkdir /mnt/chroot # mkdir /mnt/chroot/bin # cp /bin/bash /mnt/chroot/bin # chroot /mnt/chroot /bin/bash
Ceci devrait lancer un bash, dans lequel nous ne verrions que /bin/bash dans le système de fichiers. Et si vous essayez, cela ne marche pas.
# chroot /mnt/chroot/ /bin/bash chroot: /bin/bash: No such file or directory
Cet article va vous expliquer comment monter cet environnement pour exécuter bash et quelques commandes. Les problèmes rencontrés engendrent des messages que l'on retrouve sur ma machine de test: Mandrake Cooker, mais ces problèmes sont les mêmes sur une Debian Woody qui m'a servi à vérifier qu'ils n'étaient pas spécifiques à Mandrake. De plus l'article suivant, comme vous le verrez, utilise une Debian comme distribution sur la machine de test.
L'intérêt d'avoir un tel environnement chrooté est grand, et varie suivant les utilisations. En général, cela rajoute un élément de sécurité, car on y fait tourner des serveurs. En cas de faille dans le programme serveur, un pirate peut devenir l'utilisateur qui fait lancer le programme. Et tant que le pirate n'est pas root, il reste dans cet environnement où il dispose de peu de choses. Entre autres, il n'a aucune visibilité sur l'ensemble du système puisque la visibilité se limite à l'environnement chroot (et un peu plus, comme nous le verrons plus loin, mais peu quand même).
Mais attention, chroot n'a pas été prévu pour la sécurité. Chroot ne fait que changer la racine du système de fichiers. Le fait que cela améliore la sécurité est un effet de bord. La sécurité est donc un peu améliorée, mais sachez qu'il suffit de devenir root pour pouvoir à nouveau changer la racine du système de fichiers. Et même sans être root en utilisant certaines failles...
La raison pour laquelle bash n'a pas voulu se lancer est la suivante: /bin/bash est dynamiquement lié à certaines bibliothèques. Il s'agit donc de trouver lesquelles, de les copier au bon endroit dans la nouvelle racine /mnt/chroot, et de recommencer. Pour cela, ldd est notre ami:
# ldd /bin/bash libtermcap.so.2 => /lib/libtermcap.so.2 (0x40020000) libdl.so.2 => /lib/libdl.so.2 (0x40025000) libc.so.6 => /lib/i686/libc.so.6 (0x40029000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Copions ces fichiers, et les fichiers sur lesquels ils pointent quand il s'agit d'un lien, au bon endroit (vérifiez comme moi que vous n'en copiez pas trop quand vous mettez une étoile) :
cp /lib/libtermcap.so* /mnt/chroot/lib cp /lib/libdl* /mnt/chroot/lib cp /lib/libc.so* /mnt/chroot/lib cp /lib/libc-* /mnt/chroot/lib cp /lib/ld* /mnt/chroot/lib
Et maintenant, recommençons:
# chroot /mnt/chroot/ /bin/bash [I have no name!@localhost /]#
Cela a marché! Allons plus loin pour vérifier que nous sommes bien à la nouvelle racine:
[I have no name!@localhost /]# ls bash: ls: command not found
Dommage, cela semblait si simple, finalement!
... et pourtant, c'est si simple. Le problème que nous venons de rencontrer est que ls n'existe pas sur la nouvelle racine. Cela indique que nous avons de grandes chances de nous trouver effectivement sur la nouveller racine. Ne soyons pas catégorique cependant: une variable $PATH mal positionnée et nous avons la même erreur.
L'installation des programmes dans la nouvelle racine part toujours de la même manière. On copie le programme dans la nouvelle racine au même endroit qu'à sa place initiale. Et on regarde de quelles bibliothèques il a besoin. Il peut arrive qu'une bibliothèque aie besoin d'une autre. Il faut aussi regarder pour les bibliothèques, avec ldd aussi. Une autre méthode consiste à copier le programme et à le tester dans l'environnement chrooté, et à copier les bibliothèques jusqu'à ce qu'il fonctionne. Un peu de pratique avec ls:
# cp /bin/ls /mnt/chroot/bin/ # ldd /bin/ls libtermcap.so.2 => /lib/libtermcap.so.2 (0x40020000) libc.so.6 => /lib/i686/libc.so.6 (0x40025000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Ici, tout va bien, les bibliothèques sont déjà installées. Vous n'avez plus qu'à vous remettre dans l'environnement chrooté et à lancer ls:
# chroot /mnt/chroot/ /bin/bash [I have no name!@localhost /]# ls bin lib
Je vous conseille de copier non seulement ls comme nous avons vu, mais les outils de base de gestion des fichiers, comme cat, more, cp, mv, rm et mkdir. Ceci vous permettra de monter votre environnement chrooté facilement. Par contre, si l'objectif est ensuite d'améliorer la sécurité, de protéger un démon, vous veillerez à supprimer ces outils qui ne sont pas nécessaires, voire autant d'outils qui aideront un éventuel pirate à briser les protections.
Un programme un peu plus gros sera le démon sshd, qui lorsqu'il tournera, nous permettra de venir dans l'environnement chrooté non pas avec chroot, mais avec ssh. L'intérêt est grand: n'importe quel utilisateur pourra venir dans l'environnement chrooté! Pour votre information personnelle, si vous voulez juste installer un démon sshd, sachez qu'il est capable de faire appel à chroot() tout seul. Pas besoin de l'environnement chrooté. Voyez la documentation de sshd. Mais l'intérêt est ici de voir un démon qui a besoin du réseau, de la gestion des utilisateurs, et qui montre bien, une fois qu'il tourne, qu'on est bien dans un environnement chrooté. De plus, il n'est pas trop long à installer. C'est pour cela que j'ai choisi ce démon.
Gardons la méthode: on copie le binaire dans la nouvelle racine, on regarde ses dépendances en terme de bibliothèques, et on les recopie.
# mkdir -p /mnt/chroot/usr/sbin # cp /usr/sbin/sshd /mnt/chroot/usr/sbin # ldd /usr/sbin/sshd libpam.so.0 => /lib/libpam.so.0 (0x40020000) libdl.so.2 => /lib/libdl.so.2 (0x40029000) libutil.so.1 => /lib/libutil.so.1 (0x4002d000) libz.so.1 => /lib/libz.so.1 (0x40030000) libnsl.so.1 => /lib/libnsl.so.1 (0x4003e000) libcrypto.so.0.9.7 => /usr/lib/libcrypto.so.0.9.7 (0x40052000) libc.so.6 => /lib/i686/libc.so.6 (0x40140000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) # cp /lib/libpam.so* /mnt/chroot/lib # cp /lib/libutil.so* /mnt/chroot/lib # cp /lib/libz.so* /mnt/chroot/lib # cp /lib/libnsl.so /mnt/chroot/lib # mkdir -p /mnt/chroot/usr/lib # cp /usr/lib/libcrypto.so.0.9.7 /mnt/chroot/usr/lib # chroot /mnt/chroot /usr/sbin/sshd -p 2002 PRNG is not seeded
La méthode ne change pas par rapport à ce que nous avons vu avec ls. Et on lance sshd. Comme sshd tourne peut-être déjà sur le port 22 (voyez votre fichier /etc/services), nous le faisons tourner sur un autre port, ici 2002 (pris au hasard). Cela ne marche pas, et les choses sérieuses commencent ici.
Ici, je pourrais vous dire qu'il manque /dev et son contenu, /etc et quelques fichiers ou encore /proc. Je n'ai pas envie de vous présenter cela comme si c'était un didacticiel. Nous allons choisir la méthode hacker pour résoudre les problèmes: identification, recherche d'une solution et résolution.
Pour identifier les problèmes, il y a trois méthodes assez intéressantes ici. La première que nous allons mettre en oeuvre est de regarder ce qui manque probablement, entre autres une arborescence unix minimale. La seconde qui doit toujours être mise en oeuvre, quelle que soit la situation et quel que soit le problème est d'aller voir dans les logs ou d'utiliser le mode verbeux des programmes quand il existe. D'ailleurs, revenons à la première méthode: il manque déjà le répertoire /var/log. Troisième méthode assez intéressante aussi: l'utilisation de strace. Ce programme nous indique principalement tous les accès aux fichiers.
Créons tout d'abord une arborescence unix/linux digne de ce nom. Il nous faut généralement les répertoires suivants:
/bin /dev /etc/ /home /lib /proc /sbin /tmp /usr /usr/bin /usr/lib /usr/sbin /var /var/log
A nouveau, si l'objectif est la sécurité, vous veillerez à supprimer ensuite tout ce qui est non utile.
Pas besoin d'être devin pour se douter que /dev doit être rempli un minimum. Sur un système sans devfs tel que debian woody, utilisez MAKEDEV:
# cd /mnt/chroot/dev # /dev/MAKEDEV std
Voyez la page de manuel de MAKEDEV pour en savoir plus sur ce que l'on peut créer. Simplement std permet de créer un jeu de devices standard, la base pour fonctionner. Avec cela, vous devriez avoir ce qu'il faut pour démarrer sans avoir trop de problèmes. Je reviens à nouveau sur l'aspect sécurité: avec ceci, vous en avez largement trop et si vous gardez tout, vous facilitez la tâche aux pirates si l'objectif est d'améliorer la sécurité. Donc ici, faites le ménage une fois que cela marche si vous voulez protéger l'environnement.
Sur un système fonctionnant avec devfs, il faudrait faire tourner un démon devfsd sachant créer les devices dans /mnt/chroot/dev de la même manière qu'il le fait dans /dev. Il y a une manière plus simple de faire: monter /dev sur /mnt/chroot/dev. Avec les noyaux récents, une options de mount est apparue; elle permet de monter un répertoire sur un point de montage. Cela ressemble à la création d'un partage de répertoire pour ceux qui connaissent NFS, et ensuite à un montage de ce répertoire partagé. Mais il n'y a rien de réseau là dessous. Depuis la racine (pas l'environnement chrooté), faites:
# mount -o bind /dev /mnt/chroot/dev
En ce qui concerne /proc, il est généralement inutile. En l'occurence, avec sshd, il est inutile. Pourtant, dans certains cas, il peut s'avérer nécessaire. Il faudra alors le monter. Mais dans ce cas, sachez qu'un pirate vous sera particulièrement reconnaissant de lui donner accès à /proc, encore une fois si l'objectif est la sécurité.
Ici, nous allons tout simplement le monter de la manière la plus classique qu'il soit, depuis l'environnement chrooté. Pour que ce soit encore plus facile, remarquez qu'il manque le fichier /etc/fstab que nous allons en profiter pour éditer:
# chroot /mnt/chroot /bin/bash # cat /etc/fstab bash, cat, command not found # cat /etc/fstab none /dev/pts devpts mode=0620 0 0 none /proc proc defaults 0 0 # mount /proc bash, mount, command not found # mount /proc
Eh oui, il manquait cat et mount que j'ai recopiés, dans une autre fenêtre, au bons endroits, et c'est pour cela que ca marche du second coup. J'ai aussi installé umount pour démonter /proc avant de quitter l'environnement chrooté. Dans /etc/fstab, mettez tout ce qui peut vous arranger pour de futurs montages à l'intérieur de l'environnement chrooté.
Recommençons à lancer sshd comme nous l'avons fait. S'il n'est toujours pas content et continue à parler de PRNG not seeded, nous irons voir ce que cela veut dire dans la documentation de sshd, les FAQ ou nous utiliserons d'autres moyens de nous documenter.
# chroot /mnt/chroot /bin/bash # mount /proc # /usr/sbin/sshd -p 2002 /etc/ssh/sshd_config: No such file or directory
Le message d'erreur à changé, donc pas besoin de se casser la tête à comprendre d'où venait le problème de PRNG. Petite digression en ce qui concerne le précédent message. PRNG is not seeded est un message de sshd pour indiquer qu'il n'a pas de moyen de générer des nombres aléatoires digne de ce nom. Sur GNU/Linux, /dev/random suffit amplement et c'est pour cela que nous n'avons plus le problème. Sur Solaris, il faut installer un générateur de nombres aléatoires en plus. Fin de la digression.
Le message d'erreur actuel est que sshd ne trouve pas ses fichiers de configuration. Cela est simple: je vous laisse recopier les fichiers nécessaires de /etc/ssh vers /mnt/chroot/etc/ssh.
Recommencez. Le message est maintenant:
# /usr/sbin/sshd -p 2002 Privilege separation user sshd does not exist
Si cela ne vous dit pas grand chose, au moins, cela doit vous faire penser que nous n'avons pas de /etc/passwd, /etc/group ni /etc/shadow. Ici encore, il suffit de les recopier. Pour améliorer la sécurité, ne gardez que les utilisateurs dont vous avez besoin, à savoir root, sshd et un utilisateur si besoin.Evitez par contre de modifier les uid/gid si vous n'avez pas de bonne raison de le faire. En effet, c'est plus facile hors du chroot de savoir à qui appartiennent les fichiers créés à l'interieur de l'environnement chrooté. Et hop, on recommence. Et hop, on retrouve le même message d'erreur.
Passons à la vitesse supérieure: lançons sshd en mode debug
# /usr/sbin/sshd -d -d -d -p 2002 debug2: read_server_config: filename /etc/ssh/sshd_config debug1: sshd version OpenSSH_3.6.1p2 debug1: private host key: #0 type 0 RSA1 debug3: Not a RSA1 key file /etc/ssh/ssh_host_rsa_key. debug1: read PEM private key done: type RSA debug1: private host key: #1 type 1 RSA debug3: Not a RSA1 key file /etc/ssh/ssh_host_dsa_key. debug1: read PEM private key done: type DSA debug1: private host key: #2 type 2 DSA Privilege separation user sshd does not exist
Pas moyen d'en savoir beaucoup à partir de cela, et pas moyen non plus d'en savoir plus avec la log: il n'y en a tout simplement pas. Nous devons passer à une vitesse encore supérieure et utiliser strace. Installez-le comme vous avez installé les autres binaires (vérifiez les bibliothèques avec ldd).
# strace /usr/sbin/sshd -d -p 2002 [...] open("/etc/nsswitch.conf", O_RDONLY) = -1 ENOENT (No such file or directory) [...]
Je n'ai pas fait une lecture attentive de la sortie, mais quelques lignes avant la fin, on repère sans trop de difficultés qu'il manque ce fichier /etc/nsswitch.conf. Il suffit de le rajouter comme d'autres déjà.
Je vais faire une nouvelle digression sur les bibliothèques partagées et le chargeur dynamique. Apres le message concernant /etc/nsswitch.conf, voici ce qui apparaît chez moi:
open("/lib/libnss_compat.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/libnss_compat.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/libnss_files.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
Ce genre de message se trouve souvent, et vous pouvez le trouver dès le début ou plus loin. Exemple (extraits):
open("/lib/libcrypto.so.0.9.7", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/i686/libcrypto.so.0.9.7", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/libcrypto.so.0.9.7", O_RDONLY) = 3
Quand cela marche, le chargeur cherche dans plusieurs répertoires (ceux qui sont dans /etc/ld.so.conf; d'ailleurs, il est manquant, mais certains chemins comme /lib et /usr/lib sont déjà pris par défaut). Et lorsqu'il a trouvé le fichier contenant la bibliothèque partagée, il s'arrête et on passe à d'autres messages. Quand cela ne marche pas, vous avez un exemple avec libnss_files.so et libnss_compat.so qui sont manquantes aussi. Encore deux fichier manquants: veuillez les installer!
Essayons à nouveau... Cela marche! Il ne reste plus qu'à se connecter depuis ailleurs. Et là, déception: le serveur sshd s'arrête après refus de connexion.
Vous avez maintenant compris la méthode: lorsque les messages d'erreurs ne suffisent pas à dire ce qu'il manque, on utilise strace. On recommence avec strace ici comme ci-dessus. Puis on se logue depuis ailleurs, ce qui nous rajoute quelques messages du côté de strace avant l'arrêt/plantage de sshd. A la fin, nous avons un message indiquant qu'il manque /etc/localtime:
open("/etc/localtime", O_RDONLY) = -1 ENOENT (No such file or directory)
Vous pouvez copier le fichier comme on a fait déjà, mais ce serait intéressant de savoir ce qu'est ce fichier qui est plutôt binaire. Ce fichier n'est rien d'autre qu'un lien ou une copie d'un fichier que l'on peut trouver dans /usr/share/zoneinfo. C'est le fichier qui décrit le fuseau horaire où l'on se trouve. Ainsi, si vous habitez la Bretagne, le fuseau horaire est celui de Paris puisqu'on trouve aussi des bretons dans le quartier Edgar Quinet à Montparnasse entre autres (je ne suis pas très sur pour mon explication sur les fuseaux horaires), et il vous suffit donc de copier /usr/share/zoneinfo/Europe/Paris dans /mnt/chroot/etc.
Pourtant, cela ne change pas grand chose à notre problème qui se situe ailleurs. Voici deux des messages vers la fin:
stat64("/etc/pam.d", 0xbfffeea0) = -1 ENOENT (No such file or directory) open("/etc/pam.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
Voyons ce que l'on trouve dans /etc/pam.d quand on n'y connaît rien à PAM. On y trouve des fichiers texte, qui contiennent des règles d'authentification. Effectivement, PAM signifie bien Pluggable Authentification Modules. Donc c'est tout simple, c'est comme pour le reste: il suffit de copier les fichiers. Et si vous vous amusez à essayer à nouveau, vous devriez avoir du nouveau: on va vous demander votre mot de passe. Mais même si vous fournissez le bon mot de passe, il vous sera impossible de vous loguer. Pour continuer, il faut en savoir plus sur les Modules d'Authentification à brancher. La page de manuel est bien faite sur Linux: outre les explications, on nous indique à la fin que nous avons oublié de copier les fichiers /usr/lib/libpam.so.X et /usr/lib/security/*.so. Sshd étant lié à libpam, nous l'avons déjà recopié. Reste /usr/lib/security/*.so. Attention, la page de manuel n'est pas forcément conforme à la réalité. En outre, Debian et Mandrake placent ces bibliothèques dans /lib/security et pas dans /usr/lib/security. Vous savez ce qu'il vous reste à faire...
...et cela ne marche toujours pas. Il faut remonter un peu plus haut dans les messages d'erreur:
open("/etc/hosts.allow", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/hosts.deny", O_RDONLY) = -1 ENOENT (No such file or directory) [... beaucoup de lignes ici ...] open("/etc/protocols", O_RDONLY) = -1 ENOENT (No such file or directory) [...] connect(3, {sa_family=AF_UNIX, path="/var/run/.nscd_socket"}, 110) = -1 ENOENT (No such file or directory) open("/etc/protocols", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/resolv.conf", O_RDONLY) = -1 ENOENT (No such file or directory) [...] open("/etc/host.conf", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/hosts", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/libnss_nisplus.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/libnss_nisplus.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/libnss_nis.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/libnss_nis.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/libnss_dns.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/libnss_dns.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
Bref, il nous manque pas mal de choses au niveau réseau. Mais rien de neuf ici: il suffit encore de copier les fichiers manquants. Attention, les fichiers /var/run/* sont un peu spéciaux. Ce sont des fichiers créés par les programmes ou les scripts qui les lancent pour indiquer qu'ils tournent, et qui servent généralement à contenir leur numéro de processus (PID). Ici, nous n'avons dont pas à créer le fichier /var/run/.nscd_socket, mais juste à nous assurer que /var/run existe et est un répertoire. Dans le même style, créez un répertoire /var/lock car certains démons ou scripts créent un fichier dans ce répertoire pour éviter qu'on le lance une seconde fois.
Par ailleurs, il est un fichier que sshd ne semble pas nécessiter, mais que d'autres programmes utilisent. C'est le fichier /etc/services, que vous pouvez aussi copier. Attention aussi à un autre fichier absent: le fichier nologin. Ce fichier doit lui, au contraire des autres, être effectivement absent. Ce fichier, lorsqu'il est présent, empêche les connexions à distance: exactement le contraire de ce que nous voulons!
Cela ne marche pas encore, toujours pas, mais ne nous decourageons pas: on est proche du bout. Sauf que... impossible de trouver ce qu'il manque maintenant. Si vous avez l'oeil, vous avez déjà repéré qu'il manque libcrypt.so et libcrack (éventuellement aussi libglib qui me semble inutile). Sinon, vous aurez peut-être fait comme moi, à savoir copié grep et la bibliothèque libpcre.so pour pouvoir les utiliser:
# strace /usr/sbin/sshd -d -p 2002 2>&1 |grep ENOENT open("/lib/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) open("/lib/libcrack.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
Et voilà, si vous les copiez, vous devriez pouvoir vous loguer après avoir relancé sshd.
Relancez sshd avec strace pour la dernière fois, par acquis de conscience. Vous devrez noter que /var/run/utmp, /var/run/utmpx, /var/log/xtmp, /var/log/wtmpx et /var/log/lastlog manquent. Ce sont des fichiers que vous devriez créer s'ils existent déjà sur votre distribution:
# touch /mnt/chroot/var/run/utmp # touch /mnt/chroot/var/log/wtmp # touch /mnt/chroot/var/log/lastlog
Maintenant que vous avez installé votre environnement chrooté, il y a au moins deux manières de l'utiliser. L'une consiste à s'y installer pour y lancer un programme, exactement de la même manière que nous avons lancé sshd ci-dessus. Seul root peut faire cela puisque chroot est limité à root pour son utilisation. Cela peut s'avérer intéressant pour certains programmes démons, tels que sshd justement, ou sendmail/postfix, des serveurs web ou ftp, des serveurs proxies et tout ce qui peut s'avérer sensible comme programme. A part sshd qui est un cas particulier, ces programmes sont utilisés dans de tels environnements chrootés quand on souhaite que si jamais un pirate réussit à s'immiscer sur le système via le programme, il se retrouve dans la prison qu'est l'environnement chrooté. S'il n'est pas root à ce moment là, il aura encore du travail. S'il est root, il pourra évidemment très facilement monter la véritable racine dans un répertoire et sortir de la prison avec un nouveau chroot qu'il aura ramené si vous ne lui en avez pas installé un:
# MAKEDEV generic (inutile si vous avez devfs et monté /dev comme expliqué ci-dessus) # mkdir /mnt/racine # mount /dev/hda1 /mnt/racine # chroot /mnt/racine /bin/bash
Voici comment sortir de la prison du chroot quand on est root. Bien entendu, trouver la partition à monter se fait un peu à tatons, et en ce qui concernes les binaires MAKEDEV, mkdir, mount et chroot, le pirate peut amener avec lui des versions statiques de ceux-ci si vous ne les avez pas installés. Pourtant, cela ne lui facilite pas la vie.
Une autre manière d'utiliser votre environnement chrooté est de permettre aux utilisateurs de travailler dessus. C'est là que se trouve tout l'intérêt d'installer sshd et de le faire tourner, comme on a fait ci-dessus. Ainsi, vous pouvez limiter vos utilisateurs au niveau de la véritable racine, mais en créer dans l'environnement chrooté. Les utilisateurs arriveront donc dans la prison de l'environnement chrooté, et ne peuvent pas faire autant de choses qu'ils le souhaiteraient, mais que celles permises par les outils que vous laissez à leur disposition.
J'ai parlé de prison plusieurs fois. Un environnement chrooté est effectivement une prison de laquelle seul root peut sortir ou s'évader. Et encore, avec un noyau sur lequel on n'a pas installé de patchs de sécurité, même pas besoin d'être root. De plus, il y a plusieurs ouvertures à connaître dans un tel environnement, ouvertures qui dans certains cas peuvent véritablement devenir des failles de sécurité. Lancez la commande ps auxwww (vous aurez bien entendu installé ps dans la prison). Vous devriez voir les processus qui tournent hors de la prison. Ainsi, on sait tout de suite que l'on a affaire à un environnement chrooté. Autre ouverture: voyez /proc. Ou encore /dev si vous utilisez devfs. Ces répertoires contiennent des informations sur le système global, tel que la charge système. On peut donc voir ce qui se passe hors de la prison, même si on ne peut pas influer dessus. Autre faille de sécurité potentielle: où se trouve votre /mnt/chroot ? Est-ce sur la même partition que /var ? Que se passe-t-il si un utilisateur ou un processus remplit complêtement l'espace disque de la prison ? Il devient impossible d'utiliser /var, ce qui peut bloquer voire planter des processus qui tournent hors de la prison. /var est un exemple systématique, mais d'autres répertoires peuvent être impactés de la même manière. Pour vous protéger de cela, vous devez au minimum mettre en place un système de quotas, et au mieux avoir une partition dédiée à la prison.
Si lancer un démon dans un environnement vraiment sécurisé vous intéresse, sachez que sur freebsd par exemple, vous pouvez utiliser jail qui lui a vraiment été conçu pour la sécurité. Ce n'est pas le cas de chroot. Mais les applications de chroot ne se limitent pas à la sécurité. Chroot peut aussi servir à simplement avoir un environnement propre à une application, qui n'interagit pas avec une autre application, le tout sur un même système.
Vous venez d'installer une prison rudimentaire avec un démon sshd qui tourne. Il ne vous reste plus qu'à aménager cette prison en fonction de vos besoin, en fonction des besoins des utilisateurs qui vont être amenés à travailler dans cette prison. Dans l'article qui suit, nous allons voir comment installer une distribution Mandrake dans un prison, prison installée sur une distribution non Mandrake.
chroot: man chroot
rpm: http://www.rpm.org
debian: http://www.debian.org
mandrake: http://www.mandrakelinux.com
easy urpmi: http://plf.zarb.org/~nanardon/
© 2003 Yves Mettier