Voici la procédure à suivre pour créer et configurer un espace de stockage de fichiers sur la VM de bureautique, ainsi que le compte user qui lui est associé.

Prérequis

Un espace de stockage de fichiers et le compte qui lui est associé doivent répondre aux contraintes suivantes:

  • Seul l'user associé à un espace de stockage de fichiers peut y accéder en écriture et (par défaut) en lecture.
  • L'user qui accède à son espace de stockage ne doit pas pouvoir accéder au reste du système de fichiers.

Cela implique que l'user en question n'a pas d'accès shell à la machine. Il ne doit donc pas pouvoir se connecter par ssh, mais uniquement par un client supportant sftp (ou scp), dans un répertoire chrooté.

Création du compte

Soit « lucane » l'identifiant du compte à créer. On crée un compte avec un mot de passe désactivé et sans shell de connexion, et d'abord sans créer son répertoire personnel (pour ne pas y copier des fichiers inutiles):

sudo adduser --quiet --gecos "" --disabled-password --no-create-home --home /srv/sftp/lucane --shell /usr/sbin/nologin lucane

On préfère garder les clefs (publiques) SSH du compte versionnées sous /etc:

sudo cp /chemin/vers/ssh-key.pub /etc/ssh/role_keys/lucane

Configuration de l'espace de stockage

Créer un répertoire dédié dans /srv, par exemple /srv/sftp/lucane. Le répertoire /srv/sftp doit appartenir à root:root et avoir le mode 0755.

Le sous-répertoire lucane doit appartenir à lucane:lucane et son mode doit être 0700 (ou 0750). Par défaut, il vaut mieux activer le bit setgid, même si ça ne semble pas strictement nécessaire.

Dans /etc/ssh/sshd_config, ajouter:

Match User lucane
    AuthorizedKeysFile /etc/ssh/role_keys/%u
    ChrootDirectory /srv/sftp
    ForceCommand internal-sftp -u 077
    AllowTcpForwarding no
    X11Forwarding no

Ne pas hésiter à consulter les pages de manuel de sshd_config(5) et sftp-server(8) pour des détails sur la directive Match et les options de la directive ForceCommand.

Enfin ne pas oublier: sudo etckeeper commit.

Puis envoyer au(x) bénéficiaire(s) de cet espace de stockage l'adresse de connexion (ici lucane@bulbe.nos-oignons.net) et les empreintes des clefs ssh du serveur:

for k in /etc/ssh/ssh_host_*_key; do
    ssh-keygen -lf ${k} | awk '{print $2,$4}'
done

Partager un espace de stockage

Il peut arriver qu'un espace de stockage doive répondre à des contraintes supplémentaires, notamment en termes de partage du même espace de stockage entre plusieurs users, avec des permissions différentes.

Si deux users abc et xyz ont chacun un espace de stockage de fichiers sur la même machine et que abc doit pouvoir accéder en lecture au contenu du répertoire de stockage de xyz, les conditions suivantes doivent être réunies:

  1. Les users abc et xyz doivent être membres d'un même groupe (généralement le groupe de connexion de l'un des deux).
  2. Les répertoires de stockage de abc et xyz doivent être des sous-répertoires du même répertoire de chroot, tel que défini par le paramètre ChrootDirectory; par exemple: /srv/sftp/abc et /srv/sftp/xyz.
  3. Si le groupe qui possède le répertoire /srv/sftp/xyz n'est pas le groupe primaire ou groupe de connexion de xyz, le bit setgid doit impérativement être activé sur ce répertoire.
  4. Le masque des permissions doit être fixé de manière à empêcher l'écriture par le groupe, tout en autorisant la lecture et la traversée des répertoires.
  5. Comme rien ne garantit qu'un fichier envoyé par xyz sera lisible par abc (si son mode est de 400 côté client, il conservera ce mode sur le serveur), en l'absence d'un mécanisme complémentaire à umask ou similaire à trap (qui permettrait de modifier les permissions à la déconnexion), on demande à cron de faire en sorte que les fichiers soient lisibles par le groupe.

Dans ce cas on obtiendrait, pour un accès en lecture de abc aux fichiers de xyz mais pas l'inverse:

  • abc est membre du groupe xyz.
  • xyz n'est pas membre du groupe abc.
  • /srv/sftp/abc appartient à abc:abc.
  • /srv/sftp/xyz appartient à xyz:xyz.

Dans /etc/sshd_config:

Match Group xyz
    ChrootDirectory /srv/sftp
    ForceCommand internal-sftp -u 027

Dans /etc/cron.d/sftp:

30 */12 * * * xyz find /srv/sftp/xyz \( -type d ! -perm /050 -exec chmod g+rx {} + \) -o \( -type f ! -perm /040 -exec chmod g+r {} + \)

Mais dans un autre cas, on obtiendrait, pour un accès en lecture de chaque user aux fichiers de l'autre (à ajuster selon le contexte):

  • abc est membre du groupe xyz.
  • xyz est membre du groupe abc.
  • /srv/sftp/abc appartient à abc:abc.
  • /srv/sftp/xyz appartient à xyz:xyz.

Ou encore:

  • abc est membre du groupe xyz.
  • xyz n'est pas membre du groupe abc.
  • /srv/sftp/abc appartient à abc:xyz et son bit setgid est activé.
  • /srv/sftp/xyz appartient à xyz:xyz.

Dans /etc/cron.d/sftp, faire exécuter, en plus de la commande précédente, la même commande find sous l'identité de abc et appliquée au répertoire /srv/sftp/abc.

Voir aussi:

NOTES

La configuration des comptes et espaces de stockage décrits ici a fait l'objet de nombreux tests et tâtonnements, notamment en ce qui concerne le partage des espaces de stockage par plusieurs users avec des permissions différentes.

  1. Une piste évoquée mais non testée, pour un accès en lecture seule sans passer par cron: créer un compte ${user}-ro avec les mêmes uid et gid que ${user}, et lui appliquer la directive ForceCommand internal-sftp -R dans la configuration du serveur ssh.
    todo: à tester avec des comptes de test ou sur une autre machine.

  2. Concernant l'appartenance aux groupes et l'activation du bit setgid, le contexte peut servir de guide, ou pas. Par exemple, pour les espaces de stockage dédiés au conseil d'administration (admin) et aux comptables (compta), j'ai pris en compte le fait que la comptabilité est un sous-ensemble de tâches et de documents afférents à l'administration, et que l'équipe comptable est elle-même un sous-groupe du CA, pour arriver à cette conclusion: compta est membre du groupe admin; son espace de stockage appartient au groupe admin et a donc son bit setgid activé; admin et compta doivent chacun pouvoir lire les documents de l'autre.

  3. Ne pas hésiter à demander aux titulaires des espaces de stockage partagés des précisions sur les spécifications de ces espaces. Il peut s'avérer qu'une entrée dans le fichier crontab ne soit pas nécessaire si un user veut garder la maîtrise de ce à quoi il autorise l'accès par un autre.