Criando um utilitário do Linux: best-practices users / groups / permissions

1

Estou criando um utilitário que será executado em máquinas Linux. Para os propósitos desta discussão, digamos que seja análogo a fazer.

O negócio é o seguinte: às vezes, quando você executa o utilitário, ele cria arquivos no diretório em que você está executando e eles precisam ser criados como o mesmo usuário / grupo que o usuário que está executando a ferramenta. Este é o cenário "make main.o" - create main.o from main.c. Este será o padrão quando você executar o utilitário como seu próprio usuário, o que é bom.

Às vezes, quando você executa o utilitário, ele cria arquivos em / usr / local / bin e outros, que precisam ser root: root. Este é o cenário "sudo make install" - crie / usr / local / bin / executable em root: root. Este será o padrão quando você executar o utilitário como root, o que é bom.

O problema é que, em todos os casos, o utilitário precisa gerenciar alguns arquivos de cache adicionais, digamos, em / var / cache / utility. Quando você executa o utilitário como root, esses arquivos são root: root, o que é um problema na próxima vez que você executar o utilitário como usuário normal. Eles não podem ser excluídos / modificados.

O que eu estou querendo saber é, é uma boa idéia criar um usuário / grupo dedicado para este utilitário quando você o instala? Eu sei que o apache, svn e outros fazem isso. Esta é a única abordagem em que posso pensar, mas estou aberto a outras soluções.

Se eu tiver um usuário / grupo dedicado para o utilitário, como assumir temporariamente a identidade desse usuário para fins de gerenciamento dos arquivos de cache e, em seguida, retomar a identidade anterior para o restante da execução (para criar arquivos como usuário: usuário e arquivos do sistema como root: root)?

O que eu tenho até agora é algo assim:

  • getpwnam (predefined_utility_user_name) // obtém o uid
  • seteuid (utility_uid)
  • setegid (utilitário_gid)

// faz coisas em / var / cache / utility

  • seteuid (getuid ()) // retomar o ID anterior
  • setegid (getgid ()) // retomar o grupo anterior

O PROBLEMA: supondo que a identidade predefinida NÃO funcione ao executar o utilitário como você mesmo! Funciona quando você executa como root (obviamente).

Estou bem adicionando a mim mesmo e a outros usuários ao grupo associado ao utilitário. No entanto, isso não funciona. Então, como faço isso funcionar? Isso é uma má ideia?

EDIT: Resposta à sugestão abaixo

Eu fiz mais algumas leituras e acho que tenho uma boa solução usando # 2 que você sugeriu que se parece com isso

O executável do utilitário pertence ao utilitário: utility e possui as permissões u + se g + s. Portanto, logo quando eu começo a executar, eu tenho euid / egid de utilitário e utilitário, respectivamente. Eu tenho ruid / rgid de qualquer usuário executado o programa. Então, o que eu posso fazer é, quando eu começo a execução, setegid (getgid ()) e seteuid (getuid ()). Isso permite que o processo assuma a identidade de quem executou o programa. Eu vou manter isso durante toda a duração do programa, EXCETO ao lidar com / var / cache / utility, eu uso a mesma técnica para assumir o utilitário: utility identity.

Eu não preciso particionar o software, não há nenhum grupo ao qual seu usuário deva pertencer, o executável precisa apenas de seu próprio usuário / grupo e u + se + g + s. Eu acho que você tem que confiar que o programa não é malicioso, mas você tem que assumir que, de qualquer maneira, se você for executá-lo. Pensamentos?

    
por Todd Freed 24.12.2012 / 04:20

1 resposta

0

Para maior clareza, o problema com o seu código é que os usuários sem privilégios só podem seteuid em um alguns casos com base em como o executável foi chamado. Então, precisamos de outra solução.

Este é um problema interessante. Existem diferentes maneiras de resolvê-lo. Não sei se existe uma solução de melhores práticas aceitas, mas aqui estão algumas opções.

  1. Defina as permissões de grupo em /var/cache/utility .

    Essa abordagem permite que o seu utilitário seja executado sob as permissões dos iniciadores. Certifique-se de que o usuário esteja no grupo que possui /var/cache/utility e altere as permissões para que a atribuição de grupo seja fixa para todo o conteúdo. Você pode conseguir isso com o seguinte:

    mkdir /var/cache/utility
    chown -R :user /var/cache/utility
    chmod 2770 /var/cache/utility
    usermod -a -G users joe
    

    Agora, como joe está no users , quando ele executa seu utilitário, tudo fica bem. A premissa de grupo de quaisquer arquivos modificados em /var/cache/utility permanecerá users . O problema é que não há nenhum grupo ao qual todos os usuários pertençam automaticamente. Portanto, esse método não funcionará automaticamente para todos os usuários. Existe também o problema de segurança. Seu utilitário pode modificar arquivos em /var/cache/utility de uma maneira bem comportada, mas esses métodos abrem as comportas para o oeste selvagem da terra do usuário.

  2. Divida seu utilitário em front-ends e back-ends.

    Dividir o utilitário em front-ends e back-ends é inconveniente, mas o força a formalizar a interface operacional. A comunicação entre as partes pode ter duas formas comuns:

    • Comunicações de soquete, sejam soquetes unix ou soquetes TCP. Isso requer que seu back-end seja um serviço.

    • Ferramentas de linha de comando. Isso é consideravelmente mais simples do que usar soquetes, e seu back-end não é executado continuamente.

    A idéia é uid-execute-sticky-bit em seu back-end, para que ele seja executado automaticamente sob a conta do proprietário, independentemente do usuário atualmente conectado. O front-end ainda será executado sob as credenciais do usuário.

    Veja se você pode dividir seu utilitário para que toda a manipulação do cache seja executada pelo back-end, mas outras atividades são executadas no front-end. Você pode definir o uid do back-end da seguinte forma:

    chmod u+s /usr/bin/utility-back-end
    

    Existe uma visão geral razoavelmente boa desta técnica aqui . Ainda é um tanto inconveniente particionar o software dessa forma, mas é a melhor solução que conheço. O comando a seguir listará todos os utilitários em seu sistema que já usam este método:

    find / -xdev \( -perm -4000 \) -type f -print0 | xargs -0 ls -l
    

Espero que ajude.

    
por 24.12.2012 / 13:27