Práticas recomendadas para usar o sudo em um script bash

11

Eu tenho um script bash de longa e longa execução, em que vários comandos precisam ser executados como root, enquanto a maioria dos comandos precisa ser executada como usuário comum antes do sudo, porque isso atrapalharia a propriedade do arquivo.

Eu vim com alguns métodos, mas cada um deles tem alguns problemas

Método 1: usando o sudo dentro do arquivo

#!/bin/bash
sudo echo "I must be run by root"
touch needsToBeOwnedByUser1
echo "needs to be run by user"
sleep 1000
sudo echo "I, again, must be run by root"

Isso ficaria bom, da maneira como o código é escrito. sudoé escrito antes das poucas instruções que realmente precisam ser executadas pelo root, mas se o tempo entre cada sudochamada for muito longo sudonovamente solicitará uma senha. Além disso, se a primeira execução de sudofalha, por exemplo, devido a uma senha inválida, o restante do script ainda é executado.

Método 2: usando o sudo para chamar o arquivo e, em seguida, volte ao usuário original quando necessário

#!/bin/bash
echo "I must be run by root"
su username -c 'touch needsToBeOwnedByUser1'
su username -c 'echo "needs to be run by user"'
su username -c 'sleep 1000'
echo "I, again, must be run by root"

Isso também é péssimo, porque eu preciso adicionar su username -cna frente de quase todas as linhas. Também sudoé possível encontrar o nome de usuário original depois , mas complicado.

Existe uma maneira melhor?

Edit: Eu publiquei apenas pequenos scripts sem sentido aqui para mostrar o que estou falando. No script atual, eu tenho algumas linhas que precisam do sudo (iniciando e parando serviços), algumas linhas em que não importa se existe sudo e muitas linhas que realmente precisam ser executadas sem o sudo.

Dakkaron
fonte
4
Isso raramente é necessário. Na maioria dos casos, basta executar o script sudose ele precisar ter permissões elevadas. Mas não há sentido em mudar su username -cpara executar um echo. Em outras palavras, isso soa como um [XY]. Você pode editar e explicar o que seu script realmente fará e por que você sente que precisa trocar de usuário com tanta frequência?
terdon
11
@ElderGeek você colou o link errado? Isso nem parece relacionado. Isso provavelmente é uma duplicata de Como executo o comando 'sudo' dentro de um script? mas espero que o OP possa explicar um pouco mais.
terdon
@terdon Parece que sim. Limpando.
Elder Geek
Este é apenas um exemplo de script. Eu não queria colar um script de mais de 200 linhas aqui. Vou editar a resposta para mais detalhes.
Dakkaron
Você considerou a opção validar, descrita em man sudo? -v, --validate 'Atualize as credenciais em cache do usuário, autenticando o usuário, se necessário. Para o plug-in sudoers, isso prolonga o tempo limite do sudo por mais 15 minutos por padrão, mas não executa um comando. Nem todas as políticas de segurança suportam credenciais em cache. (Se você executá-lo com bastante frequência, a autenticação sudo não deve tempo limite.)
sudodus

Respostas:

5

Em relação ao método 2, é mais fácil usar uma função. Por exemplo:

#!/bin/bash

func(){
    echo "Username: $USER"
    echo "    EUID: $EUID"
}

export -f func

func
su "$SUDO_USER" -c 'func'

$SUDO_USERé o nome de usuário do sudoer. Você também pode usar $(logname)em seu lugar.

Correndo na minha máquina:

$ sudo bash test.sh
[sudo] password for wja: 
Username: root
    EUID: 0
Username: wja
    EUID: 1000
wjandrea
fonte
2

Ao ler man sudoers, vê-se:

 PASSWD and NOPASSWD

   By default, sudo requires that a user authenticate him or herself
   before running a command.  This behavior can be modified via the
   NOPASSWD tag.  Like a Runas_Spec, the NOPASSWD tag sets a default for
   the commands that follow it in the Cmnd_Spec_List.  Conversely, the
   PASSWD tag can be used to reverse things.  For example:

   ray     rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm

   would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm
   as root on the machine rushmore without authenticating himself. 

Assim, você pode permitir que o regularhost machine1execute command1e command2como root, sem autenticação de senha com:

reguser machine1 root = NOPASSWD: /usr/local/command1, /usr/local/command2  

mas leia cada um deles man -k sudopara obter detalhes.

waltinator
fonte
0

Talvez isso possa ajudar:

chmod 775 herscript.sh

Então você pode usar o sudo dentro do script (sem solicitação de senha) E não pode usar o sudo para outros comandos dentro do seu script.

1337 HaXxoR
fonte
Eu temo que isso não funcione. chmod 775permite apenas executar o arquivo e não altera o usuário que está executando o arquivo ou seus direitos.
Dakkaron 14/04