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

5

Eu tenho um script longo e de longa execução onde um punhado de comandos precisa ser executado como root, enquanto a maioria dos comandos precisam ser executados como o usuário regular antes do sudo, porque isso atrapalharia a propriedade do arquivo e tal.

Eu criei 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 bem, a partir do modo 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 chamada sudo for muito longo sudo novamente pedirá uma senha. Além disso, se a primeira execução de sudo falhar, por ex. devido a uma senha inválida, o restante do script ainda é executado.

Método 2: usando o sudo para chamar o arquivo e depois voltar 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 é uma droga, porque eu preciso adicionar su username -c na frente de quase todas as linhas. Também encontrar o nome de usuário original após sudo é possível, mas complicado.

Existe uma maneira melhor?

Edit: Eu só postei pequenos scripts sem sentido aqui para mostrar o que estou falando. No script atual eu tenho algumas linhas que precisam de sudo (iniciar e parar serviços), algumas linhas onde não importa se há sudo e muitas linhas que realmente precisam ser executadas sem sudo.

    
por Dakkaron 25.07.2017 / 14:19

2 respostas

4

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 sudo. Você também pode usar $(logname) em seu lugar.

Em execução na minha máquina:

$ sudo bash test.sh
[sudo] password for wja: 
Username: root
    EUID: 0
Username: wja
    EUID: 1000
    
por wjandrea 25.07.2017 / 23:01
1

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 regular no host machine1 execute command1 e command2 como raiz, sem autenticação de senha com:

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

mas leia cada um dos man -k sudo para detalhes.

    
por waltinator 25.07.2017 / 18:34

Tags