8
votes

Comment effectuer une manipulation de fichiers / répertoires avec des privilèges utilisateur à l'esprit?

J'ai une application de serveur qui fonctionnera sous un compte système car à tout moment, il s'agira de demandes de traitement pour le compte de tout utilisateur du système. Ces demandes consistent en des instructions permettant de manipuler le système de fichiers.

Voici la capture: le programme doit garder à l'esprit les privilèges de cet utilisateur particulier lors de l'exécution des actions. Par exemple, joe ne doit pas être capable de modifier / home / larry si ses autorisations sont 755 . .

actuellement ma stratégie est celle-ci

  • Obtenez le propriétaire / le groupe du fichier
  • Comparez-le à l'ID utilisateur / ID de groupe de l'utilisateur essayant d'effectuer l'action
  • Si correspondez (ou si aucune correspondance), utilisez la partie appropriée du champ de permission dans le fichier pour autoriser ou refuser l'action

    est-ce sage? Y a-t-il un moyen plus facile de faire cela?

    Au début, je pensais avoir plusieurs instances de l'application exécutées sous les comptes de l'utilisateur - mais ce n'est pas une option car une seule des instances peut alors écouter sur un port TCP donné.


0 commentaires

3 Réponses :


2
votes

Soit un serveur exécuté sur le port de serveur PrevileGued et les processus de l'enfant Spawn pour les utilisateurs qui se connectent au système. Les processus de l'enfant doivent supprimer des privilégus et inpersonater l'utilisateur qui se sont connectés. Maintenant, les enfants ne peuvent plus faire du mal.


3 commentaires

Oui, mais comment les connexions sont-elles transférées du serveur aux processus d'enfant?


Je crois que cela fonctionne en laissant le processus racine configurant la prise, puis passez simplement le descripteur de fichier à l'enfant. Je ne sais pas comment cela se fait exactement, mais au moins PostgreSQL fonctionne de manière similaire, où pour chaque connexion, un processus enfant est généré pour le gérer. Et je ne peux pas croire que tout le trafic doit être acheminé à travers le processus principal, ce sera donc une certaine fd y passant.


Eh bien ... je vais regarder dans ça. Cela rend les choses plus compliquées, bien que, parce que les processus de l'enfant doivent alors communiquer avec le parent.



3
votes

J'aurais ma fourche de serveur () et immédiatement setuid (uid) pour abandonner les privilèges root. Ensuite, toute manipulation de fichiers serait au nom de l'utilisateur que vous êtes devenu. Puisque vous êtes un enfant du serveur, vous tenez toujours l'acceptation () ed enfant prise que la demande (et je suppose que la réponse) continuerait. Ceci (évidemment) nécessite un privilège root sur le démon.

Passage descripteurs de fichiers entre les processus semble inutilement compliqué dans ce cas, comme l'enfant a déjà le descripteur "Demande".


1 commentaires

Hmmm ... c'est certainement une possibilité.



3
votes

Jetez un coup d'œil à samba pour un exemple de ceci peut être effectué. Le démon Samba fonctionne comme une racine mais des fourches et suppose les informations d'identification d'un utilisateur normal dès que possible.

Unix Systems dispose de deux ensembles de références distinctes: les ID d'utilisateur / groupe réel et des ID d'utilisateur / groupe efficaces. Le réel ensemble identifie qui vous êtes réellement et que l'ensemble effectif définit ce que vous pouvez accéder. Vous pouvez modifier l'UID / GID effectif à votre guise si vous êtes une racine, y compris à un utilisateur ordinaire et à nouveau, à mesure que vos identifiants d'utilisateur / groupe réels restent root pendant la transition. Donc, une autre façon de le faire dans un seul processus consiste à utiliser seduid / gid pour appliquer les autorisations de différents utilisateurs à l'origine et de ventilation. Si votre démon de serveur fonctionne en tant que root ou a cap_setuid , cela sera autorisé.

Toutefois, remarquez que si vous avez la possibilité de changer l'uid / gid effectif à WHIM et que votre application est subvertie, cette subversion pourrait par exemple changer l'uide / gid effectif à 0 et que vous pourriez avoir une vulnérabilité sérieuse de la sécurité. . C'est pourquoi il est prudent de laisser tomber tous les privilèges de manière permanente le plus tôt possible, y compris votre UID / gidon réel.

Pour cette raison, il est normal et plus sûr d'avoir une seule prise d'écoute exécutant en tant que root, puis de la fourche et de modifier les ID utilisateur réels et efficaces en appelant setuid . Ensuite, il ne peut pas changer de retour. Votre processus préféré aurait la prise accepter () ED tel qu'il est une fourchette. Chaque processus ferme simplement les descripteurs de fichiers dont ils n'ont pas besoin; Les sockets restent vivants car ils sont référencés par les descripteurs de fichiers dans les processus opposés.

Vous pouvez également essayer d'appliquer les autorisations en les examinant individuellement vous-même, mais j'espère qu'il est évident que cela est potentiellement sujet aux erreurs, a de nombreux cas de bord et plus susceptible de se tromper (par exemple. Cela ne fonctionnera pas avec POSIX ACLS, sauf si vous ne mettez pas spécifiquement de l'outil aussi).

Donc, vous avez trois options:

  1. Fourchette et setgid () / setuid () à l'utilisateur souhaité. Si une communication est requise, utilisez tuyau (2) ou socketpair (2) avant votre fourchette.
  2. Ne pas Fork et Seteuid () / Segid () Dans le besoin (moins sécurisé: plus susceptible de compromettre votre serveur par accident).
  3. Ne plaisante pas avec des informations d'identification du système; faire l'application de la permission manuellement (moins sécurisée: plus susceptibles d'obtenir une autorisation incorrecte).

    Si vous devez communiquer avec le démon, alors qu'il pourrait être plus difficile de le faire sur une prise ou un tuyau, la première option est vraiment la meilleure façon sécurisée d'y aller. Voir Comment SSH Séparation privilégie , par exemple. Vous pouvez également envisager si vous pouvez modifier votre architecture afin de la communication que le processus peut simplement partager une certaine mémoire ou un espace disque.

    Vous mentionnez que vous avez envisagé d'avoir un processus distinct pour chaque utilisateur, mais vous avez besoin d'un seul port TCP à écouter. Vous pouvez toujours le faire. Il suffit de disposer d'un démon maître d'écouter sur le port TCP et d'envoi de demandes à chaque démon utilisateur et de communiquer selon les besoins (par exemple, via des prises de domaine UNIX). Cela serait effectivement presque le même que d'avoir un démon maître forking; Je pense que ce dernier se révélerait être plus facile à mettre en œuvre.

    lecture supplémentaire: les informations d'identification (7) Manpage. Notez également que Linux dispose d'un système de fichiers UID / GIDS; Ceci est presque identique à celui des UID / Gids efficaces, à l'exception des autres trucs comme l'envoi de signaux. Si vos utilisateurs n'ont pas accès à Shell et ne peuvent pas exécuter de code arbitraire, vous n'avez pas besoin de vous inquiéter de la différence.


5 commentaires

Merci pour une réponse très écrite! Serait-il possible de créer un processus maître qui écoute sur un port puis transforme les données à un autre processus sur une autre connexion à la prise? Est-ce ce que vous dites dans votre deuxième paragraphe?


Oui, c'est vrai et vous pourriez le faire. Cependant, sur la base de tout ce que vous avez dit, je suis à peu près sûr que ce serait plus facile et plus simple pour vous de mettre en œuvre un démon d'écoute maître de Forking et que les privilèges de chute des enfants. Le processus préféré aura automatiquement accès à la prise de la demande, tout comme le démon principal; Pas besoin de communiquer cette partie.


D'accord. Je cherche une solution qui fonctionnera également avec QT, bien que ce ne soit pas une exigence. Donc, je prends cela en considération lorsque vous décidez la bonne approche.


Pour autant que je sache que, avec fourchette () fonctionnera parfaitement avec qt, mais bien sûr, il ne sera plus une plate-forme multiplatette car Windows n'a pas de concept de ce type.


Merci! J'ai accepté votre réponse et j'ai récompensé la prime - votre réponse a été extrêmement utile.