summaryrefslogtreecommitdiff
path: root/content/Informatique/chroot.rst
diff options
context:
space:
mode:
Diffstat (limited to 'content/Informatique/chroot.rst')
-rwxr-xr-xcontent/Informatique/chroot.rst230
1 files changed, 230 insertions, 0 deletions
diff --git a/content/Informatique/chroot.rst b/content/Informatique/chroot.rst
new file mode 100755
index 0000000..ce5a733
--- /dev/null
+++ b/content/Informatique/chroot.rst
@@ -0,0 +1,230 @@
+.. -*- mode: rst -*-
+.. -*- coding: utf-8 -*-
+
+Mettre en place un environnement sftp chrooté
+#############################################
+
+:date: 2010-04-08
+:tags: Libre, Hébergement
+
+*Note* : Je propose une autre approche pour mettre en place cette
+solution :
+`mettre-en-place-un-environnement-sftp-chroote-2/ <|filename|sftp.rst>`_
+
+La demande
+~~~~~~~~~~
+
+Ma copine m'a demandé de trouver une solution simple pour échanger des
+fichier avec sa sœur, msn posant des problèmes… J'ai pensé à mon serveur
+ssh et mettre en place une connexion sftp pour ça. Sur le principe cela
+a été adopté avec une petite présentation de filezilla (je ne sais pas
+s'il existe des clients sftp intégrés sous windows ?), j'ai donc
+commencé à mettre en place le système. De mon côté, la condition
+principale est de n'autoriser les connexions que par clef publique ( pas
+de mot de passe ), ma copine a tenu à ce que sa sœur ne puisse pas
+accéder aux documents présents dans son home, et du mien à ce que l'on
+ne puisse pas pour autant se promener dans l'arborescence du serveur :
+il va donc falloir chrooter l'environnement. Il existe pas mal de
+documentation la dessus sur internet, mais je me suis souvent retrouvé
+face à des exemples incorrects ou incompatible avec le fait de passer
+par une clef publique, je vais donc détailler les problèmes rencontrés.
+
+Le compte + clef publique
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+La première étape est de créer le compte, cela se fait assez simplement
+:
+
+::
+
+ # adduser ${user}
+
+|Création de la clef ssh avec puttygen| et en répondant aux questions
+par défaut… Vient ensuite la clef publique : filezilla gère les clefs
+privés au format ppk ( putty ) et je n'ai pas trouvé d'outil pour les
+générer sous windows. Je suis donc passé par wine + puttygen pour créer
+la clef. Une fois celle-ci crée, on enregistre la partie publique et la
+partie privée de la clef. La clef publique va être enregistrée dans le
+fichier ${user}/.ssh/know\_host sur le serveur pour autoriser le client
+à s'y connecter. La clef privée sera enregistrée de son côté au format
+ppk pour être utilisée par filezilla (il est possible à partir de ce
+fichier de générer une clef privée de type openssh ).
+
+|image1|
+
+Il faut ensuite intégrer la clef privée dans filezilla en passant par
+les paramètres : elle sera automatiquement lue à la connexion ( il faut
+choisir «interactive» dans le type d'authentification ). ( Attention :
+sous windows j'ai rencontré des problèmes avec un répertoire contenant
+des accents, la clef semblait être lue, mais la connexion ne se faisait
+pas pour autant. )
+
+Chrooter l'environnement
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Aujourd'hui il est possible de chrooter nativement un environnement sftp
+avec openssh. Il faut pour cela mettre en place une condition sur
+l'utilisateur ( ou le groupe ) pour faire le chroot :
+
+::
+
+ Match user ${user}
+ ChrootDirectory /var/chroot/
+ X11Forwarding no
+ AllowTcpForwarding no
+ ForceCommand internal-sftp
+
+Dans cet exemple le chemin /var/chroot sera utilisé comme racine lors
+des connexions sftp. Ce répertoire doit être détenu par root:root et
+avoir les droits 755. Cela veut dire que si notre utilisateur à pour
+répertoire home /home/${user}, il se retrouvera dans
+/var/chroot/home/${user} lors des connexions sftp. Il est nécessaire de
+conserver le répertoire home de l'utilisateur pour que ssh accepte une
+connexion par clef. En effet, lorsque l'utilisateur va se connecter, ssh
+va lire dans son répertoire personnel pour lire le fichier
+.ssh/know\_host et autoriser ou non la clef qui se présente. Ce qui
+signifie que si l'on modifie le répertoire personnel, il faut aussi
+déplacer cette arborescence ( hors de question dans ce cas de mettre /
+comme racine de l'utilisateur ). À noter : j'ai préféré faire le match
+sur le nom de l'utilisateur plutôt que sur son groupe ( le groupe sera
+utilisé par ailleurs ). Dans le cas où nous avons plusieurs
+utilisateurs, il est possible de les mettre à la suite ( séparés par des
+virgules ). J'ai vu de nombreux tutoriaux qui indiquent comme répertoire
+de chroot « /home/%u » ( le répertoire de l'utilisateur standard ), et
+qui demandent de changer le répertoire de login de l'utilisateur par « /
+». Je pense que c'est une très mauvaise idée : d'une part parce que cela
+oblige à déposer les clefs à la racine du serveur, mais aussi à cause de
+la contrainte d'openssh demandant à ce que le répertoire root soit
+détenu par root : cela veut dire que l'utilisateur n'a pas le droit de
+déposer de fichiers ou de créer de répertoires dans son propre home ! Le
+plus simple est donc de prendre un autre répertoire pour l'échange, et
+laisser le home de l'utilisateur pour la configuration. ( Cela permet
+aussi d'être sûr que le répertoire .ssh ne sera pas effacé par erreur
+par l'utilisateur… ) J'ai donc mis un lien symbolique pour lier le /home
+de l'utilisateur avec son répertoire d'échange :
+
+::
+
+ # mkdir /home/${user}/echanges
+ # ln -s /var/chroot/home/${user} /home/${user}/echanges
+
+On retrouvera ainsi la possibilité de voir les fichiers déposés en
+passant par le /home de l'utilisateur ( même si ce dernier ne pourra pas
+y aller… )
+
+Isoler l'environnement
+~~~~~~~~~~~~~~~~~~~~~~
+
+Maintenant que nous avons empêché l'utilisateur de se balader sur
+l'ordinateur, nous allons l'empêcher de se balader dans les autres
+répertoires des utilisateurs : cela se fait en une ligne de commande
+(pour chacun des répertoires que nous allons ouvrir en sftp : )
+
+::
+
+ # for fichier in /var/chroot/home/*; do chmod o-r ${fichier}; done
+
+Et voilà ! Les utilisateurs peuvent voir qu'il existe d'autres comptes
+que le leur, mais ne peuvent pas y accéder.
+
+Autoriser le partage
+~~~~~~~~~~~~~~~~~~~~
+
+Maintenant que nous avons fermé les droits de manière générale il nous
+reste à autoriser le partage des fichiers ( après tout c'était le but de
+la demande !) de manière plus fine. Cela implique pour moi deux choses :
+
+#. permettre à un autre utilisateur d'accéder aux données présentes
+#. permettre à un autre utilisateur de déposer ( ou de supprimer des
+ donnée )
+
+Pour le premier point, c'est facile il suffit d'ajouter l'utilisateur A
+au groupe de l'utilisateur B :
+
+::
+
+ # usermod -a -G ${user} ${un_autre_utilisateur}
+
+Et l'utilsateur un\_autre\_utilisateur pourra donc accéder à l'ensemble
+des fichier pour les lire ( et éventuellement les rapatrier chez lui).
+Pour le second point ( possibilité d'écrire et modifier ) c'est un peu
+plus compliqué; en gros nous voulons que les fichiers déposés par sftp
+dans le répertoire de l'utilisateur ait comme groupe d'appartenance
+celui du propriétaire du répertoire ( quel que soit l'utilisateur qui
+dépose ) et qu'ils soient modifiable par le groupe ( g+w ) du
+propriétaire. Par exemple : l'utilisateur A dépose un fichier dans le
+répertoire d'échange de l'utilisateur B. Il faut que les droits de ce
+fichier se présentent ainsi une fois le transfert terminé :
+
+::
+
+ $ ls -l fichier
+ -rw-rw---- 1 utilisateurA utilisateurB
+
+( ainsi l'un et l'autre pourront supprimer le fichier ). Pour cela nous
+allons utiliser une « bidouille » de l'os : le sgid bit. Derrière ce nom
+barbare se trouve un marqueur qui permet de fixer le droit de tous les
+fichiers qui seront créés dans le répertoire ( plus d'info
+`ici <http://en.wikipedia.org/wiki/Setuid>`_ ). Pour le déterminer on
+passe par chmod :
+
+::
+
+ # chmod g+s /var/chroot/${user}
+
+Cela détermine bien quel est le groupe qui sera propriétaire du fichier,
+mais cela ne donne pas à ce groupe le droit de le modifier pour autant !
+Sous linux, c'est la commande umask qui permet de déterminer les droits
+des fichiers. Le problème est qu'il s'agit d'une commande lié à
+l'environnement de l'utilisateur, et non pas aux répertoires sur
+lesquels nous travaillons ( à moins de passer par les ACLs mais cela est
+déjà assez compliqué comme ça… ). Ici, nous sommes dans un environnement
+sftp, sans shell de login, donc sans possibilité d'exécuter la commande
+directement, il faut que ce soit le serveur sftp qui le configure. J'ai
+trouvé énormément de documentations ( la plupart des bidouillages ) pour
+contourner le problème, mais la solution la plus simple vient de la
+dernière version d'OpenSSH (5.4 ) sortie le 8 mars dernier.
+
+|image2|
+
+Une nouvelle option sur le serveur sftp permet d'indiquer quel est
+l'umask qui sera appliqué ( dans notre cas 002) : dans le
+fichier/etc/ssh/sshd\_config nous allons configurer les paramètres par
+défaut du serveur sftp : Remplacer :
+
+::
+
+ Subsystem sftp /usr/lib/openssh/sftp-server.sh
+
+par :
+
+::
+
+ Subsystem sftp /usr/lib/openssh/sftp-server -u 002
+
+Pour définir les droits umask qui seront appliqués par défaut pour
+toutes les connexions sftp par défaut. Ce paramétrage est à redéfinir
+pour les paramétrages personnalisés ( bloc Match ) :
+
+::
+
+ ForceCommand internal-sftp -u 002
+
+Conclusion
+~~~~~~~~~~
+
+Nous avons un environnement bien hermétique, pouvant gérer
+l'augmentation du nombre de compte ( il suffit de refaire les chmod dans
+notre environnement chrooté à la création du compte ), et hermétique. Le
+paramétrage côté serveur est effectivement assez lourd au début, mais je
+pense que la mise à jour ne demande pas trop de travail, et on gère les
+droits de manière assez fine ( en passant par les groupes ce qui me
+semble être dans la mentalité unix ). Pour le client, il n'y a pas grand
+chose à paramétrer ( récupérer la clef et l'intégrer ), et il n'y a
+aucun risque que celui-ci vienne casser son paramétrage. On peut même
+sauvegarder sa clef privée dans son home (le vrai ), au cas où il
+perdrait le fichier.
+
+.. |Création de la clef ssh avec puttygen| image:: |filename|../images/puttygen-300x276.jpg
+.. |image1| image:: |filename|../images/filezilla-300x140.jpg
+.. |image2| image:: |filename|../images/conf-300x175.jpg