Créer CHROOT SSH limité simplement

Je voulais me créer un mémo et me suis dit que je ne serais peut être pas le seul dans cette situation alors on va faire partager :)

Mon problème de base était de créer une sorte d’hébergement pour un de nos partenaires, la partie configuration apache restait bien évidemment sous notre responsabilité, mais ils devaient être capables de mettre leur site en production simplement. Pour ceci ils avaient juste besoin de RSYNC, et c’est tout ce qu’on va leur donner.

Pour ceux du fond près du radiateur, un CHROOT est un environnement cloisonné dont un utilisateur ne pourra pas sortir, et qui peut offrir des services limités.

Création du CHROOT

Premièrement allez dans le dossier dans lequel votre utilisateur va être enfermé, ici nous dirons que c’est /home/chroot.

Dans ce dossier il va falloir créer une sorte de mini-linux, en copiant les librairies nécessaires aux commandes que l’utilisateur pourra effectuer. Pour ceci, pas d’inquiétude, c’est scripté.

Le principe est très simple, on a une liste de commandes que vous souhaitez permettre (APPS), on vérifie les librairies nécessaires à ces scripts (LDD) et on les copie dans notre chroot:

A noter que je n’ai aucun mérite, c’est une version simplifiée de ce script.

#!/bin/bash

mkdir -p {bin,dev,lib,lib64}
mknod dev/null c 1 3
mknod dev/zero c 1 5
chmod 0666 dev/{null,zero}

TMPFILE1=./temp1
TMPFILE2=./temp2

APPS="/bin/bash /bin/cp /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /usr/bin/id /usr/bin/rsync /usr/bin/scp /usr/bin/wget /usr/bin/vim /usr/bin/vi /bin/cat /bin/less /usr/bin/tail /usr/bin/clear /bin/chmod"

for app in $APPS;  do
	if [ -x $app ]; then
		app_path=`dirname $app`
		if ! [ -d .$app_path ]; then
		    mkdir -p .$app_path
		fi
		cp -p $app .$app
		ldd $app >> ${TMPFILE1}
	fi
done

for libs in `cat ${TMPFILE1}`; do
   	frst_char="`echo $libs | cut -c1`"
   	if [ "$frst_char" = "/" ]; then
   	  	echo "$libs" >> ${TMPFILE2}
   	fi
done

for lib in `cat ${TMPFILE2}`; do
    	mkdir -p .`dirname $lib` > /dev/null 2>&1
    	cp $lib .$lib
done

cp -r /lib/terminfo ./lib/

rm -f $TMPFILE1
rm -f $TMPFILE2

Un point intéressant à noter est la copie de /lib/terminfo. Le problème est simple, certaines des commandes que j’ajoute (clear, less) interragissent avec le terminal et renverront une erreur de ce type:

user@computer:$ clear
'xterm': unknown terminal type
user@computer:$ less test.txt
WARNING: terminal is not fully functional

Configuration de SSH

Votre environnement est désormais prêt, il ne reste plus qu’à enfermer un utilisateur dans ce CHROOT grâce à OPENSSH. Pour cela il suffit de se rendre dans /etc/ssh/sshd_config et rajouter ce qui suit à la fin du fichier:

user@computer:$ vim /etc/ssh/sshd_config
[...]
Match User rootlab
ChrootDirectory /home/chroot
AllowTCPForwarding no
X11Forwarding no

Si ce n’est pas fait créez votre utilisateur, faites attention au home de l’utilisateur, pour lui la racine « / » est /home/chroot

user@computer:$ useradd -s /bin/bash -d / -p super_passwd rootlab

Bien entendu redémarrez openssh

user@computer:$ /etc/init.d/ssh restart

Et voilà! à sa prochaine connexion, votre utilisateur rootlab sera incapable de sortir du dossier /home/chroot et il aura un shell très limité.

Articles similaires :

    • cedric
    • 20 septembre 2012 4:07

    Bonjour,
    ayant exactement les memes besoins, j’ai essayé mais il reste un probleme que je n’identifie pas, j’ai du changer dans sshd_config : UsePrivilegeSeparation no. sans quoi j’etais mis dehors. Maintenant je suis toujours mis dehors mais avec un message dans les logs: bad ownership or modes for chroot directory. J’ai essayé de modifier les droits du repertoir, mais pas de changements…

    avez vous une idée?

      • cedric
      • 20 septembre 2012 4:29

      les droits:
      755 sur /home/chroot avec chown root:rootlab

      mettre dedans un répertoire appartenant a rootlab

    • Zoddo
    • 25 mai 2013 12:50

    Bonjour,
    J’ai un problème : les liens symboliques qui pointes en dehors du home de l’utilisateur sont inaccessibles.

    -bash-4.2$ cd ./update
    -bash: cd: ./update: No such file or directory
    -bash-4.2$ ls -n
    total 0
    lrwxrwxrwx 1 0 0 15 May 25 10:46 update -> /var/www/update

    • Bonjour,

      C’est normal que les liens qui pointent en dehors ne fonctionnent pas, vu que l’utilisateur n’a pas accès en dehors. Pour permettre cela, il faut soit faire un montage « –bind » du répertoire concerné afin de le rendre accessible dans le chroot, soit faire pointer chroot sur le répertoire parent de la cible, soit ne pas utiliser chroot.

    • Julien Fastré
    • 10 février 2014 10:37

    Bonjour,

    Merci pour ce billet, j’ai, en effet, le même besoin :-)

    Pourriez-vous me dire où et sous quel nom j’enregistre le fichier du script que vous proposez ?

    Merci !

    • Bonjour,
      Vous pouvez enregistrer le script sous n’importe quel nom, il faudra ensuite lui donner les droits d’exécution, par exemple si vous l’appelez jail.sh:
      # chmod +x jail.sh
      Et pour exécuter le script, placez vous dans le même dossier puis:
      # ./jail.sh

  1. Aucun trackback pour l'instant