Comment permettre aux utilisateurs de transférer des fichiers vers d'autres utilisateurs sur Linux

10

Nous avons un environnement de quelques milliers d'utilisateurs exécutant des applications sur environ 40 clusters dont la taille varie de 20 nœuds de calcul à 98 000 nœuds de calcul. Les utilisateurs de ces systèmes génèrent des fichiers volumineux (parfois> 1 Po) contrôlés par des autorisations Unix traditionnelles (les listes de contrôle d'accès ne sont généralement pas disponibles ou pratiques en raison de la nature spécialisée du système de fichiers).

Nous avons actuellement un programme appelé "give", qui est un programme suid-root qui permet à un utilisateur de "donner" un fichier à un autre utilisateur lorsque les autorisations de groupe sont insuffisantes. Ainsi, un utilisateur doit taper quelque chose comme ceci pour donner un fichier à un autre utilisateur:

> give username-to-give-to filename-to-give ...

L'utilisateur destinataire peut alors utiliser une commande appelée "take" (partie du programme give) pour recevoir le fichier:

> take filename-to-receive

Les autorisations du fichier sont ensuite effectivement transférées à l'utilisateur destinataire.

Ce programme existe depuis des années et nous aimerions revoir les choses d'un point de vue sécuritaire et fonctionnel.

Notre plan d'action actuel consiste à supprimer la pourriture de bits dans notre implémentation actuelle de «Give» et à l'intégrer sous forme d'application open source avant de la redéployer en production.

Quelqu'un a-t-il une autre méthode à utiliser pour transférer des fichiers extrêmement volumineux entre utilisateurs lorsque seules les autorisations Unix traditionnelles sont disponibles?

Jon Bringhurst
la source
1
Y a-t-il une raison pour laquelle vous ne pouvez pas simplement créer un répertoire partagé auquel tous les utilisateurs ont accès?
Zoredache
1
S'il existe un répertoire avec accès partagé, les utilisateurs sans autorisation auront accès aux fichiers lorsqu'ils sont partagés. Dans cet environnement, les noms de fichiers sont parfois également sensibles. Donc, malheureusement, un répertoire partagé n'est pas une option. Avec un répertoire partagé, il est également possible qu'un troisième utilisateur falsifie le fichier.
Jon Bringhurst
Ne serait-ce pas suffisant qu'une tâche cron recopie elle-même les fichiers? Exemple: l'utilisateur foo veut donner une barre de fichier à l'utilisateur chiot. il crée donc un répertoire spécialisé qui est scanné par cron job avec un fichier 'control' contenant le nom d'utilisateur reçu. Les tâches cron liraient ce fichier de «contrôle», si l'utilisateur est OK, le répertoire de destination a de l'espace est OK, la copie. Vous pouvez toujours créer un wrapper pour «donner» pour simplement créer un fichier «de contrôle» pour avoir une compatibilité historique. Pas besoin de suid-root, vous pouvez copier ce fichier sous un utilisateur non root puis sudo pour changer de propriétaire.
jirib
Si vous souhaitez simplement modifier les autorisations, chownvous devez le faire. Il semble que vous souhaitiez également copier le fichier, une fois que les deux parties concernées se sont entendues.
zebediah49
@JiriXichtkniha J'aime l'idée d'un fichier de contrôle et d'un travail cron. Cependant, les fichiers sont trop volumineux pour être copiés.
Jon Bringhurst

Réponses:

1

Si l'émetteur est vraiment prêt à donner le fichier, vous pouvez utiliser un binaire SUID qui déplace le fichier dans un répertoire accessible en écriture à tous et qui a le bit collant (comme /tmp), puis change de propriétaire au nouveau propriétaire. chown(3)prend déjà en charge la suppression des bits set-user-IDet set-group-IDpour vous. De cette façon, le nouveau propriétaire peut faire ce qu'il veut avec le fichier, y compris le déplacer.

Ce répertoire accessible en écriture à tous peut appartenir au répertoire personnel de l'utilisateur, au cas où vous souhaiteriez utiliser plusieurs systèmes de fichiers pour les répertoires personnels et vous assurer de ne pas dépasser les limites du système de fichiers car les performances seraient immédiatement terribles. Dans ce cas, vous voudrez probablement vous assurer que le destinataire sait quand un nouveau fichier est proposé.

Les e-mails feraient l'affaire. Une solution plus Unixy serait une /etc/profileliste de vos fichiers nouvellement livrés. Bonus supplémentaire si vous offrez cette fonctionnalité avec pam_echo( par exemple avec file=/tmp/deliveries/%u, voir pam_echo(8)). Comme pour tout ce qui concerne PAM, vous voudrez d'abord vérifier que toutes vos implémentations offrent un tel module.

Pierre Carrier
la source
0

Vous pouvez utiliser un système avec un répertoire partagé, (éventuellement sans exécution permanente), où les choses pour un utilisateur donné sont archivées avec une structure de nom de fichier spécifique ( to-$username_from-$username.tar, par exemple). Give crée le fichier et le chownsfait pour l'utilisateur cible; prendre extrait le fichier et le supprime.

Si vous voulez le faire comme un déplacement réel (IE, changer l'emplacement du fichier et les autorisations; pas de copie en raison de la taille du fichier géant), vous pourriez être en mesure de passer à un répertoire partagé avec -x perms (donc personne ne peut y lister les fichiers), et la même chownméthode. mv, chown/ mv.

zebediah49
la source
0

Comme le dit xryl669, vous pouvez utiliser un répertoire pour partager réellement les fichiers. Ça devrait ressembler à ça:

$ ls -ld shared
drwxrws--- 2 root usergroup 4096 somedate shared
$ ls -l shared
drwx-wx--- 2 user1 usergroup 4096 somedate user1
drwx-wx--- 2 user2 usergroup 4096 somedate user2
drwx-wx--- 2 user3 usergroup 4096 somedate user3
drwx-wx--- 2 user4 usergroup 4096 somedate user4

La commande donner devient

#!/bin/sh
#Use a random suffix to prevent guessing
RANDOM=$(dd if=/dev/urandom count=4 2> /dev/null | sha512sum | cut -d' ' -f1)
NEWNAME=/path/to/shared/$2/$1$RANDOM
#Move the file
mv $1 $NEWNAME
#Make it readable
chmod 440 $NEWNAME

La commande take ressemble à ceci:

$ cd /path/to/shared/user
$ ls
...
$ mv somefile ~
miniBill
la source
0

Je suggère de réécrire l'application pour imiter en effet un "donner" et "prendre", mais plutôt "pousser" et "tirer" à partir d'un répertoire protégé. Votre répertoire n'est accessible que pour l'application push / pull - qui gère les déplacements de fichiers. Alternativement, votre application / script peut créer un répertoire temporaire aléatoire avec des autorisations définies pour l'expéditeur et le destinataire uniquement.

Vous souhaitez avoir plus de sécurité? Vous pouvez PGP crypter / signer le fichier (en utilisant la clé publique du récepteur).

En termes de refaire d'un "point de vue sécurité et fonctionnel", je vous suggère fortement de ne pas créer de programmes SUID. Si vous ne supprimez pas les privilèges de manière appropriée, vous pouvez accéder virtuellement à n'importe quel fichier du système. Si votre programme est bogué (débordement de tampon, etc ...) - on peut l'exploiter pour avoir un accès root sur votre système.

ndrix
la source
0

Cela ne vous est probablement pas utile, mais pour référence, la cible source cp --reflink effectue des copies minces de fichiers à l'aide de la copie sur écriture.

Cela signifie que vous pouvez copier le fichier et que seuls les blocs modifiés seront réellement copiés. Contrairement à un lien dur, le nouveau fichier a son propre inode et ses propres métadonnées, ce qui signifie que vous pouvez ensuite fournir la copie du fichier au nouvel utilisateur en utilisant des éléments standard montrés.

Pour autant que je sache, c'est une fonctionnalité qui n'est actuellement disponible que sur OCFS2 et btrfs. Je suppose que cela résout votre problème mais vu que la disponibilité de celui-ci n'est pas répandue, cela ne sera probablement pas utile.

Matthew Ife
la source