Como matar um processo iniciado com um usuário diferente sem ser root ou sudoer?

20

em um ambiente Linux, preciso matar um processo iniciado pelo usuário2 se eu for usuário1 sem ser sudoers ou usando root. Você sabe se existe uma maneira de definir isso ao iniciar o processo? Como uma lista de usuários autorizados a matar o processo?

O fato é que instâncias simultâneas do mesmo processo podem ser iniciadas por usuários diferentes, por isso não é conveniente definir o ID do grupo para o processo. Outros usuários que não estão no grupo não poderão iniciar um segundo processo paralelo.

O que tenho é uma lista de usuários com permissão para iniciar o processo, definido no banco de dados, antes de iniciar o processo, verifico se o usuário atual está na lista e, se sim, inicio o processo com o usuário atual. Se um segundo usuário permitir fazer isso, interromper o processo, eu gostaria que ele fizesse isso, mas não quero que ele sofra.

Portanto, eu estava pensando em criar um processo em execução como root, que recebe a solicitação para matar processos de um usuário, verifica se o usuário tem permissão para iniciar / parar o processo e o mata.

Você acha que poderia ser a melhor solução?

slhck
fonte
Bem-vindo ao SO. Eu não acho que isso seja possível ... Enfim, isso é mais adequado para o site irmão da SO, serverfault.com. Pode ser migrado para lá em breve, sem necessidade de fazer nada.
Pekka suporta GoFundMonica
De que tipo de programa estamos falando? Seria difícil no caso geral, mas em alguns casos (como o apache ou um aplicativo que você pode se modificar) seria mais fácil.
Kim

Respostas:

14

Sinto muito, mas isso simplesmente não é possível (isso é por design). No entanto, se membros de um grupo comum, o usuário1 pode gravar em um arquivo que o processo do usuário2 verifica, indicando para o processo que ele deve finalizar.

Ou, o usuário2 pode executar algo em segundo plano que verifica um arquivo e envia os sinais apropriados. O usuário1 simplesmente precisa gravar nesse arquivo. Isso pode ser mais fácil, pois não exigiria nenhuma modificação dos programas do usuário2.

Convencionalmente, não, o usuário1 não pode enviar sinais POSIX para o processo do usuário2.

Tim Post
fonte
Obrigado pela sua resposta. No meu caso, de fato, eu não uso o arquivo, mas usamos um sistema ( dim.web.cern.ch/dim ) que pode enviar o sinal apropriado; então, um processo pode ser chamado para verificar se o usuário tem permissão para interrompa o processo e mata o processo.
@ ATelesca - Uso algo muito semelhante para permitir que usuários carentes controlem / iniciem / parem máquinas virtuais Xen em um farm bastante grande. Basicamente, a mesma coisa.
Tim Post
9

A menos que ACLs, SELinux ou qualquer outra coisa tenha uma maneira melhor de fazê-lo, a maneira como eu vi isso é com um script SetUID . Como você pode imaginar, eles são famosos por serem riscos à segurança.

Em relação ao seu caso, diga que procOwner é o nome de usuário do proprietário do processo, e userA (uid 1000), userB (uid 1201) e userC (uid 1450) são as pessoas autorizadas a interromper o processo.

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.

Em seguida, defina o proprietário e as permissões com:

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

E também coloque userA, userB e userC no grupo procGroup.


fonte
Eu tentei isso e não funcionou. O usuário não proprietário recebeu uma permissão negada no comando kill.
JavaScript é necessário
11
Gostaria de acrescentar, por que não deixar o sistema controlar as permissões para o script de interrupção? Criar um grupo com userA, userB e userC e, em seguida, associar o killscript a esse grupo e modificá-lo para g + x parece muito mais ordenado para mim.
Leonid Shevtsov
11
Setuid não bit permitido em shell scripts, u necessidade de caixa simples invólucro Programa compilado para executá-lo
El'
2

Não é convencional - fazer com que qualquer usuário venha e mate os processos de outra pessoa é a vulnerabilidade final de negação de serviço.

Isso pode ser feito se o processo de destino cooperar. Uma maneira seria monitorar um evento externo (como um arquivo sendo criado em / var / tmp ou uma mensagem em um soquete), instruindo-o a se matar. Se você não puder gravá-lo para fazer isso, poderá criar um wrapper para ele que o inicie e faça o monitoramento, matando o processo filho se o evento ocorrer.


fonte
1

Não, você não pode.

Se você deseja compartilhar processos com outros usuários, inicie o processo com um ID de usuário comum.

Konerak
fonte
1

Obviamente, você pode escrever o programa de forma que ele termine normalmente quando receber um determinado sinal (termo usado livremente para significar "um evento predeterminado", não um sinal POSIX) de um certo (lista de) usuários.

drxzcl
fonte
Os sinais não têm um campo "usuário". Eles são apenas sinais.
LtWorf
Por isso eu disse "um evento predeterminado, não um sinal POSIX".
Drxzcl
1

Você pode escrever um programa suid que somente usuários de um determinado grupo podem executar e que envia o sinal apropriado ao processo. Não tenho certeza se você pretendia excluir o suid também.

Kim
fonte
0

O bit suid não funciona com scripts bash. imho, a melhor maneira é escrever um script de wrapper "killservice". Suponha que seu serviço esteja sendo executado como usuário serviceuser

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

então

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

então, você só precisa adicionar uma regra em / etc / sudoers para permitir que eles executem / usr / bin / killserviceworker como usuário do serviço de usuário sem solicitar uma senha:

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

O killserviceworker pode ficar assim:

#!/bin/bash
kill ${cat /run/service.pid}
O gelo
fonte