SFTP, chroot et pas de SSH : bloquer un utilisateur dans un répertoire

closeCet article a été publié il y a 7 ans 2 mois 17 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

Salut,
Un petit article sur ce sujet récurrent car il y a plein de méthodes, dont une assez simple, mais avec 2/3 points de paramétrage précis.
Le but est de permettre à un client/fournisseur d’envoyer/récupérer des fichiers sur un serveur, en SFTP, sans pour autant lui donner accès en SSH (exécuter des commandes) et sans voir autre part que son « home ».
Le tout sur un serveur SSH déjà monté et par ailleurs utilisé pour du SSH normal en interne, avec du SFTP normal aussi.

Il y a 3 méthodes courantes pour commencer à jouer avec les chroot ssh/sftp :

  • Héberger un serveur SSH en chroot normal : c’est chiant. Créer un « home », reproduire un minimum d’arborescence standard, d’utilisateurs etc.
  • Utiliser rssh comme shell alternatif, c’est un shell qui limite l’utilisateur à du SFTP, SCP, CVS, RSYNC etc. On choisit ce qu’on veut tolérer. Mais, l’utilisateur peut quand même se promener dans le système (tout « / »).
  • Enfin, ce que je vais décrire : utiliser la fonctionnalité de « chroot » intégrée aux serveurs SSH (serveur ssh >= 4.8, donc n’importe quel SSH d’une Debian stable de nos jours). On va simplement brider quelques comptes et mettre quelques permissions bien senties.

Adaptation d’un utilisateur

Le mieux est de prévoir large : on risque d’avoir plusieurs clients/fournisseurs qui voudront accéder.
On va donc créer un groupe des utilisateurs SFTP seulement, nommé « sftpusers ».
Je crée un utilisateur pour mon client, nommé xfer1, en changeant son home :

xfer1:x:1011:1012:Transfert client1,,,:/transferts_partenaires/xfer1/:bin/bash

Notez que le groupe 1012 est le groupe « sftpusers » :

$ id xfer1
uid=1011(xfer1) gid=1012(sftpusers) groupes=1012(sftpusers)

Création du répertoire d’échange, permissions

On crée l’arborescence qui va servir de home bidon à tout ces utilisateurs :

$ mkdir --parents /transferts_partenaires/xfer1/
$ chown -R root:sftpusers /transferts_partenaires/
$ chmod -R 750 /transferts_partenaires/

Les permissions ci-dessus sont hyper importantes. Le serveur SFTP refusera la connexion si le home de ces utilisateurs n’est pas en écriture uniquement pour le root ! Donc oui, en l’état, notre utilisateur xfer1:sftpusers ne peut pas écrire dans son home. Il pourra lire, ce qui peut être suffisant si vous lui mettez simplement des fichiers à disposition. Mais pour écrire, il faudra créer un sous-répertoire, genre « upload ».

mkdir /transferts_partenaires/xfer1/upload/
chown xfer1:sftpusers /transferts_partenaires/xfer1/upload/
chmod 700 /transferts_partenaires/xfer1/upload/

Déclaration du compte en SFTP uniquement

Enfin, on paramètre le serveur SSH comme suit. Modifiez votre fichier /etc/ssh/sshd_config :

# param par défaut, on change : Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem     sftp   internal-sftp -f AUTH -l VERBOSE

# plus loin...
Match Group sftpusers
        ChrootDirectory /transferts_partenaires/%u
        ForceCommand internal-sftp
        AllowTcpForwarding no
        GatewayPorts no
        X11Forwarding no

A noter que les AllowUsers/DenyUsers s’appliquent toujours. L’utilisateur xfer1 – ou plutôt les utilisateurs du groupe sftpusers – doivent être autorisés d’une manière ou d’une autre.
A noter aussi la beauté du geste avec le « %u » pour indiquer le nom de l’utilisateur.

Ensuite vous recharger le serveur SSH et testez les connexions SFTP et SSH-qui-passent-pas, sans oublier la distinction lecture/écriture.

24 réflexions au sujet de « SFTP, chroot et pas de SSH : bloquer un utilisateur dans un répertoire »

  1. Chimrod

    J’avais fait il y a quelques temps un article similaire que j’avais publié sur le planet. Dans les commentaires, on m’avait parlé d’une solution beaucoup plus simple qui est mysecureshell.
    En gros, il suffit de remplacer le shell de connexion de l’utilisateur par mysecureshell et le chroot s’applique. C’est désormais ce que j’utilise…

    http://mysecureshell.sourceforge.net/fr/index.html

    À comparer…

    Répondre
    1. michauko Auteur de l’article

      Soit. Merci d’avoir indiqué l’outil.
      En lisant vite fait, il semble qu’il faille un logiciel supplémentaire à installer, mysecureshell, justement. Alors qu’on a dédié SSH…
      En plus, il faut aussi modifier le home et le shell des utilisateurs, genre :
      msstest:x:1006:500:MSS Testing:/home/sftpusers/msstest:/bin/sh
      Résultat…. c’est pas plus simple si ?
      Par contre on peut affiner les permissions apparement. Bon pourquoi pas. Mais *pas* si c’est un service en plus du SSH. Je trouve ça trop dommage 🙂

      Répondre
  2. cyrille

    Je confirme, mysecureshell est l’outil que j’utilise sur mon serveur personnel, voici le billet correspondant, ce n’est pas très long comme on peut le voir. http://www.cyrille-borne.com/index.php?post/2010/05/09/Le-X-Man-sans-le-X%2C-%C3%A9pisode-4-%3A-plus-loin-avec-ssh%2C-mysecureshell

    Par contre, il y a un soucis sur la limitation de la bande passante, on a du mal à passer la barre des 20 ko/s chez moi quel que soit le paramétrage de l’upload.

    Répondre
  3. michauko Auteur de l’article

    Si c’était un autre serveur SSH qui ne faisait que SFTP.
    Bref, un autre service, un autre port etc.
    Mais non, tu me confirmes que c’est une surcouche, disons un truc qui s’intercale avec le SSH normal.
    merci

    Répondre
  4. pyrrha

    Bonsoir,
    J’ai utilisé cette technique pendant un bon moment, c’est parfait.
    Maintenant, le problème c’est que je m’authentifie uniquement par clé partagés sur mon serveur SSH pour plus de sécurité (PAM désactivé).
    Quelqu’un sait s’il est possible de laisser l’authentification PAM pour certains utilisateurs uniquement ?
    Merci

    Répondre
  5. imars

    J’ai suivi le tuto par contre je suis étonné que personne n’est mentionné le fait qu’il faille ajouter les utilisateurs sur la ligne AllowUsers user1 user2 user3 etc…

    Car il m’était impossible de me connecter .

    Répondre
    1. michauko Auteur de l’article

      Salut,
      Peut-être car personne n’a eu à le faire. Personnellement je n’ai pas eu à le faire.
      Mais il faut dire que je n’ai aucune ligne AllowUsers. Si par contre on utilise cette directive, peut-être faut-il ajouter les utilisateurs, en effet.
      Je ne sais plus bien (et pas trop envie de tester ;))

      Merci de l’avoir signalé, à tout hasard

      Répondre
  6. imars

    Effectivement 😉 .
    La directive AllowUsers d’après les tutos c’est pour sécuriser le serveur pour éviter les tentatives de connexions en ssh avec root sur le port 22 par défaut. Du coup passer par l’autre compte utilisateur genre « toto » en ssh pour se connecter et utiliser su pour passer en mot root. Du coup il faut ajouter AllowUsers dans sshd_config pour autoriser « toto » est désactiver la connexion à root avec PermitRootLogin no. C’est pour ça que je n’arrivais à mettre en place le tuto qui était super claire pourtant.

    Une dernière question ?
    Lorsqu’ont se connecte au compte sftp avec un client en tombe directement dans  » /home/user/  » ok parfait.
    Mais je constate qu’il n’est pas possible de chrooter l’utilisateur au delà de /home/user/ par exemple /home/user/www/ j’ai testé dans sshd_config /home/%u/www mais cela ne marche pas et il semble que cela ne soit pas possible après avoir fait 20 pages de recherche dans google, tant pis.

    Répondre
  7. colas

    Très bon tuto, surtout concernant les droits sur les répertoires.
    Idem que imars j’ai du rajouter un AllowUsers. En sachant que j’ai un PermitRootLogin no.
    J’ai essayé du coup de faire un AllowGroups pour rester plus générique mais ceci ne me permet pas de me connecter. Une idée ou c’est normal ?

    Répondre
  8. Macgyvre

    A propos de la comparaison avec Mysecureshell, je ne pense pas que ce dernier soit plus contraignant, au contraire, car on n’a juste qu’à changer le fichier /etc/password sans avoir à toucher/créer un nouveau groupe, ni de répertoire spécifique pour le home. De plus, on peut très bien avec Mysecureshell attribuer aux fichier le groupe que l’on veut (comme www-data, très pratique si on fait du web), ce que l’on ne peut pas faire avec cette méthode…)

    Répondre
  9. imars

    Après on avoir fait le tour j’ai installé vsftpd je pensais pouvoir créer autant de compte que je voulais en spécifiant à chaque fois un répertoire dédié mais cela ne semble pas possible en native.

    Répondre
  10. ffg

    c’est le millionieme tutoriel que j’essaye
    pas moyen mon user parcours tout le file systeme sans jamais etre bloqué
    putain de chroot de m…

    Répondre
    1. admin

      salut, curieux, dans les logs /var/log/*log tu n’as rien qui te dit que quelque chose ne va pas au lancement et donc le chroot tombe à l’eau ? une permission sur je ne sais quel fichier par exemple ?

      Répondre
    2. ssm2017

      j’avais aussi le meme probleme.
      j’avais oublié de mettre le user dans le groupe sftpusers.
      je suppose donc que seuls les users de ce groupe sont affectés par le chroot (voir directive Match) et les autres users ne sont pas concernés.
      ajouter le user dans le groupe puis rafraichir la vue du client sftp.

      Répondre
  11. jean

    après avoir suivi un tas de tutos sftp n’est pas possible sur linuxmint18 et je cherche encore

    systemctl status ssh.service
    ● ssh.service – OpenBSD Secure Shell server
    Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
    Active: failed (Result: exit-code) since jeu. 2016-07-14 09:58:57 CEST; 34s ago
    Process: 1568 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
    Process: 3740 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=255)
    Main PID: 3740 (code=exited, status=255)

    juil. 14 09:58:57 pedro-H systemd[1]: Starting OpenBSD Secure Shell server…
    juil. 14 09:58:57 pedro-H sshd[3740]: /etc/ssh/sshd_config line 110: Directive ‘UsePAM’ is not allowed within a Matc
    juil. 14 09:58:57 jean-H systemd[1]: ssh.service: Main process exited, code=exited, status=255/n/a
    juil. 14 09:58:57 jean-H systemd[1]: Failed to start OpenBSD Secure Shell server.
    juil. 14 09:58:57 jean systemd[1]: ssh.service: Unit entered failed state.
    juil. 14 09:58:57 jean systemd[1]: ssh.service: Failed with result ‘exit-code’.
    lines 1-13/13 (END)

    Répondre
  12. nbo

    Bonjour,
    Merci pour cet article.
    Je dispose d’un serveur dédié hébergé chez un FAI sur lequel j’aimerai disposer d’un serveur sftp.
    Les utilisateurs ne doivent pas être capables de voir l’arborescence des fichiers.
    J’ai mis en place la solution que vous décrivez mais comme indiqué dans votre article, je perds l’accès SSH.
    Hors c’est via une connexion SSH que je peux me connecter au serveur pour le configurer.
    Y-a-t-il moyen d’adapter la configuration que vous proposez pour avoir en parallèle l’accès au sftp et une connexion SSH ? Ou faut-il s’y prendre d’une manière différence comme par exemple en utilisant mysecureshell tel qu’évoqué dans certain commentaires?

    Répondre
  13. Ping : SFTP – Transfert de fichiers via SSH – Administration système

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *