Chrooter un utilisateur

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 :

  1. création classique de l'utilisateur
  2. attribution d'un mot de passe
  3. 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 !

Laisser un commentaire