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:
- Les users
abcetxyzdoivent être membres d'un même groupe (généralement le groupe de connexion de l'un des deux). - Les répertoires de stockage de
abcetxyzdoivent être des sous-répertoires du même répertoire de chroot, tel que défini par le paramètreChrootDirectory; par exemple:/srv/sftp/abcet/srv/sftp/xyz. - Si le groupe qui possède le répertoire
/srv/sftp/xyzn'est pas le groupe primaire ou groupe de connexion dexyz, le bit setgid doit impérativement être activé sur ce répertoire. - 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.
- Comme rien ne garantit qu'un fichier envoyé par
xyzsera lisible parabc(si son mode est de400côté client, il conservera ce mode sur le serveur), en l'absence d'un mécanisme complémentaire àumaskou 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:
abcest membre du groupexyz.xyzn'est pas membre du groupeabc./srv/sftp/abcappartient àabc:abc./srv/sftp/xyzappartient à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):
abcest membre du groupexyz.xyzest membre du groupeabc./srv/sftp/abcappartient àabc:abc./srv/sftp/xyzappartient àxyz:xyz.
Ou encore:
abcest membre du groupexyz.xyzn'est pas membre du groupeabc./srv/sftp/abcappartient àabc:xyzet son bit setgid est activé./srv/sftp/xyzappartient à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.
Une piste évoquée mais non testée, pour un accès en lecture seule sans passer par cron: créer un compte
${user}-roavec les mêmes uid et gid que${user}, et lui appliquer la directiveForceCommand internal-sftp -Rdans la configuration du serveur ssh.
todo: à tester avec des comptes de test ou sur une autre machine.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:comptaest membre du groupeadmin; son espace de stockage appartient au groupeadminet a donc son bit setgid activé;adminetcomptadoivent chacun pouvoir lire les documents de l'autre.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.