Comment tuer un processus démarré avec un autre utilisateur sans être root ou sudoer?

20

dans un environnement Linux, j'ai besoin de tuer un processus qui a été démarré par user2 si je suis user1 sans être sudoers ou utiliser root. Savez-vous s'il existe un moyen de régler cela lors du lancement du processus? Comme une liste d'utilisateurs autorisés à tuer le processus?

Le fait est que des instances simultanées du même processus peuvent être démarrées à partir d'utilisateurs différents, c'est pourquoi il n'est pas pratique pour moi de définir l'ID de groupe sur le processus. Les autres utilisateurs qui ne font pas partie du groupe ne pourront pas démarrer un deuxième processus parallèle.

Ce que j'ai est une liste d'utilisateurs autorisés à démarrer le processus, définie dans la base de données, avant de démarrer le processus, je vérifie que l'utilisateur actuel dans la liste et, si oui, je démarre le processus avec l'utilisateur actuel. Si un deuxième utilisateur autorisé à le faire veut tuer le processus, j'aimerais qu'il soit autorisé à le faire, mais je ne veux pas que ce soit des sudoers.

Par conséquent, je pensais créer un processus fonctionnant en tant que root qui reçoit la demande de tuer les processus d'un utilisateur, vérifie si l'utilisateur est autorisé à démarrer / arrêter le processus et tue le processus.

Pensez-vous que cela pourrait être la meilleure solution?

slhck
la source
Bienvenue chez SO. Je ne pense pas que ce soit possible ... Quoi qu'il en soit, cela convient mieux au site frère de SO, serverfault.com. Il pourrait y migrer bientôt, pas besoin de faire quoi que ce soit.
Pekka prend en charge GoFundMonica
De quel type de programme parlons-nous? Ce serait difficile dans le cas général, mais dans certains cas (comme Apache ou une application que vous pouvez modifier vous-même), ce serait plus facile.
Kim

Réponses:

14

Je suis désolé, mais ce n'est tout simplement pas possible (c'est par conception). Cependant, si les membres d'un groupe commun, user1 peut écrire dans un fichier que le processus de user2 vérifie, indiquant au processus qu'il doit se terminer.

Ou, user2 pourrait exécuter quelque chose en arrière-plan qui vérifie un fichier, puis envoie les signaux appropriés. L'utilisateur 1 doit alors simplement écrire dans ce fichier. Cela peut être plus facile, car cela ne nécessiterait aucune modification des programmes de user2.

Classiquement, non, l'utilisateur1 ne peut pas envoyer de signaux POSIX au processus de l'utilisateur2.

Tim Post
la source
Merci pour votre réponse. Dans mon cas, en effet, je n'utilise pas le fichier mais nous utilisons un système ( dim.web.cern.ch/dim ) qui peut envoyer le signal approprié, puis un processus peut être appelé pour vérifier que l'utilisateur est autorisé à arrêtez le processus et tuez le processus.
@ATelesca - J'utilise quelque chose de très similaire pour permettre aux utilisateurs défavorisés de contrôler / démarrer / arrêter des machines virtuelles Xen sur une batterie de serveurs assez grande. Fondamentalement, la même chose.
Tim Post
9

À moins que les ACL ou SELinux ou autre chose aient une meilleure façon de le faire, la façon dont j'ai vu cela se fait avec un script SetUID . Comme vous pouvez l'imaginer, ils sont tristement célèbres pour être des risques de sécurité.

En ce qui concerne votre cas, disons que procOwner est le nom d'utilisateur du propriétaire du processus, et userA (uid 1000), userB (uid 1201) et userC (uid 1450) sont les personnes autorisées à tuer le processus.

killmyproc.bash:

#!/bin/bash
case ${UID} in
1000|1201|1450) ;;
*) echo "You are not allowed to kill the process."
   exit 1;;
esac

kill ${PROCESS_ID}
# PROCESS_ID could also be stored somewhere in /var/run.

Ensuite, définissez le propriétaire et les autorisations avec:

chown procOwner:procGroup killmyproc.bash
chmod 6750 killmyproc.bash

Et mettez également userA, userB et userC dans le groupe procGroup.


la source
J'ai essayé ça et ça n'a pas marché. L'utilisateur non propriétaire a obtenu une autorisation refusée sur la commande kill.
Javid Jamae
1
Je voudrais simplement ajouter, pourquoi ne pas laisser le système contrôler les autorisations du script kill? Créer un groupe à partir de userA, userB et userC, puis répartir le killscript dans ce groupe et le modifier en g + x me semble beaucoup plus net.
Leonid Shevtsov
1
bit setUid non autorisé dans les scripts shell, vous devez créer un programme compilé par wrapper simple pour l'exécuter
El '
2

Pas de manière conventionnelle - inviter un utilisateur à tuer les processus de quelqu'un d'autre est l'ultime vulnérabilité de déni de service.

Cela peut être fait si le processus cible coopère. Une façon serait de surveiller un événement externe (comme un fichier créé dans / var / tmp, ou un message sur un socket), en lui demandant de se tuer. Si vous ne pouvez pas l'écrire pour cela, vous pouvez lui écrire un wrapper qui le démarre, puis effectue la surveillance, tuant le processus enfant si l'événement se produit.


la source
1

Non, tu ne peux pas.

Si vous souhaitez partager des processus avec d'autres utilisateurs, vous devez démarrer le processus sous un ID utilisateur commun.

Konerak
la source
1

Bien sûr, vous pouvez écrire le programme de telle manière qu'il se termine avec élégance lorsqu'il reçoit un certain signal (terme utilisé de manière lâche pour signifier "un événement prédéterminé", pas un signal POSIX) d'un certain (liste) d'utilisateurs.

drxzcl
la source
Les signaux n'ont pas de champ "utilisateur". Ce ne sont que des signaux.
LtWorf
C'est pourquoi j'ai dit "un événement prédéterminé, pas un signal POSIX".
drxzcl
1

Vous pouvez écrire un programme suid que seuls les utilisateurs d'un certain groupe peuvent exécuter et qui envoie le signal approprié au processus. Je ne sais pas si vous vouliez également exclure suid.

Kim
la source
0

suid bit ne fonctionne pas avec les scripts bash. à mon humble avis, la meilleure façon est d'écrire un script wrapper "killservice". Supposons que votre service fonctionne en tant que service utilisateur

#!/bin/bash
sudo -u serviceuser /usr/bin/killserviceworker

ensuite

# addgroup servicekiller
# chown root:servicekiller /usr/bin/killservice
# chmod 750 /usr/bin/killservice
# adduser bob servicekiller

ensuite, il vous suffit d'ajouter une règle dans / etc / sudoers pour leur permettre d'exécuter / usr / bin / killserviceworker en tant que service utilisateur sans demander de mot de passe:

servicekiller        ALL = (serviceuser:serviceuser) NOPASSWD: /usr/bin/killserviceworker

killserviceworker peut ressembler à ceci:

#!/bin/bash
kill ${cat /run/service.pid}
La glace
la source