On veut sécuriser les connexion ftp d'une utilisatrice et l'on veut que cette utilisatrice ne puisse accéder qu'au répertoire de travail ftp qu'on lui affecte. Pour ce faire, on dispose de deux techniques : ftps et sftp.
ftps qui s'appuie sur tls et un serveur ftp. En configurant le serveur ftp, on peut facilement restreindre l'accès de toute utilisatrice à son répertoire de base. Il n'est pas nécessaire de lui donner accès à un shell (simple utilisatrice reconnue par le serveur ftp). Mais on peut ne pas vouloir ou ne pas pouvoir utiliser de certificats1) ! Dans ce cas, l'option ftps doit être écartée.
L'autre solution consiste à utiliser le protocole sftp. Un serveur sftp peut être réalisé de deux manières. La méthode “classique” s'appuie sur une application serveur SSH qui fournit un canal sécurisé à travers lequel le client dialogue avec une application serveur sftp. La deuxième technique2) - que nous développons ici - n'utilise pas de serveur ftp séparé, le service sftp étant intégralement fourni par l'application OpenSSH. Il en découle une contrainte et un problème. La contrainte est que le l'utilisatrice doit disposer d'un shell. Dans les deux cas, l'utilisatrice commence par emprunter un canal ssh. Une utilisatrice pouvant lancer un shell a automatiquement le droit de se promener dans tout le système de fichiers3).
On voudrait avoir les avantages de ftps (limitation à un répertoire de base) et ceux de sftp (pas de serveur ftp et par de certificats) ; autrement dit, emprisonner (jail) l'utilisatrice sftp dans un répertoire de base (typiquement, son répertoire “home”).
Sources :
On peut très rapidement mettre en œuvre une configuration technique permettant d'atteindre cet objectif.
# nano /etc/ssh/sshd_config
à la fin du fichier, ajouter le bloc suivant :
Match group jailed ChrootDirectory %h AllowTcpForwarding no ForceCommand internal-sftp
sauvergarder les modifications. On a indiqué que toute utilisatrice rattachée au groupe que l'on a décidé de nommer jailed sera restreinte à sa “home”. Rien ne change pour les autres. Ne pas oublier de demander à OpenSSH de recharger sa configuration afin que les modifications apportées soient prises en compte :
# /etc/init.d/ssh reload
On commence par créer le groupe auquel appartiendront toutes les utilisatrices d'OnpenSSH dont nous souhaitons limiter les possibilités de navigation ;
# addgroup jailed
On ajoute l'utilisatrice (ici, flo) au groupe jailed et on modifie les droit sur sa “home” :
# usermod -G jailed flo # chown root:root /home/flo # chmod 755 /home/flo
À ce stade, flo ne peux plus que circuler dans sa home et en voir le contenu. Elle ne peut rien créer ni modifier. Il faut y remédier.
On crée des sous-répertoires de sa “home” et on lui donne tous les droits sur ces sous-répertoires. Par exemple :
# cd /home/flo # mkdir data public_html # chown flo:jailed data public_html
Enfin, notre utilisatrice n'ayant besoin d'ouvrir de sessions interactive, inutile de lui affecter un shell. Lui retirer ce shell si la commande/script de création d'utilisatrice lui en a affecté un. Ceci s'obtient en lui affectant le shell /bin/false.
Dans l'exemple précédent nous avons supposé que la “home” se trouvait immédiatement dans '/home'. Nous avons également supposé que ce répertoire appartenait à root:root. C'est bien la configuration par défaut mais ce n'est pas toujours le cas.
Dans toute autre configuration, le chemin depuis la racine du système de fichier jusqu'à la “home” de l'utilisatrice doit vérifier deux conditions, imposées par certaines versions d'OpenSSH4) :
Si vous utilisez un client ftp correct (Konqueror, Filezilla…), vous ne rencontrerez pas de problème pour vous connecter en sftp. Si vous êtes scotchée avec un client ftp de m…, il se peut qu'ils ne parvienne pas à établir une connexion sftp.
Souvent, l'accès sftp “restreint” s'applique à l'administratrice d'un site web. On souhaite alors qu'elle puisse téléverser des fichiers à la racine de son site. C'est ce suggérait la création du répertoire public_html, dans la section précédente.
Il faut alors prendre garde à ce que l'utilisatrice ne puisse pas, par le biais du serveur web (Apache ou autre) exécuter un script qui lui permettrait de contourner les limitations mises en place et, par là même, de circuler dans tout le système de fichier. On prendra donc le plus grand soin dans la configuration du vhost.
Cette solution n'est donc applicable qu'aux site web se contentant de servir des fichiers statiques.
La technique la plus simple consiste à utiliser un répertoire standard, créé dans la “home” de l'utilisatrice (dans notre exemple public_html), comme racine du site web (DocumentRoot). Le vhost sera configuré en conséquence. Cette opération (classique) n'est pas détaillée ici.
Si l'on souhaite que la racine du site web se trouve dans une arborescence web commune à toutes les utilisatrices (par ex. /var/www/flo), on est face à un contradiction. Cet espace (/var/www) se trouvant en dehors de la “home” de notre utilisatrice chrootée, le système ne nous laissera pas créer un lien (au sens trivial : link) que l'utilisatrice pourra exploiter6). Heureusement !
Qu'à cela ne tienne, on obtient le résultat fonctionnel souhaité en montant la racine du site web sur un répertoire accessible à l'utilisatrice. Pour ce faire, on utilise la technique de bind mount qui permet de monter une partie d'un système de fichier déjà monté, sans créer de conflit. Par exemple :
# mount /var/www/flo /home/flo/public_html -o bind
On prendra garde à ce que les droits du répertoire que l'on monte permette à la fois :
Un des moyens d'atteindre cet objectif est de rendre l'utilisatrice sftp propriétaire de la racine du site tout en l'affectant au groupe sous l'identité duquel le serveur web est lancé (dans un cas standard, www-data).
Lire aussi : DefaultRoot, Symlinks and chroot()(en). Une discussion instructive sur les liens en environnement chrooté.
Si l'on utilise Virtualmin, il n'est pas judicieux de dériver les utilisatrices sftp chrootées à partir d'utilisatrice crées par Virtualmin. La contrainte d'appartenance à root:root de la “home” de l'utilisatrice est contradictoire avec la gestion qui en est faite par Virtualmin.
On créera donc des utilisatrices à partir des commandes de base, comme nous l'avons fait précédemment. Si l'on tient absolument à une interface graphique, rien n'empêche d'utiliser Webmin.
Rien ne s'oppose à ce qu'on utilise un vhost créé à travers Virtualmin (virtual server). Dans ce cas, il faudra ajuster les droits du répertoire public_html du virtual server. Par exemple en supposant que le virtual server appartient à flo-www, en incluant le bind mount :
# mount /home/flo/public_html /home/flo-www/public_html -o bind # chown flo /home/flo-www/public_html
Ainsi :
Si le besoin de coupler un compte sftp chrooté à un site web est fréquent, il sera intéressant de créer un modèle de serveur Virtualmin (server template).
On peut se passer complètement de Virtualmin et créer le vhost “à la main” (en ligne de commande et éditeur ou à travers Webmin).
L'avantage est que l'on configure le vhost exactement comme on le souhaite, en ajoutant à partir de rien plutôt qu'en retirant à partir d'un profil Virtualmin trop permissif.
L'inconvénient est que l'on perd l'enrichissement qu'apporte la notion de virtual server (intégration, fonctionnalités) par rapport à la notion de virtual host (vhot). web perd l'intégration et les fonctionnalités mise à disposition par Virtualmin.
Tant qu'à proposer un accès sécurisé, autant le faire dans les meilleurs conditions. Au lieu d'utiliser une authentification rustique à l'aide d'un login et d'un mot de passe, mieux vaut utiliser l'authentification par clés, puisque ssh le permet. Du côté de l'utilisatrice, cela lui évite d'avoir à taper un login et un mot de passe. Du côté du serveur, on peut interdire toute autre forme d'authentification et n'autoriser la connexion que depuis certaines adresses IP.
Dans l'exemple traité précédemment, notre utilisatrice (flo) a été créée en suivant les règles habituelles. La déclaration des clés utilisables pour se connecter se fait donc suivant les règles habituelles. Il faudra cependant tenir compte du fait qu'elle ne possède plus son répertoire “home” puisqu'on l'a “donné” à root :
# cd /home/flo # mkdir .ssh # cd .ssh # nano authorized_keys puis copier/coller les clés publiques voulues, éventuellement restreintes aux IP voulues…
Si tel est bien le but poursuivi, ne pas oublier de désactiver la connexion par login/mdp, dans la configuration d'OpenSSH.
La technique alternative la plus documentée est celle qui passe par une mise en œuvre manuelle de comptes chrooted.
Elle est beaucoup plus lourde à mettre en place et ne peut être appliquée à des utilisatrices déjà créées. En effet, cette technique exige un processus particulier de création des comptes utilisatrices.
Pour une présentation complète de la solution :