chroot est une commande permettant de lancer une commande en modifiant l'emplacement du répertoire racine. Ainsi, si l'on choisit comme répertoires racine /usr/local/jail, lorsque l'utilisateur tapera "cd /" il arrivera dans ce qui est pour lui la racine (la commande pwd lui retournera bien /), alors qu'en réalité il sera dans /usr/local/jail. Il ne pourra donc pas accéder à la vraie racine du serveur.
Objectif : permettre à un utilisateur d'accéder à un système Linux de manière étanche avec le reste du système tout en lui permettant d'accéder à certaines ressources ou services, comme par exemple la possibilité de se connecter en ssh et d'utiliser sftp.
En pratique, on obligera l'utilisateur à s'emprisonner lui-même dans un environnement "prison" que l'on aura préparé spécialement pour lui 🙂
Cette note sera découpée en deux grandes parties : la création de la prison et de son environnement, puis la création des utilisateurs de cette prison.
Logiciels utilisés : chroot, OpenSSH 4
Système d'exploitation : RedHat EL 5, Linux 2.6.x
1 – Création de l'environnement prison
1.1 – Création d'un volume logique
Cette étape est facultative, elle permet, pour ceux qui utilisent du LVM sur leur machine, de créer un volume logique dédié à la prison afin de la séparer des autres volumes logiques (et ainsi éviter qu'un utilisateur sature un volume logique qui sert à autre chose).
Nous créerons ici un volume logique nommé lv_jail dans le groupe de volume rootvg, d'une taille de 2 Gio.
Pour voir la liste de vos groupes de volumes, ainsi que la place disponible, tapez la commande vgdisplay :
$ vgdisplay
--- Volume group ---
VG Name rootvg
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 19
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 17
Open LV 17
Max PV 0
Cur PV 1
Act PV 1
VG Size 67.69 GB
PE Size 32.00 MB
Total PE 2166
Alloc PE / Size 874 / 27.31 GB
Free PE / Size 1292 / 40.38 GB
VG UUID xxx
Création du volume logique :
$ lvcreate -L 2G -n lv_jail rootvg
Création d'un système de fichiers ext3 sur ce volume logique :
$ mkfs.ext3 /dev/rootvg/lv_jail
Création du point de montage :
$ mkdir -vp /usr/local/jail
Insertion d'une nouvelle ligne à la fin du fichier /etc/fstab, pour remontée automatique du système de fichiers au démarrage :
$ vi /etc/fstab
/dev/rootvg/lv_jail /usr/local/jail ext3 defaults 1 2
Attention : on aura besoin de créer des devices, donc pas d'option nodev pour ce montage !
Montage du système de fichiers ainsi créé :
$ mount /usr/local/jail
Voilà, on dispose maintenant d'un répertoire de base pour notre environnement prison.
1.2 – Création du groupe
Nous allons maintenant créer un groupe dans lequel nous mettrons les futurs utilisateurs. Ce groupe sera autorisé à utiliser les commandes chroot et su via sudo.
Création du groupe jail avec le gid 60000 :
$ groupadd -g 60000 jail
Ajout de l'autorisation à la fin du fichier /etc/sudoers :
$ vi /etc/sudoers
%jail ALL=NOPASSWD: /usr/sbin/chroot, /bin/su
1.3 – Création des répertoires
Nous allons maintenant créer les répertoires de base de l'environnement. Cet environnement étant considéré comme la racine du système par les futurs utilisateurs, il faut donc qu'il y retrouve les classiques répertoires tels que /etc, /home, /dev, etc.
Création des répertoires :
$ mkdir -vp /usr/local/jail
$ cd /usr/local/jail
$ mkdir -vp bin dev etc home lib usr/lib
Remarque : si vous êtes en 64 bits, il faut créer les répertoires /lib64 et /usr/lib64 à la place de /lib et /usr/lib. Pour savoir si vous êtes en 64 bits, tapez la commande uname -i
1.4 – Création des devices
Nous aurons besoin ici de deux devices : null et tty, que nous créerons grâce à la commande mknod :
$ mknod /usr/local/jail/dev/null c 1 3 -m 666
$ mknod /usr/local/jail/dev/tty c 5 0 -m 666
$ chgrp tty /usr/local/jail/dev/tty
1.5 – Création du shell utilisateur
Habituellement, lorsqu'un utilisateur se connecte, la première chose qu'il lance après la phase d'authentification est un shell (par exemple, le shell bash).
Ici, lorsque nous créerons plus tard un utilisateur, on l'obligera non pas à exécuter un shell classique à la connexion mais à exécuter notre propre script, qui se chargera de faire le chroot à travers un sudo.
Création du fichier /bin/chroot_shell :
$ vi /bin/chroot_shell
#!/bin/bash
/usr/bin/sudo /usr/sbin/chroot /usr/local/jail /bin/su $USER "$@"
Le script déplace la racine dans /usr/local/jail puis effectue une connexion de l'utilisateur dans ce répertoire "prison". Tout ça à travers un sudo, puisque c'est l'utilisateur lui-même qui réalisera cette opération.
1.6 – Ajout des commandes utiles
A ce stade, si un utilisateur se connectait dans cet environnement prison, il n'aurait accès à aucune commande. Charge à nous donc de mettre en place les commandes de base.
Une commande est représentée par un fichier, par exemple quand on tape ls on exécute en fait /bin/ls. Mais copier ce fichier dans notre environnement ne suffirait pas. En effet, comme nous avons créer cet environnement à partir de rien, il n'y a même pas de librairies. Or, toute commande a généralement besoin de librairies.
De quelles librairies a besoin une commande ? Pour le savoir c'est très simple, il suffit d'utiliser la commande ldd. Cette commande affiche toutes les librairies, avec leur emplacement, dont une commande est dépendante. Par exemple, pour la commande ls :
$ ldd /bin/ls
librt.so.1 => /lib64/librt.so.1 (0x0000003c59000000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003c59800000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003c58000000)
libc.so.6 => /lib64/libc.so.6 (0x0000003c57800000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003c58800000)
/lib64/ld-linux-x86-64.so.2 (0x0000003c57400000)
libattr.so.1 => /lib64/libattr.so.1 (0x0000003c59c00000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003c57c00000)
libsepol.so.1 => /lib64/libsepol.so.1 (0x0000003c58400000)
Si on veut mettre une commande à disposition de l'utilisateur, il faut donc y copier le fichier, mais aussi toutes les librairies associées, dans les répertoires correspondants (à savoir le même répertoire prefixé de /usr/local/jail) :
$ cp -vp /bin/ls /usr/local/jail/bin/ls
$ cp -vp /lib64/librt.so.1 /usr/local/jail/lib64/librt.so.1
$ cp -vp /lib64/libacl.so.1 /usr/local/jail/lib64/libacl.so.1
$ ...
Bon, c'est un peu fastidieux 🙂 Voici donc un petit script pour faire ça rapidos :
#!/usr/bin/ksh command="/bin/bash /bin/su /usr/bin/id /usr/libexec/openssh/sftp-server" jail="/usr/local/jail" for cmd in $command do echo "Ajout de $cmd" mkdir -p ${jail}$(dirname $cmd) cp -p $cmd ${jail}${cmd} for lib in `ldd $cmd | awk '{if ($2 == "=>") {print $3} else {print $1}}'` do mkdir -p ${jail}$(dirname $lib) cp -p $lib ${jail}${lib} done done
A noter : la liste de commandes présentée ici est une liste minimale à mettre en place. A vous d'ajouter à cette liste les autres commandes qui vous semblent utiles (ls, grep, cat, etc.)
A noter : sftp-server sera utilisé pour que les utilisateurs puissent faire du sftp vers la machine. Cette commande peut être ailleurs, à voir dans le fichier de configuration d'OpenSSH (fichier sshd_config, paramètre subsystem)
1.7 – Copie des fichiers utiles
Pour le bon fonctionnement de l'environnement, il est nécessaire de rajouter un certain nombre de fichiers comme des librairies ou des fichiers de configuration.
Copie des librairies utiles :
$ cp -p /lib/libnss* /usr/local/jail/lib/
$ cp -Rp /lib/security /usr/local/jail/lib/
$ cp -p /usr/lib/libcrack.so* /usr/local/jail/usr/lib
A noter : si vous êtes en 64 bits, remplacer lib par lib64
Copie des fichiers de configuration :
$ mkdir -p /usr/local/jail/etc/pam.d
$ cp -p /etc/pam.d/su-l /usr/local/jail/etc/pam.d
$ cp -p /etc/pam.d/su /usr/local/jail/etc/pam.d
$ cp -p /etc/pam.d/system-auth /usr/local/jail/etc/pam.d
$ cp -p /etc/pam.d/other /usr/local/jail/etc/pam.d
$ mkdir -p /usr/local/jail/etc/security
$ cp -p /etc/security/limits.conf /usr/local/jail/etc/security
$ cp -p /etc/bashrc /usr/local/jail/etc
$ cp -p /etc/ld.so.cache /usr/local/jail/etc
$ cp -p /etc/localtime /usr/local/jail/etc
$ cp -p /etc/nsswitch.conf /usr/local/jail/etc
$ cp -Rp /etc/profile.d/ /usr/local/jail/etc
$ mkdir -p /usr/local/jail/etc/security/limits.d
$ cp -p /etc/security/limits.d/ termcap /usr/local/jail/etc/security/limits.d
Copie des fichiers terminfo (informations sur les types de terminaux), utile pour le confort de certaines commandes comme less :
$ mkdir -p /usr/local/jail/usr/share
$ cp -Rp /usr/share/terminfo /usr/local/jail/usr/share
A noter : cette liste de fichiers peut être différente selon votre environnement. Si elle n'est pas suffisante chez vous, l'utilisation de la commande strace vous permettra de connaître les fichiers manquants.
L'environnement prison est maintenant fin prêt pour accueillir nos futurs utilisateurs 🙂
2 – Création d'un utilisateur
La création d'un nouvel utilisateur évoluant dans notre environnement prison se déroulera en 3 étapes :
- création classique de l'utilisateur
- attribution d'un mot de passe
- insertion de l'utilisateur dans l'environnement prison
2.1 – Création classique de l'utilisateur
La création de l'utilisateur se fera de manière classique avec la commande useradd à la différence près que, contrairement à un utilisateur classique, celui-ci n'aura pas un shell tel que /bin/bash mais le shell personnalisé que nous avons créé précédemment.
Cet utilisateur doit également appartenir au groupe jail, groupe créé dans le chapitre précédent.
Création de l'utilisateur toto possédant l'UID 60001 :
$ useradd -u 60001 -g jail -d /usr/local/jail/home/toto -s '/bin/chroot_shell' -c 'user in jail' toto
2.2 – Attribution d'un mot de passe
L'attribution d'un mot de passe à l'utilisateur se fait tout simplement grâce à la commande passwd :
$ passwd toto
2.3 – Insertion de l'utilisateur dans l'environnement prison
L'insertion de l'utilisateur ainsi créé dans l'environnement prison se fera par son insertion dans les fichiers de configuration classiques tels que passwd, group et shadow. Mais pas les fichiers du système, ceux de l'environnement prison.
Ajout dans le fichier passwd :
$ echo "toto:x:60001:60000:user in jail:/home/toto:/bin/bash" >> /usr/local/jail/etc/passwd
$ chmod 644 /usr/local/jail/etc/passwd
Ajout dans le fichier group :
$ grep "^jail:" /etc/group >> /usr/local/jail/etc/group
$ chmod 444 /usr/local/jail/etc/group
Ajout dans le fichier shadow :
$ grep "^toto:" /etc/shadow >> /usr/local/jail/etc/shadow
$ chmod 400 /usr/local/jail/etc/shadow
On remarquera ici que, dans le fichier passwd, on donne maintenant un shell classique à l'utilisateur : en effet, lorsque celui-ci arrive dans l'environnement prison, c'est comme s'il arrivait dans un environnement "normal". Il ne se rend pas compte qu'en fait le /bin/bash qu'il utilise est, en réalité, le fichier /usr/local/jail/bin/bash 🙂
3 – Donner accès à certains répertoires
Vous souhaitez, par exemple, qu'un utilisateur emprisonné puisse lire les fichiers de logs présents dans /monAppli/logs. Cette arborescence étant hors de sa portée, il ne pourra pas y accéder.
Une solution pour lui donner accès est de monter ce répertoire dans notre environnement prison. Pour cela, on utilisera l'option bind de la commande mount :
$ mkdir /usr/local/jail/logs_monAppli
$ mount -o bind /monAppli/logs /usr/local/jail/logs_monAppli
Le répertoire /monAppli/logs sera ainsi visible par l'utilisateur emprisonné, qui y accédera via /logs_monAppli.
Conclusion
Voilà, notre environnement prison est en place, et un utilisateur a été créé. Cet utilisateur peut se connecter à la machine via SSH où utiliser des outils tels que WinSCP pour récupérer des fichiers.
Ici, tout à été fait à la main dans le but d'expliquer étape par étape. Bien sur, tout ceci peut être mis dans deux scripts : un pour la création de l'environnement, l'autre pour la création d'un utilisateur. Il sera ainsi très facile d'ajouter des utilisateurs à cet environnement !
Leave a Reply