Como descartar privilégios de root em scripts de shell?

13

A opção "--up" no OpenVPN é normalmente usada para roteamento etc. E, portanto, é processada antes que o OpenVPN descarte os privilégios de root para executar como ninguém. No entanto, estou invocando scripts de shell que precisam executar como um usuário não privilegiado.

Como faço isso? Estudei privilégios de processo de entrega, especialmente as respostas de polinômios e de tylerl, mas não entendo como implementar. Estou trabalhando no Centos 6.5 e suid está bloqueado, como "chmod u + s" e como "setuid ()".

Existe um plugin OpenVPN ("openvpn-down-root.so") que permite que scripts chamados pela opção "--down" sejam executados como raiz. Pode haver um equivalente, como "openvpn-up-user.so", mas eu não o encontrei.

Editar0

De acordo com a resposta de Nikola Kotur, instalei o runit-rpm de Ian Meyer . Embora o comando chpst funcione no terminal, no script up ele falha com "comando não encontrado". O que funciona é "sudo chpst" mais a configuração da tela e do idioma adequados. Consulte Por que meu terminal não gera caracteres unicode corretamente? Dado isso, o script up precisa dessas quatro linhas:

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &

Edit1

Pelo comentário de 0xC0000022L, acho que "sudo -u user" funciona tão bem quanto "sudo chpst -u user -U user":

LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &

Vou estudar sudoers para homens e atualizar se / quando eu tiver o sudo sozinho para trabalhar.

mirimir
fonte
comentário deixado por @ user66229: "Posso sugerir que você navegue para sourceforge.net/p/openvpn/mailman e assine as listas que achar mais adequadas."
slm
@ user66229 Obrigado. Mas não acredito que seja uma pergunta específica do OpenVPN. Por que você acredita que é?
mirimir 31/05

Respostas:

7

Eu uso a ferramenta runitchpst para tarefas como esta. Por exemplo, no script up, chame seu script não privilegiado:

chpst -u nobody /path/to/script
Nikola Kotur
fonte
Legal :) Obrigado. O github.com/imeyer/runit-rpm é a melhor maneira de obter o runit no Centos 6.5? Mesmo com os repositórios da Red Hat, não estou encontrando um pacote.
mirimir
@mirimir, sim, eu uso esse repositório quando preciso criar um pacote runit para o CentOS.
Nikola Kotur
10

Cobrir apenas runit e sudo erra muito. Na verdade, existe toda uma família de conjuntos de ferramentas, como runit, e uma grande variedade de ferramentas para fazer exatamente isso, a mesma tarefa para a qual eles foram projetados:

  • Os daemontools de Daniel J. Bernstein setuidgid:

    usuário setuidgid /home/user/unprivileged.sh
  • O freedt de Adam Sampson tem setuidgid:

    usuário setuidgid /home/user/unprivileged.sh
  • O daemontools-encore de Bruce Guenter tem setuidgid:

    usuário setuidgid /home/user/unprivileged.sh
  • O runit de Gerrit Pape possui chpst:

    chpst -u usuário /home/user/unprivileged.sh
  • O criminoso de Wayne Marshall tem runuid:

    usuário runuid /home/user/unprivileged.sh
  • O s6 de Laurent Bercot tem s6-setuidgid:

    usuário s6-setuidgid /home/user/unprivileged.sh
  • meu nariz tem setuidgid:

    usuário setuidgid /home/user/unprivileged.sh

Eles não se misturam na tarefa diferente de adicionar privilégios e nunca caem no modo interativo.

Seus problemas resolvidos são pouco mais do que você esquecer de ter sbine também os binseus PATH, a propósito.

Leitura adicional

JdeBP
fonte
3

script que remove privilégios e executa outro script (mas aqui eu fiz apenas para rodar sozinho):

#!/bin/sh

id=`id -u`
safeuser="nobody"

if [ $id = "0" ]
then
         # we're root. dangerous!
        sudo -u $safeuser $0
else
    echo "I'm not root"
    id
fi

Exemplo:

root@n3:/tmp/x# id
uid=0(root) gid=0(root) группы=0(root)
root@n3:/tmp/x# ./drop.sh
I'm not root
uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)
yaroslaff
fonte
Embora o uso de "sudo -u user" funcione para alguns comandos, ele não fornece ambiente de usuário suficiente para meus propósitos. E enquanto "su -l user" funciona bem no terminal, ele não faz nada nos scripts. Suponho que seja um recurso de segurança. Parece que fiquei com a instalação do runit.
mirimir 31/05
1
@mirimir: por quê? /etc/sudoerspermite ser muito específico sobre quais variáveis ​​de ambiente podem ser transmitidas para o programa executado sudoe assim por diante. man sudoers. Honestamente, quem usa sudoapenas por sudo su -ou ao contexto de troca de usuário não tem nenhuma pista sobre o que está por trás deste programa incrível e quanto você pode bloquear as coisas para programas individuais, usuários, anfitriões etc ...
0xC0000022L
@ 0xC0000022L Obrigado. Dei outra olhada no sudo. E sim, "sudo -u user", além de exibição e idioma, também funciona.
mirimir
1
Falando em perigoso - você não pode confiar $0; o chamador pode definir um script $0para literalmente qualquer coisa que ele queira que seja. E use mais citações.
Charles Duffy
2
... se o seu script $0for/directory/name with spaces/script (e lembre-se, os usuários podem criar links simbólicos arbitrários em locais que possuem, mesmo se eles não usam exec -a somename yourscriptpara chamar yourscriptcom um $0dos somename), então você deseja obter sudo -u nobody /directory/name with spaces, com withe spacespassados como argumentos separados para o seu comando .
Charles Duffy
1

A respeito:

sudo -Eu <user> <command>

Você reclamou do ambiente em um comentário anterior, portanto, você também pode comparar as diferenças entre as saídas:

sudo -u <user> printenv
sudo -Eu <user> printenv
thiagowfx
fonte
1

No Linux, você pode usar runuserou setprivse uma sessão PAM não for necessária (ambas de util-linux):

runuser -u USER [--] COMMAND [ARGUMENTS...]

setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...]  # Like su/runuser/sudo
setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...]  # Like daemontools setuid(8)

Na supágina do manual:

su é projetado principalmente para usuários sem privilégios, a solução recomendada para usuários com privilégios (por exemplo, scripts executados pelo root) é usar o comando runuser (1) de ID de usuário não definido, que não exija autenticação e forneça uma configuração PAM separada. Se a sessão do PAM não for necessária, a solução recomendada é usar o comando setpriv (1) .

dcoles
fonte